Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pod 的生命周期状态 #31

Closed
QingyaFan opened this issue Apr 26, 2023 · 0 comments
Closed

Pod 的生命周期状态 #31

QingyaFan opened this issue Apr 26, 2023 · 0 comments

Comments

@QingyaFan
Copy link
Owner

QingyaFan commented Apr 26, 2023

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,你会发现

image

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:

  1. pod中所有的container都已 ready
  2. 所有 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 判断的影响

  1. 容器生命周期的不同步:Sidecar 容器通常用于辅助主应用容器,可能需要在主容器之前启动或在主容器之后停止。如果 Sidecar 容器启动较慢,Pod 的 Ready 状态会受到影响,因为 Kubernetes 会等待所有容器都处于就绪状态。例如,如果一个日志收集的 Sidecar 容器启动缓慢,主应用容器虽然已经就绪,但整个 Pod 仍然会被认为是未就绪的,直到 Sidecar 容器也就绪;
  2. 容器的健康检查:Kubernetes 使用健康检查(liveness 和 readiness probes)来确定容器的健康状态。如果 Sidecar 容器的健康检查配置不当,可能导致 Pod 被标记为不健康,尽管主应用容器正常运行。例如,如果 Sidecar 容器出现短暂的故障并触发了健康检查的失败,Pod 可能会被重启,影响到主应用容器的正常运行;
  3. 容器的资源消耗:Sidecar 容器可能会消耗大量资源(如 CPU、内存),从而影响 Pod 的整体性能和稳定性。如果资源分配不合理,可能导致资源争用,影响 Pod 的稳定性。例如,一个监控 Sidecar 容器消耗过多内存,导致主应用容器的内存不足,从而触发 Pod 的 OOM(Out Of Memory)情况;
  4. 终止信号的处理:Kubernetes 在终止 Pod 时,会向所有容器发送终止信号,并等待它们优雅地关闭。如果 Sidecar 容器关闭时间较长或无法正确处理终止信号,可能延迟整个 Pod 的终止过程。例如,一个代理 Sidecar 容器在接收到终止信号后需要较长时间关闭,可能会导致 Pod 无法及时释放资源,影响集群的调度效率。

Footnotes

  1. https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/

  2. /~https://github.com/kubernetes/kubernetes/blob/16a594f907d0d4a6224dab2d0704793d5e7898f6/pkg/apis/core/types.go#L2678

  3. https://imroc.cc/kubernetes/troubleshooting/pod/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant