Pod 的一生

原文:Pod Lifecycle

本文阐述了 Pod 的生命周期,这并不是一篇全面的文档,仅是这一话题的简介。

Pod 的阶段(Phase)

按照《API 公约》 的描述,Pod 阶段是对生命周期的一个阶段的概括。他不是一个对 Pod 或者容器层次的状态的详尽结论,也不是一个全面的状态机。

PodPhase 很封闭。除了本文提到的内容,不应该对一个 Pod 的 PodPhase 做出任何假设。

  • Pending:Pod 被系统接收,但是其中的一个或者多个容器镜像尚未创建。这一过程包括下载镜像的时间,以及被计划运行之前的时间。
  • Running:该 Pod 被分派给一个 Node,并且已经创建了所有容器。至少一个容器还在运行,或者正在被启动以及重启。
  • Succeeded:Pod 中的所有容器都已经成功结束,并且不会重新启动。
  • Failed:Pod 里所有的容器都已经结束运行,且至少一个容器的退出结果是失败的(被系统结束,或非 0 的退出状态)。
  • Unknown:因为某些原因无法获得 Pod 状态,一般来说是 Pod 所处主机的通信出了故障。

Pod 状态(Condition)

Pod 中容器的就绪检测会报告就绪状况,其取值可能是 True、False 或者 Unknown。

容器检测

Kubelet 会周期性的对容器进行检测 。这一过程是如下三种方法之一:

  • ExecAction:执行一个容器内的指定命令,如果命令返回码为 0 ,则代表成功。
  • TCPSocketAction:对目标容器的 IP 地址执行 TCP 操作,如果指定端口开放,则代表成功。
  • HTTPGetAction:对目标容器的 IP 地址、端口号以及路径进行 HTTP Get 操作,如果返回码在 200 和 400 之间,则检测成功。

检测过程可能会有三种结果之一:

  • Success:容器成功通过检测。
  • Failure:容器检测失败。
  • Unknown:检测未能完成。

目前 Kubelet 能够有两种独立的检测可以被触发:

  • LivenessProbe:用于检查当前容器是否存活,也就是正在运行。LivenessProbe 会告知 Kubelete 容器的健康状况。如果 LinenessProbe 失败,Kubelete 会杀掉这个容器,接下来,容器会根据 RestartPolicy(重启动策略)进行后续动作。容器在没进行这一检测之前的状态被标记为 Success。
  • ReadinessProbe:当前容器是否已经就绪,可以对外提供服务。如果这一检测失败的话,即使这一Pod 还在运行,Endpoint 控制器也会把这个 Pod 的 IP 地址从相关服务中移除,这样他就不会从 Proxy 获取流量(例如容器在提供服务之前会有一个较长的启动时间,或者容器正在关机维护)。在初始化完成之前,缺省的就绪状态是 Failure。当没有进行检测的时候,容器的就绪状态缺省假设为 Success。

容器状态(Statuses)

对容器状态的详细信息可以参考ContainerStatuses

重启策略

RestartPolicy 有几个可能的取值:Always,OnFailure 以及 Never。他的缺省值是 Always。RestartPolicy 作用于一个 Pod 中的所有容器。RestartPolicy 适用于同一 Node 的 Kubelet 的重启动操作。失败的容器会被 Kubelet 重启,重启之前会有一个渐进的延迟,延迟时长是同步频率的 0、1、2、4、8…倍,上限是五分钟,成功执行 10 分钟后会复位(延迟时间)。在 [Pod 文档中] 提到,Pod 一旦绑定到了一个 Node 上,就不会再绑定到其他 Node 了。这意味着即便是只有一个 Pod,也需要有控制器来进行操作,这样在 Node 失败的时候,才能保证 Pod 的存活。

目前有三种可用的控制器:

  • Job:用来执行会结束的 Pod (例如批处理运算)。
  • ReplicationController:不需要结束的 Pod (例如 Web Server)。
  • DaemonSet:每台(物理)机只能运行一个的 Pod,这种 Pod 提供机器相关的系统服务。如果在 ReplicationController 或者 Daemon 之间举棋不定,可以参考 Daemon Set vs Replication Controller

ReplicationController 是唯一符合 RestartPolicy = Always 需要的。Job 就适合另外两种。

