Pod对象的生命周期

Pod对象自从其创建开始到期终止退出的时间范围称其为生命周期。这个过程中Pod对象会处于多种不同的状态,并执行一些操作。其中创建主容器为必需操作,其他可选操作包括初始化容器、容器启动后钩子、容器的存活性探测、就绪性探测。以及容器终止前钩子等。

Pod的相位(状态?

无论以何种方式创建的Pod对象。总是处于其生命进程中,以下几个相位。

  • Pending:API Server已经创建了资源对象并存入etcd中,但尚未被调度完成或仍处于镜像下载过程中。
  • Running:Pod已经被调度至某个节点,并且所有容器已经被Kubelet创建完成。
  • Succeed:Pod中的所有容器已经成功终止,并且不会被重启。
  • Failed:所有容器都已经终止,但至少有一个容器终止失败。及容器返回了非零值的退出状态,或已经被系统终止。
  • Unknown:无法获取到对象的状态信息,通常是由于通讯问题造成的。即API Server无法与工作节点的Kubelet通信。

Pod的创建过程

  1. 用户通过Kubelet或者其他API客户端提交Pod spec给API Server
  2. API Serve尝试将对象的相关信息存入etcd中,执行完成即会返回相关信息
  3. API Server开始反映etcd中的变化,即可以通过kubectl get或其他命令查看资源
  4. 所有kubernetes组件均使用”watch”机制跟踪检查API Server上的变动
  5. kube-scheduler通过”watch”机制检测到API Server创建了新的Pod但尚未绑定至任一节点
  6. kube-scheduler为Pod对象挑选节点并将结果更新到API Server
  7. 调度结果由API Server更新至etcd中,同时API Server开始反映此Pod对象调度结果
  8. 目标工作节点上的Kubelet尝试启动容器并将结果状态返回值API server
  9. API server将Pod状态信息存入etcd系统中。
  10. 在etcd确认写入操作成功完成后,API Server将确认信息发送至相关的Kubelet,事件将通过它被接受

Pod生命周期中的重要行为

初始化容器

主容器启动之前要运行的容器,通常为主容器执行一些预置操作,有以下两种典型特征。

  1. 初始化容器必须运行完成直至结束,若运行失败,那么需要Kubernetes重启他直到成功完成。
  2. 每个初始化容器都必须按照定义的顺序运行。

如果Pod的spec.restartPolicy为”Never”,则运行失败的容器不会被重启。

初始化容器的典型应用场景有以下几个

  1. 用于运行特定的工具程序,出于安全等方面的原因,这些程序不是也包含在主容器镜像中。
  2. 提供主容器镜像中不具备的工具程序或自定义代码。
  3. 为容器镜像的构建和部署人员提供了分离、独立工作的途径。
  4. 初始化容器和主容器处于不同的文件系统视图中,因此可以分别安全的使用敏数据如Secrets资源
  5. 初始化容器要先于主容器串行启动并完成运行,因此可以用于建后主容器的启动,直至其依赖条件得到满足。

下面是一个示例:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: main
    image: ikubernetes/myapp:v1
  initContainers:
  - name: init
    image: busybox
    command: ['sh', '-c', 'sleep 10']

生命周期钩子函数

kubernetes为容器提供了两种生命周期钩子。

  • postStart:容器创建完成之后立即运行的钩子处理器。不过kubernetes无法确保一定在容器的ENTRYPOINT之前运行
  • preStop:容器终止操作之前运行的钩子处理器。以同步的方式调用,因此在其完成之前会阻塞删除容器的操作。

钩子处理器的实现方式有”Exec”和”HTTP”两种,第一种在触发时直接在容器中执行用户指定的命令,后一种在当前容器中向某URL发起HTTP请求。postStart和preStop 在容器的spec.lifecycle嵌套字段中,下面是一个示例:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: lifecycle-demo
    image: ikubernetes/myapp:v1
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/nginx/html/test.html"]

容器探测

其主要作用是用来检测Pod中容器的健康状态。有以下三种处理方式:

  • ExecAction:在容器中执行一个命令,并根据其返回的状态码进行诊断,为0即表示成功,否则为不健康状态。
  • TCPSocketAction:尝试与容器的某个TCP端口进行连接,成功打开即为正常,否则为不健康状态。
  • HTTPGetActione:向容器内指定的path发起HTTP GET请求响应码为2xx或3xx为成功,否则为失败。

检测结果有三种,”Success”、”Failure”、”Unknown”,只有第一种结果表示成功通过检测。
kubelet可以在活动容器上执行两种类型的检测,存活性检测和就绪性检测。

  • 存活性检测:用于判断容器是否处于运行状态。一旦检测失败,kubelet将根据restartPolicy的定义决定是否将其重启,未定义存活性检测的容器的默认状态为”success”
  • 就绪性检测:由于判断容器是否已经可以对外提供服务

后续会有更详细的关于存活性检测和就绪性检测的内容。

容器的重启策略

kubernetes可以定义三种重启策略

  • Aways:只要Pod对象终止就将其充起,此为默认设定。
  • OnFailure:请在出现错误时重启。
  • Never:从不重启。

注意其作用范围是Pod,即Pod之内的所有容器都会重启。请注意这是重启不是重建,所以其所在节点并不会有所改变。多次重启的时间间隔会逐渐变长,最长为300秒。

Pod的中止过程

下面是一个典型的Pod的终止流程:

  1. 用户发送删除Pod对象的命令
  2. API服务器中的Pod对象会随着时间推移更新,在默认的30秒宽限期内Pod被视为dead
  3. 将Pod标记为”Terminating”
  4. 和第三步同时运行。Kubelet监控到状态变为”Terminating”的同时启动Pod关闭过程
  5. 和第三步同时运行。端点控制器监控到关闭行为时,将其从所有匹配到此端点的service资源的端点列表中移出。
  6. 如果该对象定义了preStop钩子处理器,则再其标记为”Terminating”后即同步执行,若宽限期结束后仍未执行结束,则第二步会被重新执行,并获取一个时长为两秒的额外宽限期。
  7. Pod对象中的容器收到TERM信号
  8. 宽限期结束后若仍然存在运行的进程。,Pod对象会收到SIGKILL信号
  9. Kubelet请求API Server将该资源对象的宽限期设置为零,从而完成删除操作。

默认情况下的删除宽限期都是30秒,可以使用kubectl delete --grace-period=<second>命令自定义时长,指定为0则表示直接强制删除,此时需要使用--force选项。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!