Pod是kubernetes的基本操作单元,也是应用运行的载体。整个kubernetes系统都是围绕着Pod展开的,比如如何部署运行Pod、如何保证Pod的可靠性、如何访问Pod等。另外,Pod是一个或者多个相关容器的集合,这可以说是一大创新点,提供了一种容器组合的模型,当然也使得在Pod的操作和生命周期管理上稍有不同。
一、简单示例:hell-world-pod.yaml
apiVersion:v1
kind:Pod
metadata:
name:hello-world
spec:
restartPolicy:OnFailure
containers:
-name:hello
image:"ubuntu14.04"
command:["/bin/echo","hello","world"]
主要元素解释:
1.apiVersion:声明kubernetes的API版本,目前是v1。
2.kind:声明API对象的类型,这里类型是Pod。
3.metadata:设置Pod的元数据。
3.1.name:指定Pod的名称,Pod名称必须在Namespace内唯一。
4.spec:配置Pod的具体规格。
4.1.restartPolicy:设置Pod的重启策略。
4.2.containers:设置Pod中容器的规格,数组形式,每一项定义一个容器。
4.2.1.name:指定容器的名称,在Pod的定义中唯一。
4.2.2.image:设置容器镜像。
4.2.3.commond:设置容器的启动命令。
二、Pod的基本操作
1.通过定义文件创建Hello World Pod:
$kubectl create -f hell-world-pod.yaml
2.创建成功后,可以查询Hello World Pod:
$kubectl get pod hello-world
可以显示查询的Pod的简易信息,其中查询显示的字段含义如下所示:
NAME:Pod的名称
READY:Pod的准备状况,右边的数字表示Pod包含的容器总数目,左边的数字表示准备就绪的容器数目
STATUS:Pod的状态
RESTARTS:Pod的重启次数
AGE:Pod的运行时间
其中Pod的准备状况指的是Pod是否准备就绪以接收请求,Pod的准备状况取决于容器,即所有容器都准备就绪了,Pod才准备就绪。这时候kubernetes的代理服务才会添加Pod作为分发后端,而一旦Pod的准备状况变为false,kubernetes就会将Pod从代理服务的分发后端移除,即不会分发请求给该Pod。
也可以如下方式获取Pod的完整信息:
$kubectl get pod hello-world json #用json格式显示Pod的完整信息
$kubectl get pod hello-world yaml #用yaml格式显示Pod的完整信息
另外,kubectl get支持以Go Template方式过滤出指定的信息,比如查询Pod的运行状态:
$kubectl get pods hell-world --output=go-template --template={{.status.phase}}
另一个命令kubectl describe支持查询Pod的状态和生命周期事件:
$kubectl describe pod hello-world
3.然后查询Pod输出:
$kubectl logs hell-world
4.最后删除Hello World Pod:
$kubectl delete pod hell-world
另外,删除所有Pod:
$kubectl delete pod --all
5.更新Pod:
$kubectl replace /path/to/hell-world-pod.yaml
但是因为Pod的很多属性是没办法修改的,比如容器镜像,这时候可以通过kubectl replace命令设置--force参数,等效于重建Pod。
三、Pod与容器
在Docker中,容器是最小处理单位,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的。隔离是基于Linux Namespace实现的,Linux内核提供了6种Linux Namespace隔离的系统调用,如下表所示:
四、Pod和镜像
运行容器必须先指定镜像,镜像的名称则遵循Docker的命名规范。kubernetes中可以选择镜像的下载策略如下:
1.Always:每次都下载最新的镜像。
2.Never:只使用本地镜像,从不下载。
3.IfNotPresent:只有当本地没有的时候才下载镜像。
kubernetes Node是容器运行的宿主机,Pod被分配到Node之后,会根据镜像下载策略选择是否下载镜像。
Pod定义中一个容器镜像的配置示例如下所示:
name:hello-world
image:"ubuntu14.04"
imagePullPolicy:Always
五、Pod定义中设置容器启动命令和参数
示例如下:
apiVersion:v1
kind:Pod
metadata:
name:hello-world
spec:
restartPolicy:Never
containers:
-name:hello
image:"ubuntu14.04"
command:["/bin/echo","hello","world"]
另外,容器的启动命令也可以配置为:
command:["/bin/echo"]
args:["hello","world"]
在Pod的定义中,command和args都是可选项,将和Docker镜像的ENTRYPOINT和CMD相互作用,生成最终容器的启动命令,具体规则如下所示:
1.如果容器没有指定command和args,则容器使用镜像的ENTRYPOINT和CMD作为启动命令运行。
2.如果容器指定了command而没有指定args,则容器忽略镜像的ENTRYPOINT和CMD,使用指定的command作为启动命令运行。
3.如果容器没有指定command,只有指定了args,容器将使用镜像的ENTRYPOINT和CMD作为启动命令运行。
4.如果容器指定了command和args,则容器使用command和args作为启动命令运行。
六、Pod中设置容器环境变量
Pod定义中可以设置容器运行时的环境变量:
env:
-name:parameter_1
value:value_1
-name:parameter_2
valule:value_2
七、Pod中设置容器端口
在Pod的定义中,通过.spec.containers[].ports[]设置容器的端口,数组形式,每一项的参数如下所示:
1.name:设置端口名称,必须在Pod内唯一,当只配置一个端口的时候,这是一个可选项,当配置多个端口的时候,这是一个必选项。
2.containerPort:必选项,设置在容器内的端口,有效范围为0~65536(不包括0和65536)。
3.protocol:可选项,设置端口的协议,Tcp或者UDP,默认是TCP。
4.hostIP:可选项,设置在宿主机上的IP,默认绑定到所有可用的IP接口上,即0.0.0.0。
5.hostPort:可选项,设置在宿主机上的端口,如果设置则进行端口映射,有效范围为0~65536(不包括0和65536)。
八、Pod的重启策略
重启策略是通过Pod定义中的.spec.restartPolicy进行设置的,目前支持以下3种策略:
1.Always:当容器终止退出后,总是重启容器,默认策略。
2.OnFailure:当容器终止异常退出时,才重启容器。
3.Never:当容器终止退出时,从不重启容器。
九、Pod的状态和生命周期
Pod的本质是一组容器,Pod的状态便是容器状态的体现和概括,同时容器的状态变化会影响Pod的状态变化,触发Pod的生命周期阶段转换。
1.容器状态
在使用docker run运行容器的时候,首先会下载容器镜像。下载成功后运行容器,当容器运行结束退出后(包括正常和异常退出),容器终止,这是一个容器的生命周期过程。相应的,kubernetes中对Pod中的容器进行了状态的记录,其中每种状态下包含的信息如下:
1.1.Waiting:容器正在等待创建
Reason:等待原因
1.2.Running:容器已经创建,并且正在运行
startedAt:容器创建时间
1.3.Terminated:容器终止退出
exitCode:退出码
signal:容器退出的信号
reason:容器退出原因
message:容器退出信息
startedAt:容器创建时间
finishedAt:容器退出时间
containerID:容器的ID
Pod运行后,可以查询其中容器的状态:
$kubectl describe pod hello-world
2.Pod的生命周期
首先Pod被创建,紧接着Pod被调用到Node进行部署运行。Pod是非常忠诚的,一旦被分配到Node后,就不会离开这个Node,直到它被删除,生命周期完结。
Pod生命周期的阶段:
2.1.Pending:Pod已经被创建。但是一个或者多个容器还未创建,这包括Pod调度阶段,以及容器镜像的下载过程。
2.2.Running:Pod已经被调度到Node,所有容器已经创建,并且至少一个容器在运行或者正在重启。
2.3.Succeeded:Pod中所有容器正常退出。
2.4.Failed:Pod中所有容器退出,至少有一个容器是一次退出的。
查询Pod处于生命周期的阶段:
$kubectl get pods hello-world --template="{{.status.phase}}"