所有三种控制器都有对应的 PodTemplate,跟 Pod 的字段一致。建议创建控制器,让控制器创建 Pod,而不是自行直接创建 Pod。这是因为 Pod 不具备适应服务器失败的能力,而控制器可以。

Pod 的生命期

一般来说, Pod 创建之后就不会消失,除非被手工销毁。销毁手段可能是人工、ReplicationController 或者其他控制器。唯一的例外是处于 Succeeded 或者 Failed 阶段一定时间的 Pod 会因过期(由 Master 决定)而被自动销毁。

如果一个 Node 崩溃或者从集群断开,系统内的实体(目前称为 NodeController )会负责执行策略(例如超时)并把丢失的 Node 中的所有 Pod 标记为 Failed。

例子

  • Pod 在 Running 状态,1 个容器,该容器成功退出
    • 记录结束事件
    • RestartPolicy 如果是
    • Always:重启容器,Pod 保持 Running 状态
    • OnFailure:Pod 转为 Succeeded 状态
    • Never:Pod 转为 Succeeded 状态
  • Pod 在 Running 状态,一个容器,容器失败退出
    • 记录失败事件
    • 如果 RestartPolicy 是:
    • Always:重启容器,Pod 保持 Running 状态
    • OnFailure:重启容器,Pod 保持 Running 状态
    • Never:Pod 进入 Failed 状态
  • Pod 在 Running 状态,两个容器,容器 1 失败退出
    • 记录失败事件
    • 如果 RestartPolicy 是:
    • Always:重启容器, Pod 保持 Running 状态
    • OnFailure:重启容器,Pod 保持 Running 状态
    • Never:Pod 保持 Running 状态
    • 容器 2 退出…
    • 记录失败事件
    • 如果 Restart Policy 是:
      • Always:重启容器,Pod 保持 Running 状态
      • OnFailure:重启容器,Pod 保持 running 状态
      • Never:Pod 进入 Failed 状态
  • Pod 在 Running 状态,容器内存不足
    • 容器失败退出
    • 记录 OOM 事件
    • 如果 RestartPolicy 是:
    • Always:重启容器,Pod 保持 Running
    • OnFailure:重启容器,Pod 保持 Running - Never:记录失败事件,Pod 进入 Failed 状态
  • Pod 在 Running 状态,一个磁盘坏掉。
    • 所有容器被 Kill
    • 记录事件
    • Pod 进入失败状态
    • 如果在控制器之下运行,则 Pod 会在其他位置被创建
  • Pod 在 Running 状态,所在 Node 被断开

    • NodeController 等待超时长
    • NodeController 标记 Pod 为 Failed 状态
    • 如果在控制器之下运行,则 Pod 会在其他位置被创建

      type PodStatus struct {
      // Current condition of the pod.
      // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase
      Phase PodPhase `json:"phase,omitempty"`
      // Current service state of pod.
      // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions
      Conditions []PodCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
      // A human readable message indicating details about why the pod is in this condition.
      Message string `json:"message,omitempty"`
      // A brief CamelCase message indicating details about why the pod is in this state.
      // e.g. 'OutOfDisk'
      Reason string `json:"reason,omitempty"`
      
      // IP address of the host to which the pod is assigned. Empty if not yet scheduled.
      HostIP string `json:"hostIP,omitempty"`
      // IP address allocated to the pod. Routable at least within the cluster.
      // Empty if not yet allocated.
      PodIP string `json:"podIP,omitempty"`
      
      // RFC 3339 date and time at which the object was acknowledged by the Kubelet.
      // This is before the Kubelet pulled the container image(s) for the pod.
      StartTime *unversioned.Time `json:"startTime,omitempty"`
      
      // The list has one entry per container in the manifest. Each entry is currently the output
      // of `docker inspect`.
      // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses
      ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty"`
      }
      
      type ContainerState struct {
      // Details about a waiting container
      Waiting *ContainerStateWaiting `json:"waiting,omitempty"`
      // Details about a running container
      Running *ContainerStateRunning `json:"running,omitempty"`
      // Details about a terminated container
      Terminated *ContainerStateTerminated `json:"terminated,omitempty"`
      }
      
Avatar
崔秀龙

简单,是大师的责任;我们凡夫俗子,能做到清楚就很不容易了。

comments powered by Disqus
下一页
上一页

相关