Pod的生命周期包括初始化容器,容器启动之后钩子函数,就绪探测,存活探测,容器关闭前Hook函数,对应的流程图如下:
Pod周期的过程如下5步:
1.初始化容器阶段初始化pod中每一个容器,他们是串行执行的,执行完成后就退出了
2.启动主容器main container
3.在main container刚刚启动之后可以执行post start命令
4.在整个main container执行的过程中可以做两类探测:liveness probe(存活探测)和readiness probe(就绪探测)
5.在main container结束前可以执行pre stop命令
在 Pod 完整的生命周期中,存在着 5 种不同的阶段:
- Pending:创建 Pod 对象后的初始化阶段。会一直持续到 Pod 被分配给某个工作节点,镜像被拉取到本地并启动
- Succeeded:对于不打算无限期运行的 Pod,其容器部署完成后的状态
- Running:Pod 中至少一个容器处于运行状态
- Failed:对于不打算无限期运行的 Pod,其容器中至少有一个由于错误终止
- Unknown:由于 Kubelet 与 API Server 的通信中断,Pod 的状态未知。可能是工作节点挂掉或断网
可以使用 kubectl describe 命令,查看Pod状态
$ kubectl describe po kubia | grep Status:
Status: Running
健康检查探针
健康探针类型分为
- livenessProbe
探活。Kubernetes 会在容器的进程终止时重启容器,以保证应用的健康。但应用实际上有可能在进程不终止的情况下无响应,比如一个 Java 应用报出 OutOfMemoryError 错误,而 JVM 进程仍在运行中。
理想情况下,Kubernetes 需要能够检测到此类错误并重启容器。
当然,应用自身也可以捕获这类错误并令进程立即终止。但假如应用因为进入无限循环或死锁导致无响应,又或者应用本身无法检测到错误存在呢?为了确保容器能够在这些复杂情况下重启,应该提供一种从外部检查应用状态的机制。
Kubernetes 可以通过配置 liveness probe 来检查某个应用是否能够正常响应,Pod 中的每个容器都可以分别配置 liveness probe。一旦应用无响应或有错误发生,容器就会被认为是不健康的并被终止掉。之后容器被 Kubernetes 重新启动。
apiVersion: v1
kind: Pod
metadata :
name: liveness
namespace: default
spec:
containers:
- name: livenesscontainers image: nginx imagePullPolicy: IfNotPresent ports: - name:http containersPort:8080 command: ["/bin/bash","-c","touch /tmp/health;sleep 60;rm -rf /tmp/health;sleep 3600;"] livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 3 periodSeconds: 3
-
readinessProve
就绪状态检查。有时,应用程序暂时无法对外部流量提供服务。 例如,应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下,你不想杀死应用程序,但你也不想发送请求。 Kubernetes提供了readiness probe来检测和减轻这些情况。 Pod中的容器可以报告自己还没有准备,不能处理Kubernetes服务发送过来的流量,此时状态会被标记为NotReady。与livenessProbe不同的是,kubelet不会对readinessProbe的探测情况有重启操作。 -
startup probe
指示容器中的应用是否已经启动。默认的 liveness probe 配置会给应用 20 到 30s 的时间启动,如果应用需要更长的时间才能启动完成,容器会永远达不到 liveness probe 检测成功的状态,从而进入了无限重启的循环。
为了防止上述情况发生,可以增大 initialDelaySeconds、periodSeconds 或 failureThreshold 的值,但也会有一定的副作用。periodSeconds * failureThreshold 的值越大,当应用不健康时重启的时间就越长。
Kubernetes 还提供了一种 startup probe。当容器配置了 startup probe 时,容器启动时只有 startup probe 会执行。startup probe 可以按照应用的启动时间配置,检测成功之后 Kubernetes 会切换到使用 liveness probe 检测。
比如 Node.js 应用需要 1 分钟以上的时间启动,当启动成功以后若应用状态不正常,则在 10s 以内重启。
如果提供了启动探针(startup probe),则禁用所有其他探针,直到它成功为止。如果启动探针失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探针,则默认状态为成功Success。
探针有很多配置字段,可以使用这些字段精确的控制存活和就绪检测的行为:
- initialDelaySeconds:容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认是 0 秒,最小值是 0。
- periodSeconds:执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。
- timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。
- successThreshold:探测器在失败后,被视为成功的最小连续成功数。默认值是 1。存活探测的这个值必须是 1。最小值是 1。
- failureThreshold:当 Pod 启动了并且探测到失败,Kubernetes 的重试次数。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
Kubernetes 支持以下三种 probe 机制:
- HTTP GET probe:会发送 GET 请求到容器的 IP 地址、端口号和 URL 路径。如果 probe 收到正常的响应(2xx 或 3xx),该 probe 就被认定是成功的。如果服务返回了一个错误的响应码,或者没有在规定的时间内响应,则该 probe 被认定是失败的。
- TCP Socket probe:会尝试打开一个 TCP 连接到容器的特定端口。若连接成功,probe 就被认定是成功的;否则失败。
- Exec probe:会在容器内部执行一个命令并检查该命令的退出码。若退出码为 0,则 probe 被认定是成功的;否则失败。
在容器启动或关闭时触发动作
可以向容器中添加 lifecycle hooks。Kubernetes 目前支持两种类型的hook:
-
Post-start hooks:在容器启动后执行
post-start lifecycle hook 会在容器创建完成之后立即触发。可以使用 exec 类型的钩子在主进程启动的同时执行一个额外的程序,或者 httpGet 类型的钩子向容器中运行的应用发送 HTTP 请求,以完成初始化或预热操作。 -
Pre-stop hooks:在容器停止前执行
Nginx 服务在收到 TERM 信号后会立即关闭所有打开的连接并终止进程,这并不是理想的操作,不会等待正在处理的客户端请求彻底完成。
可以使用 pre-stop hook 执行 nginx -s quit 命令舒缓地关闭 Nginx 服务。
参考:
Kubernetes in Action - 管理 Pod 的生命周期
pod的生命周期管理
探活指针