kubectl get pod 的 STATUS 一栏、Pod 的 phase、conditions、容器 state,到底谁是谁?为什么 Running 的 Pod 还没就绪、为什么 Terminating 在 phase 里找不到?这篇用几个故意卡在不同位置的 Pod,把三层状态各自在什么时候变、和 kubectl 的显示怎么对应都量出来。
Pod ok(readinessProbe 检查 /tmp/ready 是否存在,一开始没有这个文件):
+ 0.0s phase=Pending PodScheduled=True Initialized=True ContainersReady=False Ready=False 容器=waiting(ContainerCreating)
+ 0.7s phase=Running PodScheduled=True Initialized=True ContainersReady=False Ready=False 容器=running
在容器里创建 /tmp/ready 之后 2.5 秒:phase=Running Ready=True ContainersReady=True 容器 ready=True带就绪探针的 Pod 启动过程:+0.0 秒 phase=Pending(容器 ContainerCreating),这时 PodScheduled、Initialized 已经是 True;+0.7 秒 phase=Running,容器已经启动,但 ContainersReady 和 Ready 仍是 False,因为探针检查的 /tmp/ready 还不存在。创建这个文件之后 Ready 才变成 True。Service 只会把 Ready 的 Pod 加入后端,所以“Running”并不意味着能收流量。
nosched phase=Pending Ready=None 容器状态=-;PodScheduled=False reason=Unschedulable message=0/3 nodes are available: 1 node(s) had untolerated taint(s), 2 node(s) didn't ma badimg phase=Pending Ready=False 容器状态=waiting(ContainerCreating);waiting.reason=ContainerCreating oneshot phase=Succeeded Ready=False 容器状态=terminated(Completed);exitCode=0 reason=Completed failing phase=Failed Ready=False 容器状态=terminated(Error);exitCode=3 reason=Error kubectl get pod 的 STATUS 列(和 phase 不是一回事):badimg=ContainerCreating | failing=Error | nosched=Pending | ok=Running | oneshot=Completed
nodeSelector 无节点匹配的 Pod:phase=Pending,PodScheduled=False,reason Unschedulable,message 0/3 nodes are available: …;镜像标签不存在的 Pod:phase=Pending,容器 waiting(ContainerCreating)——这台机器拉不到镜像,将近一分钟后还没有走到 ErrImagePull;restartPolicy: Never 的 echo 成功是 Succeeded,exit 3 是 Failed(容器 terminated(Error)、exitCode=3)。kubectl get 的 STATUS 列(ContainerCreating、Error、Completed……)是 kubectl 综合 phase 和容器状态算出来的,不是 phase。
Pod slow(sh -c "sleep 3600" 作为 1 号进程不处理 SIGTERM,terminationGracePeriodSeconds=20)执行 kubectl delete 1 秒后:phase=Running;metadata.deletionTimestamp=有;deletionGracePeriodSeconds=20;容器状态=running kubectl get pod slow 的 STATUS 列:Terminating 最终在 21 秒后被 SIGKILL 并消失(Pod 对象被删除)
删除一个不处理 SIGTERM 的 Pod(sh -c "sleep 3600" 作 1 号进程):1 秒后 phase 仍是 Running,metadata.deletionTimestamp 已设置,deletionGracePeriodSeconds=20,容器还在运行,kubectl get 显示 Terminating。要等满 20 秒的宽限期,进程被 SIGKILL,Pod 对象才消失(这次 21 秒)。Terminating 是展示层的说法,不是 phase 的取值。
restartPolicy=OnFailure、容器 3 秒后 exit 1,30 秒后:phase=Running restartCount=2 当前 state=terminated lastState.terminated(exitCode=1,reason=Error) Ready=False(容器在两次重启之间不就绪);phase 一直是 Running,不会因为反复崩溃变成 Failed
restartPolicy: OnFailure、3 秒后 exit 1 的容器,30 秒内重启了 2 次:restartCount=2,当前 state=terminated,lastState.terminated 记着上一次的 exitCode=1、reason=Error;Ready=False(两次重启之间容器不就绪),phase 却一直是 Running。反复崩溃的 Pod 不会变成 Failed,看崩溃要看 restartCount 和 lastState。