UP | HOME

生命周期

Table of Contents

接下来是 Kubernetes 中 Pod 的生命周期,包括生命周期的不同阶段、存活和就绪探针、重启策略等

相位

Pod 的 status 字段 是一个 PodStatus 对象

  • PodStatus中有一个 phase 字段 :是 Pod 在其生命周期中的简单宏观概述
这并不是对容器或 Pod 的综合汇总,也不是为了做为综合状态机

Pod 相位的数量和含义是严格指定的。除了下面列举的状态外,不应该再假定 Pod 有其他的 phase 值

下面是 phase 可能的值:

  • 挂起 Pending :Pod 已被 Kubernetes 系统接受,但有 一个或者多个 容器镜像 尚未创建

    等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间
    
  • 运行中 Running :该 Pod 已经 绑定 到了 一个节点 上,Pod 中 所有的容器 都已被 创建

    至少有一个容器正在 运行 ,或者正处于 启动 或 重启 状态
    
  • 成功 Succeeded :Pod 中的 所有容器 都被 成功终止 ,并且 不会再重启
  • 失败 Failed :Pod 中的 所有容器 都已 终止 了,并且 至少有一个 容器是因为 失败终止

    也就是说,容器以非0状态退出或者被系统终止
    
  • 未知 Unknown :因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败

下图是Pod的生命周期示意图,从图中可以看到Pod状态的变化:

kubernetes-pod-life-cycle.jpg

状态

Pod 有一个 PodStatus 对象 ,其中包含一个 PodCondition 数组

  • PodCondition 数组的每个元素都有一个 type 字段 和一个 status 字段
    • type 字段:字符串,可能的值有 PodScheduledReadyInitializedUnschedulableContainersReady
    • status 字段:字符串,可能的值有 TrueFalseUnknown

容器探针

探针 是由 kubelet 对容器执行的定期诊断 。要执行诊断 kubelet 调用 由容器实现的 Handler 。有三种类型的处理程序:

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

每次探测都将获得以下三种结果之一:

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

类型

Kubelet 可以选择是否执行在容器上运行的两种探针执行和做出反应:

  • livenessProbe :指示 容器是否正在运行
    • 如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响

      如果容器不提供存活探针,则默认状态为 Success
      
  • readinessProbe :指示容器是否 准备好服务请求
    • 如果就绪探测失败,端点控制器将从 与 Pod 匹配 的所有 Service 的端点删除 该 Pod 的 IP 地址
    • 初始延迟 之前的 就绪状态 默认为 Failure

      如果容器不提供就绪探针,则默认状态为 Success
      

用途

如果容器中的进程能够在遇到问题或不健康的情况下 自行崩溃 ,则不一定需要存活探针

kubelet 将根据 Pod 的restartPolicy 自动执行正确的操作

如果希望容器在 探测失败 时被 杀死并重新启动 ,那么请

  • 指定 一个 存活探针
  • 指定 restartPolicyAlwaysOnFailure

如果要 仅在探测成功 时才开始向 Pod 发送流量,请 指定 _就绪_探针

在这种情况下,就绪探针可能与存活探针相同,但是 spec 中的就绪探针的存在意味着 Pod 将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量

如果希望容器能够 自行维护 ,可以指定一个就绪探针,该探针检查与 存活探针不同的端点

如果只想在 Pod 被删除时能够排除请求 ,则不一定需要使用就绪探针 

在删除 Pod 时,Pod 会自动将自身置于未完成状态,无论就绪探针是否存在,当等待 Pod 中的容器停止时,Pod 仍处于未完成状态 

readinessGates

自 Kubernetes 1.14(在1.11 版本是为 alpha)起默认支持 Pod 就绪检测机制扩展

应用程序可以向 PodStatus 注入额外的反馈或信号: Pod readiness

要使用这个功能,请在 PodSpec 中设置 readinessGates 来指定 kubelet 评估 Pod readiness 的附加条件列表

Readiness gates 由 Pod 的 status.condition 字段的当前状态决定

如果 Kubernetes 在 Pod 的 status.conditions 字段中找不到这样的条件,则该条件的状态默认为 "False"

下面是一个例子:

kind: Pod
spec:
  readinessGates:
    - conditionType: "www.example.com/feature-1"
status:
  conditions:
    - type: Ready                              # 内置的 Pod 状态
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
    - type: "www.example.com/feature-1"        # 附加的额外的 Pod 状态
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
  containerStatuses:
    - containerID: docker://abcd...
      ready: true
添加的 Pod 条件的名称必须符合 Kubernetes 的 label key 格式

