Pod 的一生

POD 的阶段(Phase)

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操作

  • HTTPSocketAction 对容器IP和端口以及路径进行http Get操作。返回200和400之间

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

  • Success 容器成功通过检测

  • Failure 容器失败

  • Unknow 检测未完成

pod生命周期

  • pod创建后,一般不会自动销毁。除非手工销毁,销毁手段可能是人工或者控制器

目前 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 之间举棋不定

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

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

Pod 的生命期

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

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


type PodStatus struct {
	// +optional
	Phase PodPhase
	// +optional
	Conditions []PodCondition
	// A human readable message indicating details about why the pod is in this state.
	// +optional
	Message string
	// A brief CamelCase message indicating details about why the pod is in this state. e.g. 'Evicted'
	// +optional
	Reason string

	// +optional
	HostIP string
	// +optional
	PodIP string

	// 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.
	// +optional
	StartTime *metav1.Time
	// +optional
	QOSClass PodQOSClass

	// The list has one entry per init container in the manifest. The most recent successful
	// init container will have ready = true, the most recently started container will have
	// startTime set.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-and-container-status
	InitContainerStatuses []ContainerStatus
	// The list has one entry per container in the manifest. Each entry is
	// currently the output of `docker inspect`. This output format is *not*
	// final and should not be relied upon.
	// TODO: Make real decisions about what our info should look like. Re-enable fuzz test
	// when we have done this.
	// +optional
	ContainerStatuses []ContainerStatus
}

Chi-Chi Simon

IT软件和k8s工程师,开源爱好者。

Chi-Chi Simon