Pod 的生命周期状态
QingyaFan opened this issue · comments
Pod 的状态
pkg/apis/core/types.go L3910
type PodStatus struct {
Phase PodPhase
Conditions []PodCondition
QOSClass PodQOSClass
ContainerStatuses []ContainerStatus
EphemeralContainerStatuses []ContainerStatus
Resize PodResizeStatus
ResourceClaimStatuses []PodResourceClaimStatus
}
- Phase:Pod 所处阶段
- Conditions:是一个 PodConditin 数组,我启动了一个 postgres 的 deployment,describe 其中一个 pod,你会发现
Pod 的阶段(phase)
PodPhase 是一个字符串别名:type PodPhase string
,是pod当前 condition 的一个描述,包括 Pending、Running、Succeeded、Failed、Unknown 1:
- Pending,被 Kubernetes 系统接受,但有x个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度和通过网络下载镜像
- Running,已绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器在运行,或者正处于启动或重启状态。
- Succeeded,Pod 中的所有容器都已成功终止,并且不会再重启。
- Failed,Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
- Unknown,因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。
从这些描述中,我们可以看出 Pod 和 Container 的关系很紧密。
Pod ReadinessGate
ReadinessGate 影响Pod是否就绪的判断,Pod就绪则会被认为可以接受请求。使用方法是在 Pod 的 .spec.readinessGates 加入 kv,它是一个数组,允许多个条件同时满足才被认定为 ready,例如:
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
...
kubectl patch方法不支持修改 status,只能用 client-go 之类的 sdk 编程实现,如通过 controller。如果一个 Pod 使用了自定义 condition,只有满足以下条件,Pod才能被认定为 ready:
- pod中所有的container都已 ready
- 所有 readinessGates 都为 True
如果 container 都已ready,但 readiness gates 并不都为 True,那么 Pod 状态将是 ContainersReady
与 ReadinessProbe 的不同
注意 k8s 的 ReadinessProbe(就绪探针)和 ReadinessGate 没有直接关系,但只有它俩都 ready,Pod才会被认定为可以接收请求。ReadinessProbe 支持 HTTP、RPC、执行脚本来确定某个Pod是否 ready:
HTTP
apiVersion: v1
kind: Pod
metadata:
name: http-readiness-pod
spec:
containers:
- name: http-container
image: my-http-app
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
说明:
- initialDelaySeconds:容器启动后,探针开始执行检查的延迟时间
- periodSeconds:探针检查的时间间隔
RPC
apiVersion: v1
kind: Pod
metadata:
name: tcp-readiness-pod
spec:
containers:
- name: tcp-container
image: my-rpc-app
ports:
- containerPort: 9090
readinessProbe:
tcpSocket:
port: 9090
initialDelaySeconds: 5
periodSeconds: 10
执行脚本
apiVersion: v1
kind: Pod
metadata:
name: exec-readiness-pod
spec:
containers:
- name: exec-container
image: my-script-app
readinessProbe:
exec:
command:
- /bin/sh
- -c
- "curl -f http://localhost:8080/healthz || exit 1"
initialDelaySeconds: 5
periodSeconds: 10
容器的状态(Status)
类型定义参见 2:
- Waiting,如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态。 处于 Waiting 状态的容器仍在运行它完成启动所需要的操作:例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等。 当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
- Running,Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。 如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时, 你也会看到关于容器进入 Running 状态的信息。
- Terminated,处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时, 你会看到容器进入此状态的原因、退出代码以及容器执行期间的起止时间。如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行。
Pod 或 容器 的异常状态 3
不明确状态有 Terminating、Pending、ContainerCreating、Waiting
异常状态有
- CrashLoopBackOff,Pod 如果处于 CrashLoopBackOff 状态说明之前是启动了,只是又异常退出了,只要 Pod 的 restartPolicy 不是 Never 就可能被重启拉起。
- ImagePullBackOff
Pod Condition
PodCondition 是 pod 的状况,phase 是对 condition 的标签
// staging/src/k8s.io/apiserver/pkg/apis/example/types.go L73
type PodCondition struct {
Type PodConditionType
Status ConditionStatus
// +optional
LastProbeTime metav1.Time
// +optional
LastTransitionTime metav1.Time
// +optional
Reason string
// +optional
Message string
}
PodCondition 有如下几个:
- PodScheduled, 表明Pod已经被调度到一个node
- PodReadyToStartContainers, Pod sandbox 已被成功创建并且网络已经正常
- ContainersReady, Pod 中所有的容器已 ready
- Initialized, 所有 init containers 均已完成
- Ready, Pod已经可以正常接受请求,可以加入到负载均衡的下游中了
- DisruptionTarget,表明pod正在被 terminated,原因可能是
抢占(preemption)
、驱逐(eviction)
或GC(garbage-collection)
Sidecar 容器对 Pod Condition 和 Ready 判断的影响
- 容器生命周期的不同步:Sidecar 容器通常用于辅助主应用容器,可能需要在主容器之前启动或在主容器之后停止。如果 Sidecar 容器启动较慢,Pod 的 Ready 状态会受到影响,因为 Kubernetes 会等待所有容器都处于就绪状态。例如,如果一个日志收集的 Sidecar 容器启动缓慢,主应用容器虽然已经就绪,但整个 Pod 仍然会被认为是未就绪的,直到 Sidecar 容器也就绪;
- 容器的健康检查:Kubernetes 使用健康检查(liveness 和 readiness probes)来确定容器的健康状态。如果 Sidecar 容器的健康检查配置不当,可能导致 Pod 被标记为不健康,尽管主应用容器正常运行。例如,如果 Sidecar 容器出现短暂的故障并触发了健康检查的失败,Pod 可能会被重启,影响到主应用容器的正常运行;
- 容器的资源消耗:Sidecar 容器可能会消耗大量资源(如 CPU、内存),从而影响 Pod 的整体性能和稳定性。如果资源分配不合理,可能导致资源争用,影响 Pod 的稳定性。例如,一个监控 Sidecar 容器消耗过多内存,导致主应用容器的内存不足,从而触发 Pod 的 OOM(Out Of Memory)情况;
- 终止信号的处理:Kubernetes 在终止 Pod 时,会向所有容器发送终止信号,并等待它们优雅地关闭。如果 Sidecar 容器关闭时间较长或无法正确处理终止信号,可能延迟整个 Pod 的终止过程。例如,一个代理 Sidecar 容器在接收到终止信号后需要较长时间关闭,可能会导致 Pod 无法及时释放资源,影响集群的调度效率。