文章目录
- Pod Lifecle
- Pod的阶段:Pod phase
- 容器的状态:Container states
- 容器的探针:Container probes
- 重启策略:restartPolicy
- Pod删除
- Pod的回收
- 参考资料
Pod Lifecle
Pod的阶段:Pod phase
相关字段:.status.phase
phase表示一个Pod处于其生命周期的哪个阶段,一共有以下5个可能的取值:
- Pending:Pod已经被k8s系统接受,但Pod中还有容器没有被创建。Pod被调度前和下载容器镜像的时候都处于这个阶段
- Running:Pod已经被调度到Node上,所有的容器都已经被创建,并且至少有一个容器还在运行中(正在启动或重启中的容器也算)
- Succeeded:Pod中的所有容器都成功停止,并且不会再次重启
- Failed:Pod中的所有容器都已经停止,并且至少有一个容器是以失败停止的(以非0状态退出或被系统强制停止)
- Unknown:由于某种原因无法获得Pod的状态,一般是和Pod所在的Host出现通信问题导致
Pod phase的查看方式:
kubectl get pods pi2-ll9dn -o yaml |grep 'phase'
phase: Succeeded
注意,使用以下命令看到的STATUS
并不是Pod的phase:
kubectl get pod pi2-ll9dn
NAME READY STATUS RESTARTS AGE
pi2-ll9dn 0/1 Completed 0 4h50m
Pod并没有Completed
这个phase。
容器的状态:Container states
相关字段:.status.containerStatuses[index].state
(containerStatuses是一个数组,每个数组元素对应Pod中的一个容器)
我们知道,一个Pod中是包含有多个容器的,所以Pod的状态或者说阶段并不能直接反映Pod中容器的状态。当一个Pod被调度到Node上时,kubelet就会开始使用容器运行时(如Docker)创建容器,容器的状态可以通过命令kubectl describe pod [POD_NAME]
查看,一共以下3种状态:
- Waiting:容器默认的状态,只要不是Running和Terminated状态就是这个状态,拉取镜像的时候也是这个状态
- Running:表示容器正在正常运行中,如果定义了
postStart
hook(钩子),则该hook会在容器进入Running状态前执行 - Terminated:表示容器已经执行完并停止运行。如果定义了
preStop
钩子,在一个容器进入Terminated状态前,该钩子会被执行。执行完有两种情况,一种是正常退出,另外一种是因为某种原因失败退出,通过Reason
和Exit Code
查看容器停止的原因和状态码:
State: Terminated
Reason: Completed
Exit Code: 0
Started: Wed, 30 Jan 2019 11:45:26 +0530
Finished: Wed, 30 Jan 2019 11:45:26 +0530
容器的探针:Container probes
Node上的kebulet可以使用探针来周期性地检测运行中的容器的状态。探针的实现方式有3种:
- 在容器内执行某个特定的命令,如
cat /tmp/healthy
,如果命令返回的状态码为0,则认为探测成功 - 向容器的IP和指定端口发起一个TCP检测,如果成功则认为探测成功,类似于使用
telnet
来检测Linux服务器上的端口 - 向容器的IP和指定端口发起一次HTTP请求,如果返回的状态码在[200,400)区间内则认为探测成功
有如下3种探针:
- livenessProbe:检测容器是否还在运行中,kubelet使用这个探针来知道什么时候重启一个容器,一旦探测失败,kubelet会把该容器kill掉,至于容器需不需要重启,还需要看容器所在的Pod的重启策略(restartPolicy,详见下文),如果容器没有提供这个探针,则默认成功
- readinessProbe:用于检测容器是否已经准备好接收服务请求,如果探测失败,控制器会把这个Pod的IP地址从相应的Service上移除。在容器启动时的初始化延迟(initial delay,详见下文的
initialDelaySeconds
)时间内,探测默认为失败。如果一个容器没有提供这个探针,默认为成功(在initial delay之后) - startupProbe:用于容器启动时判断容器是否启动完成,在这个探针探测成功前,即容器启动成功前,livenessProbe和readinessProbe探针都不会起作用,防止某些启动很慢的容器在启动过程中,livenessProbe探针探测容器失败触发容器重启导致死锁。如果这个探针探测失败(容器启动时间超过了阈值),kubelet会把这个容器kill掉,再根据
restartPolicy
决定是否创建容器
探针支持的属性:
- initialDelaySeconds:默认值是0,最小值是0,容器启动后等待多久,liveness or readiness开始第1次执行
- periodSeconds:多久执行一次探针,默认值是10,最小值是1
- timeoutSeconds:探针执行超时时间,默认值是1,最小值是1
- successThreshold:失败后执行多少次探针成功才算成功,默认值是1,最小值是1,对于liveness来说必须是1
- failureThreshold:探针连续失败多少次后才算失败,默认是3,最小值是1
探针的定义方式可参考:
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name:demo-ctr
image: polinux/stress
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
livenessProbe: # liveness探针-command
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5 # 第1次执行探针时,延迟5s执行
failureThreshold: 2 # 探针执行失败2次后容器状态变为失败
periodSeconds: 5 # 每5s执行一次探针
readinessProbe: # readinessProbe的属性和livenessProbe的属性一模一样
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
startupProbe: # startupProbe
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10 # 容器启动30*10=300s内liveness和readiness探针不会执行,300s后startup探针还没成功,容器会被kill掉重启
重启策略:restartPolicy
当一个容器执行完退出时,不管是成功还是失败,都会触发重启策略,根据restartPolicy
的设置来决定要不要重启该容器,restartPolicy
有以下3种取值:
- Always:默认取值,不管是成功退出还是失败退出,都尝试重启该容器,Pod的阶段会保持为
Running
- OnFailure:失败的时候重启,Pod的阶段保持为
Running
,成功的时候不重启,Pod的阶段转为Succeeded
- Never:不管失败还是成功都不重启,Pod的阶段转为
Failed
或者Succeeded
当一个Pod退出后要重启时,有一段指数级递增的延迟(10s,20s,40s…最大达到5分钟),当一个容器重启并运行10分钟不出问题后,这个延迟会重置。
Pod删除
因为Pod代表着一组运行在node上的进程,所以允许这些进程在不再需要的时候能优雅地退出很重要(而不是被一个KILL信号强制停止,没有机会进行资源清理)。
k8s的设计目标在于让用户可以发起删除请求和知道进程什么时候终止,并能够确保删除最终完成。当对一个Pod发起一个删除请求时,集群在强制删掉这个Pod前,会记录和追踪一段grace period(terminationGracePeriodSeconds
, 默认是30s),在这段时间内,kubelet会尝试优雅地(graceful)关闭Pod。
一般的做法是,容器运行时(如Docker)会发送TERM
信号给Pod中每个容器的主进程,一旦grace period结束,容器运行时会发送KILL
给还没有成功结束的进程,然后Pod在API Server上被删除掉。如果kubelet或容器运行时的管理服务在等待这些进程优雅退出的时候重启了,那么集群会重新尝试整个删除流程,包括grace period。
如果Pod中的容器定义了preStop
钩子,那么终止容器(给容器发送TERM
或KILL
信号)前会先执行该钩子,如果grace period时间过了钩子还没执行完,kubelet会额外增加2s的时间让容器有机会优雅地退出。如果preStop
钩子需要执行很长时间的话,一般建议把terminationGracePeriodSeconds
调大。
当grace period开始时,Pod就会被从可用的服务列表中移除,服务请求不会再被转发到这个Pod上。
当所有容器(包括pause)都停掉以后,kubelet会触发API Server把这个Pod删除掉
Pod的回收
对于已完成的Pod(包括Failed和Succeeded的Pod),它们的API对象会保留在系统中。当系统中创建的Pod数量超出了指定阈值(kube-controller-manager中的terminated-pod-gc-threshold
)时,控制面板会清理这些已完成的Pod(包括Failed和Succeeded的Pod)。
参考资料
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/