Pod 对象自从其创建开始至其终止退出的时间范围称为其生命周期。 在这段时间中, Pod 会处于多种不同的状态, 并执行一些操作;其中,创建主容器( main container)为必 需的操作,其他可选的操作还包括运行初始化容器 ( init container)、容器启动后钩子( post start hook)、容器的存活性探测( liveness probe)、 就绪性探测( readiness probe)以及容器终 止前钩子(pre stop hook)等,这些操作是否执行则取决于 Pod 的定义,如图所示。
无论是类似前面几节中的由用户手动创建,还是通过 Deployment 等控制器创建, Pod 对象总是应该处于其生命进程中以下几个相位(phase)之一。
Pod 的相位是在其生命周期中的宏观概述,而非对容器或 Pod 对象的综合汇总,而且相 位的数量和含义被严格界定,它仅包含上面列举的相位值。
(1)例如查询如何定义pod资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[root@master ~] # kubectl explain pod
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
... ...
kind <string>
... ...
metadata <Object>
... ...
spec <Object>
... ...
status <Object>
... ...
|
(2)能一级一级进入查询;如查询定义pod 的metadata字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[root@master ~] # kubectl explain pod.spec
KIND: Pod
VERSION: v1
RESOURCE: spec <Object>
DESCRIPTION:
... ...
FIELDS:
... ..
affinity <Object>
... ...
[root@master ~] # kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object>
DESCRIPTION:
... ...
FIELDS:
args <[]string>
... ...
command <[]string>
... ...
|
自己定义资源时,不清楚如何定义,可以进行快速的查询
(1)查询集群中的pod(上篇创建的pod)
1 2 3 4 5 6 |
[root@master ~] # kubectl get pods
NAME READY STATUS RESTARTS AGE
client 1 /1 Running 0 4h
myapp-848b5b879b-9slqg 1 /1 Running 0 46m
myapp-848b5b879b-wtrjr 1 /1 Running 0 46m
myapp-848b5b879b-z2sqc 1 /1 Running 0 46m
|
(2)-o yaml输出为yaml格式,查看pod创建的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@master ~] # kubectl get pod myapp-848b5b879b-9slqg -o yaml
apiVersion: v1 #api版本
kind: Pod #资源类别
metadata: #元数据
annotations:
cni.projectcalico.org /podIP : 10.244.1.60 /32
labels:
pod-template- hash : "4046164356"
run: myapp
name: myapp-848b5b879b-9slqg
namespace: default
... ...
selfLink: /api/v1/namespaces/default/pods/myapp-848b5b879b-9slqg
spec: #规格、规范;期望资源应该用于什么特性;期望目标状态
... ...
status: #当前状态
... ...
|
1 2 |
[root@master ~] # mkdir manifests
[root@master ~] # cd manifests/
|
(1)编写pod-demo.yaml文件
创建2个容器,一个运行nginx;一个在busybox中执行sleep命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[root@master manifests] # vim pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
#labels: {app:myapp, tier:frontend} #映射可以写为{}形式;
labels: #也可以在下边分级写
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes /myapp :v1
- name: busybox
image: busybox:latest
#command: ["/bin/sh","-c","sleep 3600"] #列表可以写为[]形式;
command : #也可以在下边分级写,要加-
- "/bin/sh"
- "-c"
- "sleep 3600"
|
(2)基于pod-demo.yaml 文件创建create pod
1 2 |
[root@master manifests] # kubectl create -f pod-demo.yaml
pod /pod-demo created
|
(3)验证
① 查询创建pod的信息
1 2 3 4 5 6 7 8 9 10 |
[root@master manifests] # kubectl create -f pod-demo.yaml
pod /pod-demo created
[root@master manifests] # kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-demo 2 /2 Running 0 1m 10.244.1.61 node1
---查看详细信息
[root@master manifests] # kubectl describe pods pod-demo
Name: pod-demo
Namespace: default
... ...
|
② 访问pod中的服务
1 2 3 4 5 |
[root@master manifests] # curl 10.244.1.61
Hello MyApp | Version: v1 | <a href= "hostname.html" >Pod Name< /a >
---查询pod产生的日志
[root@master manifests] # kubectl logs pod-demo myapp
192.168.130.104 - - [23 /Jan/2019 :05:35:35 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"
|
③ 基于yaml文件删除pod
1 2 3 4 |
[root@master manifests] # kubectl delete -f pod-demo.yaml
pod "pod-demo" deleted
[root@master manifests] # kubectl get pods
No resources found.
|
(1)修改pod-demo.yaml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
[root@master manifests] # vim pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
#labels: {app:myapp, tier:frontend} #映射可以写为{}形式;
labels: #也可以在下边分级写
app: myapp
tier: frontend
annotations:
along.com /created-by : "cluster admin"
spec:
containers:
- name: myapp
image: ikubernetes /myapp :v1
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
#command: ["/bin/sh","-c","sleep 3600"] #列表可以写为[]形式;
command : #也可以在下边分级写,要加-
- "/bin/sh"
- "-c"
- "sleep 3600"
nodeSelector:
disktype: ssd
|
(2)将node1节点打上disktype=ssd的标签
1 2 3 4 |
[root@master manifests] # kubectl label node node1 disktype=ssd
[root@master manifests] # kubectl get nodes node1 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node1 Ready <none> 140d v1.11.2 beta.kubernetes.io /arch =amd64,beta.kubernetes.io /os =linux,disktype=ssd,kubernetes.io /hostname =node1
|
(3)基于yaml文件创建pod
1 2 |
[root@master manifests] # kubectl create -f pod-demo.yaml
pod /pod-demo created
|
(4)验证
1 2 3 4 5 6 7 8 |
--- pod只会创建到node1节点上,因为node1的disktype=ssd标签
[root@master manifests] # kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-demo 2 /2 Running 0 11s 10.244.1.68 node1
--- -l 指定标签,实现标签过滤
[root@master manifests] # kubectl get pods --show-labels -l app
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2 /2 Running 0 30s app=myapp,tier=frontend
|
目前, Kubernetes 的容器支持存活性探测的方法包含以下三种: ExecAction、 TCPSocketAction 和 HTTPGetAction。
(1)在spec字段下、containers字段配置,可使用explain查看详细用法
$ kubectl explain pod.spec.containers.
容器程序发生崩溃或容器申请超出限制的资源等原因都可能会导致 Pod 对象的终止, 此时是否应该重建该 Pod 对象则取决于其重启策略(restartPolicy)属性的定义。
需要注意的是, restartPolicy 适用于 Pod 对象中的所有容器,而且它仅用于控制在同一 节点上重新启动 Pod 对象的相关容器。 首次需要重启的容器,将在其需要时立即进行重启, 随后再次需要重启的操作将由 k:ubelet 延迟一段时间后进行,且反复的重启操作的延迟时长 依次为 10 秒、 20 秒、 40 秒、 80 秒、 160 秒和 300 秒, 300 秒是最大延迟时长。 事实上, 一 旦绑定到一个节点, Pod 对象将永远不会被重新绑定到另一个节点,它要么被重启,要么终 止, 直到节点发生故障或被删除。
$ kubectl explain pod.spec.restartPolicy.
exec 类型的探针通过在目标容器中执行由用户自定义的命令来判定容器的健康状态, 若命令状态返回值为 0 则表示“成功”通过检测,其值均为“失败”状态。 “spec.containers. !iv巳nessProbe.exec”字段用于定义此类检测,它只有一个可用属性“"command ",用于指定 要执行的命令。
(1)编写yaml文件
当探测到/tmp/healthy文件不存在时,认为服务故障;
容器在30秒后执行删除/tmp/healthy文件
[root@master manifests]# vim liveness-exec.yaml apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: liveness-exec-container image: busybox:latest imagePullPolicy: IfNotPresent command: ["/bin/sh","-c","touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 3600"] livenessProbe: exec: command: ["test","-e","/tmp/healthy"]
(2)创建运行pod
1 2 3 4 5 |
[root@master manifests] # kubectl create -f liveness-exec.yaml
pod /liveness-exec-pod created
[root@master manifests] # kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness- exec -pod 1 /1 Running 0 6s
|
(3)等30s,容器就会检测失败,重启pod;使用describe可以查看详细信息
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[root@master manifests] # kubectl describe pods liveness-exec-pod
... ...
State: Running
Started: Wed, 23 Jan 2019 16:58:09 +0800
Last State: Terminated #上次状态为终止
Reason: Error
Exit Code: 137
Started: Wed, 23 Jan 2019 16:57:01 +0800
Finished: Wed, 23 Jan 2019 16:58:09 +0800
Ready: True
Restart Count: 1 #重启次数1次
Liveness: exec [ test -e /tmp/healthy ] delay=1s timeout=1s period=3s #success=1 #failure=3
... ...
|
基于 HTTP 的探测 ( HTTPGetAction) 向 目标容器发起一个 HTTP 请求,根据其响应码进行结果判定,响应码形如 2xx 或 3xx 时表示检测通过。 “ spec.containers.livenessProbe. httpGet” 字段用于定义此类检测,它的可用配置字段包括如下几个。
下面是一个定义在资源清单文件 liveness占ttp.yarr让中的示例,它通过 lifecycle 中的 postSta此 book 创建了一个专用于 httpGet 测试的页面文件 bealthz:
(1)编写yaml文件,创建并运行pod
当探测不到容器内80端口,和提供80端口的/index.html文件时,认为服务故障;
[root@master manifests]# cat liveness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: liveness-httpget-pod namespace: default spec: containers: - name: liveness-exec-container image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 livenessProbe: httpGet: # 注意Get要大写 port: http path: /index.html # 访问此默认页 initialDelaySeconds: 1 # 在容器启动后1秒开始检测 periodSeconds: 3 # 每隔3秒时间探测一次 failureThreshold: 2 # 成功状态下连续检测两次失败将会发生重启 restartPolicy: Always
(2)手动连入容器,删除index.html文件
1 2 |
[root@master manifests] # kubectl exec -it liveness-httpget-pod -- /bin/sh
/ # rm -f /usr/share/nginx/html/index.html
|
(3)容器会检测失败,重启pod;使用describe可以查看详细信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@master manifests] # kubectl describe pods liveness-httpget-pod
... ...
Port: 80 /TCP
Host Port: 0 /TCP
State: Running
Started: Wed, 23 Jan 2019 17:10:03 +0800
Last State: Terminated #上次状态为终止
Reason: Completed
Exit Code: 0
Started: Wed, 23 Jan 2019 17:08:22 +0800
Finished: Wed, 23 Jan 2019 17:10:03 +0800
Ready: True
Restart Count: 1 #重启次数1次
Liveness: http-get http: // :http /index .html delay=1s timeout=1s period=3s #success=1 #failure=3
... ...
|
(1)编写yaml文件,创建启动容器
当探测到/tmp/healthy文件不存在时,就认为服务就绪不成功;pod启动失败;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[root@master manifests] # vim readiness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness- exec -pod
namespace: default
spec:
containers:
- name: readiness- exec -container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 3600"]
command : [ "sleep 3600" ]
readinessProbe:
exec :
command : [ "test" , "-e" , "/tmp/healthy" ]
periodSeconds: 3 # 探测周期we为3秒钟
restartPolicy: Always
[root@master manifests] # kubectl create -f readiness-exec.yaml
pod /readiness-exec-pod created
|
(2)查看,pod启动就绪失败
1 2 3 |
[root@master ~] # kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness- exec -pod 0 /1 RunContainerError 1 12s
|
生命周期钩子函数( lifecycle hook)是编程语言(如 Angular)中常用的生命周期管理的 组件,它实现了程序运行周期中的关键时刻的可见性,并赋予用户为此采取某种行动的能 力。 类似地, 容器生命周期钩子使它能够感知其自身生命周期管理中的事件,并在相应的时 刻到来时运行由用户指定的处理程序代码。 Kubernetes 为容器提供了两种生命周期钩子。
钩子处理器的实现方式有“Exec ”和“HTTP ”两种,前一种在钩子事件触发时直接在 当前容器中运行由用户定义的命令,后一种则是在当前容器中向某 URL 发起 HTTP 请求。
postStart 和 preStop 处理器定义在容器的 spec.lifecycle 嵌套字段中,其使用方法如下面 的资源清单所示,读者可自行创建相关的 Pod 资源对象,井验证其执行结果:
$ kubectl explain pod.spec.containers.lifecycle
(1)编写yaml文件,创建启动容器
启动容器前,先创建准备一个httpd服务的主页面文件/tmp/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[root@master manifests] # vim poststart-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: poststart-pod
namespace: default
spec:
containers:
- name: poststart-container
image: busybox:latest
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec :
command : [ '/bin/sh' , '-c' , 'echo hello > /tmp/index.html' ]
command : [ '/bin/sh' , '-c' , '/bin/httpd -f -h /tmp' ]
[root@master manifests] # kubectl create -f poststart-pod.yaml
pod /poststart-pod created
|
(2)验证,访问服务
[root@master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE poststart-pod 1/1 Running 0 26s 10.244.2.69 node2 [root@master ~]# curl 10.244.2.69 hello