Pod 生命周期一

Pod 生命周期

容器生命周期

init 容器

init 容器与普通的容器非常像,除了:

  1. init 容器总是运行到成功完成为止
  2. 每个 init 容器都必须在下一个 init 容器容器启动前完成

tips: 实际上最先生成 pause 容器

Podinit 容器失败,kubernetes 会不断地重启该 Pod,直到 init 容器成功为止。如果 Pod 对应的 restartPolicyNever,则Pod 启动失败

init 容器优势

init 容器 具有 与应用程序容器分离的单独镜像。

  1. 它们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的
  2. 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要 FROM另-一个镜像,只需要在安装过程中使用类似 sed、awk、 pythondig 这样的工具。
  3. 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建-一个单独的镜像。
  4. Init 容器使用 Linux Namespace , 所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问 Secret 的权限,而应用程序容器则不能。
  5. 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以 Init 容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了- -组先决条件。

容器探针

  1. livenessProbe : 指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死 容器 ,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
  2. readinessProbe : 指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配所有的 Serviceendpoint 中删除该 PodIP 地址。 初始延迟之前的就绪状态 默认为 Failure。 如果容器不提供就绪探针,则默认状态为 Success。
  3. startupProbe 通过后上面两个探针才会检测 startupProbe ,v1.16 新增 : 用于判断容器是否已启动好,如果探测失败,则 kubelet 会杀死 容器 ,并且容器将受到其 重启策略 的影响。如果容器不提供此探针,则默认状态为 Success。

探针是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 Handler 。有三种类型的处理程序。(k8s 为这些 Probe 内置的三个 Handler )

  1. ExecAction : 在容器内执行命令。如果命令退出时返回码为 0 则认为诊断成功。
  2. TCPSocketAction : 对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
  3. HTTPGetAction : 对指定的端口和路径上的容器 IP 地址执行 HTTP Get 请求。响应码 200 ~400(不包含400) ,则诊断认为是成功的。

一旦容器通过了 startupProbe 后, Kubelet 会每隔 定义的时间 进行一次探活检测 (livenessProbe),每隔 定义的时间 秒进行一次就绪检测(readinessProbe)。

探测结果:

  1. 成功: 容器通过了诊断
  2. 失败: 容器未通过诊断
  3. 未知: 诊断失败,因此不会采取任何行动。

重启策略

PodSpecrestartPolicy 字段,适用于 Pod 中所有容器。 值为 : Always, OnFailure,Never 。 没有此字段默认为 Always

restartPolicy 仅指通过 同一节点上的 kubelet 重新启动容器。

Pod hook

Pod hook(钩子)kubelet 发起,当容器的进程启动前或者容器中的进程终止前运行,这是包含在容器的生命周期之中,可以同时为 Pod 中所有容器都配置 hook

支持的 hook 类型:
postStart: 容器创建后立即执行,注意由于是异步执行,它无法保证一定在 ENTRYPOINT 之前运行。如果失败,容器会被杀死,并根据 RestartPolicy 决定是 否重启

preStop:容器终止前执行,常用于资源清理。如果失败,容器同样也会被杀死

钩子的回调函数支持两种方式:

  1. exec : 执行一段命令
  2. HTTPGET : 发送 HTTP 请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart: # 启动前动作
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler >/usr/share/message"]
preStop: # 退出前动作
exec:
command: ["/usr/sbin/nginx", "-s", "quit"] # 优雅退出

Pod phase

Podstatus 字段是一个 PodStatus 对象,PodStatus 中有一个 phase(相位) 字段,是对 Pod 在其生命周期中的简单宏观概述。

phase 仅有以下值:

  1. PendingPod 已被 Kuberntes 系统接受,但有一个或多个容器镜像尚未创建
  2. Running : 该 Pod 已绑定到了一个节点, Pod 中所有容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
  3. SucceededPod 中所有容器被成功终止 (退出返回 0),并且不会再被重启 。
  4. FailedPod 中所有容器都已终止,但至少有一个容器 以 非 0 状态退出或者被系统终止。
  5. Unknown: 因为某些原因无法取得 Pod 的状态。通常是因为 与 Pod 所在主机通信失败。

示例

Pod中只有一个容器并且正在运行,容器成功退出

  1. 记录事件完成

  2. 如果restartPolicy 为:

    1
    2
    3
    4
    5
    Always:重启容器;Pod phase 仍为 Running

    OnFailure: Pod phase 变成 Succeeded

    Never: Pod phase 变成 Succeeded

Pod 中只有一个容器并且正在运行。容器退出失败

  1. 记录失败事件

  2. 如果 restartPolicy 为:

    1
    2
    3
    4
    5
    Always:重启容器;Pod phase 仍为 Running

    OnFailure: Pod phase 仍为 Running

    Never: Pod phase 变成 failed

Pod 中有两个容器并且正在运行。容器有一个退出失败

  1. 记录失败事件

  2. 如果 restartPolicy 为:

    1
    2
    3
    4
    5
    Always:重启容器;Pod phase 仍为 Running

    OnFailure: Pod phase 仍为 Running

    Never: Pod phase 仍为 Running
    1. 如果有容器没有处于运行状态,并且另一个容器退出
      1
      2
      3
      4
      5
      Always:重启容器;Pod phase 仍为 Running

      OnFailure: Pod phase 仍为 Running

      Never: Pod phase 变成 failed

Pod 中只有一个容器并处于运行状态。容器运行时内存超出限制

  1. 容器以失败状态终止
  2. 记录 OOM 事件
  3. 如果restartPolicy为:
1
2
3
4
5
Always:重启容器;Pod phase 仍为 Running

OnFailure: Pod phase 仍为 Running

Never: Pod phase 变成 failed

Pod 正在运行,磁盘故障

  1. 杀掉所有容器。记录适当事件
  2. Pod phase 变成 Failed
  3. 如果使用控制器来运行,Pod 将在别处重建Pod

Pod 正在运行,其节点被分段

  1. 节点控制器等待直到超时
  2. 节点控制器将 Pod phase 设置为 Failed
  3. 如果是用控制器来运行,Pod 将在别处重建