首先要了解一下 K8s 中的一个设计理念,就是这个状态机制。因为 K8S 的设计是面向状态机的,它里面通过 yaml 的方式来定义的是一个期望到达的一个状态,而真正这个 yaml 在执行过程中会由各种各样的 controller来负责整体的状态之间的一个转换。

k8s应用故障排查-了解状态机制_k8s

Phase

描述

Pending

Kubernetes 已经创建并确认该 Pod。此时可能有两种情况:

  • Pod 还未完成调度(例如没有合适的节点)
  • 正在从 docker registry 下载镜像

Running

该 Pod 已经被绑定到一个节点,并且该 Pod 所有的容器都已经成功创建。其中至少有一个容器正在运行,或者正在启动/重启

Succeeded

Pod 中的所有容器都已经成功终止,并且不会再被重启

Failed

Pod 中的所有容器都已经终止,至少一个容器终止于失败状态:容器的进程退出码不是 0,或者被系统 kill

Unknown

因为某些未知原因,不能确定 Pod 的状态,通常的原因是 master 与 Pod 所在节点之间的通信故障

比如说上面的图,实际上是一个 Pod 的一个生命周期。刚开始它处在一个 pending 的状态,那接下来可能会转换到类似像 running,也可能转换到 Unknown,甚至可以转换到 failed。然后,当 running 执行了一段时间之后,它可以转换到类似像 successded 或者是 failed,然后当出现在 unknown 这个状态时,可能由于一些状态的恢复,它会重新恢复到 running 或者 successded 或者是 failed 。

其实 K8s 整体的一个状态就是基于这种类似像状态机的一个机制进行转换的,而不同状态之间的转化都会在相应的 K8s对象上面留下来类似像 Status 或者像 Conditions 的一些字段来进行表示。

像下面这张图其实表示的就是说在一个 Pod 上面一些状态位的一些展现。

k8s应用故障排查-了解状态机制_Pod_02

比如说在 Pod 上面有一个字段叫 Status,这个 Status 表示的是 Pod 的一个聚合状态,在这个里面,这个聚合状态处在一个 pending 状态。

然后再往下看,因为一个 pod 里面有多个 container,每个 container 上面又会有一个字段叫 State,然后 State 的状态表示当前这个 container 的一个聚合状态。那在这个例子里面,这个聚合状态处在的是 waiting 的状态,那具体的原因是因为什么呢?是因为它的镜像没有拉下来,所以处在 waiting 的状态,是在等待这个镜像拉取。然后这个 ready 的部分呢,目前是 false,因为它这个镜像目前没有拉取下来,所以这个 pod 不能够正常对外服务,所以此时 ready 的状态是未知的,定义为 false。如果上层的 endpoint 发现底层这个 ready 不是 true 的话,那么此时这个服务是没有办法对外服务的。

再往下是 condition,condition 这个机制表示是说:在 K8s 里面有很多这种比较小的这个状态,而这个状态之间的聚合会变成上层的这个 Status。那在这个例子里面有几个状态,第一个是 Initialized,表示是不是已经初始化完成?那在这个例子里面已经是初始化完成的,那它走的是第二个阶段,是在这个 ready 的状态。因为上面几个 container 没有拉取下来相应的镜像,所以 ready 的状态是 false。

然后再往下可以看到这个 container 是否 ready,这里可以看到是 false,而这个状态是 PodScheduled,表示说当前这个 pod 是否是处在一个已经被调度的状态,它已经 bound 在现在这个 node 之上了,所以这个状态也是 true。

那可以通过相应的 condition 是 true 还是 false 来判断整体上方的这个状态是否是正常的一个状态。而在 K8s 里面不同的状态之间的这个转换都会发生相应的事件,而事件分为两种: 一种叫做 normal 的事件,一种是 warning 事件。大家可以看见在这第一条的事件是有个 normal 事件,然后它相应的 reason 是 scheduler,表示说这个 pod 已经被默认的调度器调度到相应的一个节点之上,然后这个节点是 cn-beijing192.168.3.167 这个节点之上。

再接下来,又是一个 normal 的事件,表示说当前的这个镜像在 pull 相应的这个 image。然后再往下是一个 warning 事件,这个 warning 事件表示说 pull 这个镜像失败了。

以此类推,这个地方表示的一个状态就是说在 K8s 里面这个状态机制之间这个状态转换会产生相应的事件,而这个事件又通过类似像 normal 或者是 warning 的方式进行暴露。开发者可以通过类似像通过这个事件的机制,可以通过上层 condition Status 相应的一系列的这个字段来判断当前这个应用的具体的状态以及进行一系列的诊断