Kubernetes 中的 Pod 是容器运行的最小调度单元,它的生命周期并不是简单的启动与结束。一个 Pod 从创建到销毁会经历多个明确的阶段,每个阶段都承载着不同的调度与运行语义。理解这些阶段有助于诊断 Pod 无法启动、持续重启、删除卡住等问题。Pod 的生命周期由 API Server 中的 status.phase 字段记录,可能取值为 Pending、Running、Succeeded、Failed 和 Unknown。除此之外,每个容器自身还有 Waiting、Running、Terminated 三种状态,两者互相影响,共同描述 Pod 的真实运行情况。
一、Pod 的五个核心阶段分别代表什么
Pod 的 phase 字段是对其整体状态的高度概括,而不是容器级别的精确快照。当 Pod 刚创建时,它进入 Pending 阶段。这意味着 Kubernetes 已经接受了创建请求,但至少有一个容器尚未开始运行。常见的等待原因包括调度器还没有为 Pod 找到合适的节点、节点资源不足、镜像正在拉取或者存储卷正在挂载。如果 Pod 长时间停留在 Pending,通常需要通过 kubectl describe pod 查看事件,确认是调度失败还是镜像拉取超时。
当所有容器都成功启动并且至少有部分容器处于运行状态时,Pod 进入 Running 阶段。这里需要注意,Running 不代表所有容器都健康,也不代表服务已经就绪。一个 Pod 可能在 Running 状态下因为存活探针失败而反复重启,或者因为就绪探针未通过而无法接收流量。对于一次性任务类 Pod,当所有容器正常退出并且退出码为 0 时,Pod 会进入 Succeeded 阶段。如果任一容器以非零状态退出,或者容器被系统终止且没有自动重启,Pod 则会进入 Failed 阶段。
最后一个阶段是 Unknown,它通常表示 Pod 状态无法被 API Server 获得,常见原因是节点失联或者 kubelet 与 API Server 之间的网络异常。当节点恢复后,状态可能会重新同步。我们可以使用 kubectl get pods 查看当前所有 Pod 的 phase,也可以通过 kubectl describe pod <pod-name> 查看更详细的条件信息和事件记录,帮助判断状态转换是否正常。
# 查看 Pod 状态 kubectl get pods # 查看某个 Pod 的详细信息与事件 kubectl describe pod my-app-pod
二、容器生命周期钩子:postStart 与 preStop
容器生命周期钩子是 Kubernetes 在容器启动后和终止前暴露的两个关键介入点。它们定义在容器的 lifecycle 字段下,分别为 postStart 和 preStop。postStart 在容器创建后立即执行,但它与容器入口命令的执行顺序并不严格保证先后。也就是说,容器的主进程可能在 postStart 执行之前就已经开始运行。因此不要把关键初始化逻辑完全依赖在 postStart 上,它更适合做一些通知、写入文件或触发轻量级准备工作的场景。
preStop 则是在容器被终止之前调用的钩子,它会在容器收到 SIGTERM 信号之前执行。这是一个非常重要的优雅退出时机。比如在 Web 服务场景中,可以在 preStop 中执行健康检查摘除、通知负载均衡器移除实例或者完成正在进行的事务。下面是一个完整的生命周期钩子配置示例:
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: app
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo container started > /var/log/start.log"]
preStop:
exec:
command: ["/bin/sh", "-c", "nginx -s quit; sleep 15"]
上面的示例中,postStart 会在容器启动后写入一条日志,而 preStop 会先优雅关闭 Nginx 再等待 15 秒,给服务摘除流量留出时间。这种延迟有助于减少请求中断。需要注意的是,如果 preStop 执行时间过长,会与终止宽限期产生冲突,我们后面会详细讨论。
钩子执行失败会产生明显影响。如果 postStart 失败,容器会被杀死并根据重启策略决定是否重启。如果 preStop 失败,容器仍会被终止,但系统会记录失败事件。因此钩子脚本必须保证幂等和可重入,避免因为重复执行导致资源错乱。
三、探针如何影响 Pod 就绪与存活判定
探针是 Kubernetes 用于观察容器健康状态的核心机制,分为三类:livenessProbe、readinessProbe 和 startupProbe。存活探针用于判断容器是否仍然存活,如果连续失败达到阈值,kubelet 会杀死容器并触发重启。就绪探针用于判断容器是否准备好接收流量,当就绪探针失败时,Pod 会从 Service 的后端列表中移除,但容器本身不会被重启。启动探针专为启动时间较长的应用设计,它可以保护慢启动容器不会在初始化阶段就被存活探针误杀。
探针支持 exec 命令、HTTP GET 请求、TCP 端口检查三种方式。下面是一个同时配置 HTTP 存活探针和就绪探针的示例:
apiVersion: v1
kind: Pod
metadata:
name: probe-demo
spec:
containers:
- name: app
image: my-app:latest
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 2
上面的配置会让 kubelet 每 10 秒请求一次 /healthz,如果连续 3 次失败则重启容器。就绪探针每 5 秒请求一次 /ready,连续 2 次失败就会将 Pod 标记为未就绪。这种设计允许应用在启动后先完成缓存加载或数据库连接,再接收用户流量。
探针配置不合理常常是生产环境故障的根源。例如把存活探针检查的接口做成了依赖数据库的复杂查询,数据库抖动时就会触发容器频繁重启。就绪探针过于宽松则会导致请求打到尚未真正就绪的实例上,产生大量 5xx 错误。建议为启动时间超过 10 秒的应用单独配置 startupProbe,并给存活探针设置足够的 initialDelaySeconds 或使用启动探针保护。
四、Pod 终止与优雅退出的完整流程
当用户执行 kubectl delete pod 时,并不是立刻强制杀死容器。API Server 会先更新 Pod 的删除时间戳,然后进入 Terminating 状态。随后 kubelet 开始执行优雅终止流程:首先执行 preStop 钩子(如果定义了),然后向容器主进程发送 SIGTERM 信号。容器收到信号后应该停止接收新请求并完成正在处理的请求,然后自行退出。如果容器没有在 terminationGracePeriodSeconds 指定的时间内退出,kubelet 会发送 SIGKILL 强制杀死进程。
默认的宽限期是 30 秒,可以通过 Pod 的 spec.terminationGracePeriodSeconds 字段调整。例如下面配置将宽限期延长到 60 秒:
apiVersion: v1
kind: Pod
metadata:
name: graceful-shutdown-demo
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
image: my-app:latest
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 20"]
这段配置意味着删除 Pod 后,preStop 会先睡眠 20 秒,然后容器主进程收到 SIGTERM 信号。如果主进程正确处理信号并在剩余时间内退出,宽限期就不会耗尽。需要注意的是,preStop 的执行时间会计入宽限期。如果 preStop 本身执行了 50 秒,而宽限期只有 30 秒,那么容器会在 preStop 尚未结束时就收到 SIGKILL,导致优雅关闭失败。
Pod 长时间停留在 Terminating 状态的原因通常有几种:preStop 钩子执行时间超过宽限期、容器主进程忽略了 SIGTERM 信号、节点与 API Server 通信异常导致 kubelet 无法反馈状态、或者存储卷卸载一直未完成。排查时可以先用 kubectl describe pod 查看事件,再登录节点检查容器进程是否仍然存活。如果确认容器已经退出但 Pod 仍卡在 Terminating,可以尝试强制删除:kubectl delete pod <pod-name> --force --grace-period=0,但这会导致数据可能未持久化完成,只适用于紧急场景。
通过理解 Pod 生命周期的各个阶段、钩子执行时序、探针判定逻辑以及优雅终止机制,开发者可以更从容地定位和解决与容器调度、健康检查、流量摘除相关的问题,让应用在 Kubernetes 上运行得更加稳定。
Kubernetes PodPod 生命周期容器状态修改时间:2026-08-25 19:17:25