只有到 Pod 中的 所有容器状态 都是 Ready ,且 Pod 附加的额外状态检测的 readinessGates 条件 也是 Ready 的时候, Pod 的状态才是 Ready

Pod 和容器状态

有关 Pod 容器状态的详细信息,请参阅 PodStatusContainerStatus

请注意,报告的 Pod 状态信息取决于当前的 ContainerState

重启策略

PodSpec 中有一个 restartPolicy 字段:

  • 可能的值为 AlwaysOnFailureNever 。默认为 Always
  • restartPolicy 适用于 Pod 中的所有容器
  • restartPolicy 仅指通过 同一节点上的 kubelet 重新启动容器
    • 失败的容器由 kubelet 以 五分钟为上限 的 *指数退避延迟( (10秒,20秒,40秒…)重新启动,并在成功执行十分钟后重置
如 Pod 文档 中所述,一旦绑定到一个节点,Pod 将永远不会重新绑定到另一个节点

生命

一般来说,Pod 不会消失,直到人为销毁他们。这可能是一个 控制器

这个规则的唯一例外:成功或失败的 phase 超过一段时间(由 master 确定)的Pod将过期并被自动销毁

有三种可用的控制器:

  • 使用 Job 运行预期会终止 的 Pod,仅适用于重启策略为 OnFailure 或 Never 的 Pod

    例如:批量计算
    
  • 预期不会终止的 Pod 使用 ReplicationControllerReplicaSetDeployment ,仅适用于具有 restartPolicy 为 Always 的 Pod

    例如 Web 服务器
    
  • 提供 特定于机器的系统服务 ,使用 DaemonSet 为每台机器运行一个 Pod
所有这三种类型的控制器都包含一个 PodTemplate

建议创建适当的控制器,让它们来创建 Pod,而不是直接自己创建 Pod,这是因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以

如果 节点死亡 或与 集群的其余部分断开连接 ,则 Kubernetes 将应用一个策略将 丢失节点上的所有 Pod 的 phase 设置Failed

示例

高级 liveness 探针

存活探针由 kubelet 来执行,因此所有的请求都在 kubelet 的网络命名空间中进行:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - args:
    - /server
    image: k8s.gcr.io/liveness
    livenessProbe:
      httpGet:
        # when "host" is not defined, "PodIP" will be used
        # host: my-host
        # when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed
        # scheme: HTTPS
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      initialDelaySeconds: 15
      timeoutSeconds: 1
    name: liveness

不同状态

  1. Pod 中只有一个容器并且正在运行。容器成功退出:
    • 记录完成事件
    • 如果 restartPolicy 为:
      • Always:重启容器,Pod phase 仍为 Running
      • OnFailure:Pod phase 变成 Succeeded
      • Never:Pod phase 变成 Succeeded
  2. Pod 中只有一个容器并且正在运行。容器退出失败:
    • 记录失败事件
    • 如果 restartPolicy 为:
      • Always:重启容器,Pod phase 仍为 Running
      • OnFailure:重启容器,Pod phase 仍为 Running
      • Never:Pod phase 变成 Failed
  3. Pod 中有两个容器并且正在运行:
    • 容器1退出失败
      • 记录失败事件
      • 如果 restartPolicy 为:
        • Always:重启容器,Pod phase 仍为 Running
        • OnFailure:重启容器,Pod phase 仍为 Running
        • Never:不重启容器,Pod phase 仍为 Running
    • 如果有容器1没有处于运行状态,并且容器2退出:
      • 记录失败事件
      • 如果 restartPolicy 为:
        • Always:重启容器,Pod phase 仍为 Running
        • OnFailure:重启容器,Pod phase 仍为 Running
        • Never:Pod phase 变成 Failed
  4. Pod 中只有一个容器并处于运行状态。容器运行时内存超出限制:
    • 容器以失败状态终止
    • 记录 OOM 事件
    • 如果 restartPolicy 为:
      • Always:重启容器,Pod phase 仍为 Running
      • OnFailure:重启容器,Pod phase 仍为 Running
      • Never: 记录失败事件,Pod phase 仍为 Failed
  5. Pod 正在运行,磁盘故障:
    • 杀掉所有容器
    • 记录适当事件
    • Pod phase 变成 Failed
    • 如果使用控制器来运行,Pod 将在别处重建
  6. Pod 正在运行,其节点被分段:
    • 节点控制器等待直到超时
    • 节点控制器将 Pod phase 设置为 Failed
    • 如果是用控制器来运行,Pod 将在别处重建

Next:Pod Hook

Previous:安全策略

Home: pod