摘要:理解 Pod 的容器共享模型、生命周期、Init Container 与 Sidecar,掌握启动、就绪和存活探针的配置及常见故障排查。
1. Pod 与容器共享模型
1. 什么是 Pod?
Pod 是 Kubernetes 中最小的可部署计算单元。
注意:Pod 不等于 Container。
一个 Pod 可以包含一个或多个容器,这些容器共享部分运行环境。
例如,一个 Web 应用可能由两个容器组成:
flowchart TB
subgraph G0["Pod"]
direction TB
N0["Container A<br/>Nginx"]
N1["Container B<br/>Log Agent"]
N2["Shared Network"]
N3["Pod IP"]
end
N0 -->|"共享"| N2
N1 -->|"共享"| N2
N2 --> N3
两个容器具有以下特点:
- 共享同一个网络命名空间。
- 共享同一个 Pod IP。
- 可以通过
localhost相互访问。 - 可以通过 Volume 共享文件。
- 具有各自独立的容器文件系统。
例如:
Nginx 监听 80 端口,日志代理监听 9000 端口。
两个容器可以这样通信:
curl http://localhost:9000这里的 localhost 指向整个 Pod 的网络命名空间,而不是某一个容器。
重要:同一个 Pod 中的容器不能监听相同的 IP 和端口组合,否则会发生端口冲突。
2. 为什么 Kubernetes 引入 Pod?
为什么不直接让 Kubernetes 管理 Container?
主要原因是:某些容器在业务上具有紧密的协作关系,需要被调度到同一台机器上运行。
例如:
| 容器 | 作用 |
|---|---|
| Nginx | 提供 Web 服务 |
| Log Agent | 收集 Nginx 日志 |
| Proxy | 提供本地代理服务 |
这些容器通常需要:
- 部署在同一节点。
- 共享网络。
- 共享部分存储。
- 具有相同的生命周期管理边界。
因此 Kubernetes 使用 Pod 作为调度和管理的基本单位。
注意:Pod 中的多个容器是共同调度的,不会被分别调度到不同节点。
2. Pod 与 Deployment 有什么区别?
初学者最容易混淆这两个概念。
| 对比 | Pod | Deployment |
|---|---|---|
| 主要职责 | 运行容器 | 管理无状态应用的 Pod 副本 |
| 是否管理副本数量 | 不负责维持副本数量 | 通过 ReplicaSet 维持期望副本数 |
| Pod 删除后 | 不会自行恢复原对象 | 通常会创建替代 Pod |
| 常见用途 | 调试、理解容器运行机制 | 部署和管理长期运行的应用 |
例如:
flowchart TB
N0["Deployment"]
N1["ReplicaSet"]
N2["Pod 1"]
N3["Pod 2"]
N4["Pod 3"]
N0 --> N1
N1 --> N2
N1 --> N3
N1 --> N4
如果期望副本数为 3,而一个 Pod 被删除,ReplicaSet 会尝试创建替代 Pod。
生产环境部署 Nginx、Go API 等无状态服务时,通常优先使用 Deployment,而不是直接创建独立 Pod。
3. Pod YAML 结构与字段
apiVersion: v1kind: Podmetadata: name: nginx-pod labels: app: nginxspec: containers: - name: nginx image: nginx:1.28 ports: - name: http containerPort: 80解释几个关键字段:
| 字段 | 含义 |
|---|---|
apiVersion: v1 | 使用 Kubernetes 核心 API |
kind: Pod | 创建的资源类型是 Pod |
metadata.name | Pod 的名称 |
metadata.labels | 为 Pod 添加标签,便于选择和管理 |
spec.containers | 声明 Pod 中的容器 |
image | 容器使用的镜像 |
containerPort | 声明容器预期监听的端口,不会自动向外暴露端口 |
4. Pod 的生命周期与创建流程
这是 CKA 非常重要的知识点。
Pod 从创建到结束,会经历不同的生命周期阶段。
1. Pod 的五种主要状态
Kubernetes Pod 的 Phase 主要有五种:
| 状态 | 含义 |
|---|---|
| Pending | Pod 已被接受,但尚未完成运行准备 |
| Running | Pod 已绑定到节点,至少一个容器正在运行或正在启动 / 重启 |
| Succeeded | Pod 中所有容器均成功终止 |
| Failed | Pod 中所有容器均已终止,且至少一个容器以失败状态退出 |
| Unknown | 无法获取 Pod 当前状态,通常与节点通信问题有关 |
注意:
Pod Phase 和 kubectl get pods 显示的 STATUS 并不完全相同。
例如:
NAME READY STATUS RESTARTSnginx 0/1 CrashLoopBackOff 5mysql 0/1 ImagePullBackOff 0redis 1/1 Running 0其中:
- CrashLoopBackOff 是容器等待状态相关的展示信息。
- ImagePullBackOff 是镜像拉取失败后的退避状态。
- Running 才是 Pod 的 Phase 之一。
2. Pod 生命周期流程
理解过程:
flowchart TB
N0["创建 Pod"]
N1["Pending"]
N2["绑定 Node"]
N3["创建容器"]
N4["Running"]
N5["正常完成"]
N6["异常退出"]
N7["Succeeded"]
N8["Failed"]
N0 --> N1
N1 -->|"Scheduler 选择节点"| N2
N2 -->|"Kubelet 创建 Pod 沙箱"| N3
N3 -->|"容器启动"| N4
N4 --> N5
N4 --> N6
N5 --> N7
N6 --> N8
这里需要特别理解:
Pending 不代表 Pod 创建失败。
它可能正在等待:
- 调度器分配节点。
- 节点资源满足要求。
- PVC 绑定。
- 镜像下载。
- 容器创建准备。
因此,遇到 Pending 时不要直接删除 Pod,首先应该排查原因。
3. 创建、运行与替换过程
flowchart TB
N0["1. 创建 Pod<br/>提交 YAML,API Server 接收请求"]
N1["2. 调度 Pod<br/>Scheduler 选择合适的 Node"]
N2["3. 节点启动容器<br/>kubelet 调用容器运行时,拉取镜像并启动容器"]
N3["4. 运行与健康检查<br/>容器运行,探针检查应用状态"]
N4["5. 结束或被替换<br/>容器退出、Pod 删除,控制器可能创建替代 Pod"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4
5. Container 的生命周期
Pod 有生命周期,Pod 内部的 Container 同样有自己的生命周期。
容器的主要状态包括:
| 状态 | 含义 |
|---|---|
| Waiting | 容器正在等待启动条件 |
| Running | 容器正在运行 |
| Terminated | 容器已经终止 |
1. 容器状态转换
flowchart TB
N0["Waiting"]
N1["Running"]
N2["Terminated"]
N0 -->|"启动成功"| N1
N1 -->|"进程退出"| N2
例如:
容器启动时需要下载镜像。
如果镜像不存在,就可能处于 Waiting 状态。
如果容器主进程执行结束,就会进入 Terminated 状态。
2. 查看容器状态
kubectl get pod nginx-pod -o jsonpath='{.status.containerStatuses}'也可以:
kubectl describe pod nginx-pod重点关注:
State: RunningLast State: TerminatedRestart Count: 3其中:
- State:当前容器状态。
- Last State:上一次容器状态。
- Restart Count:容器重启次数。
3. 容器退出码(Exit Code)
这是排查容器故障时非常重要的信息。
| Exit Code | 常见含义 |
|---|---|
| 0 | 正常退出 |
| 1 | 应用程序一般性错误 |
| 2 | 命令或参数使用错误 |
| 126 | 命令存在但无法执行 |
| 127 | 命令不存在 |
| 137 | 通常表示 SIGKILL,可能是 OOM 或强制终止 |
| 139 | 通常表示 SIGSEGV,段错误 |
| 143 | 通常表示 SIGTERM |
注意:退出码 137 不一定就是 OOM,需要结合 Reason 是否为 OOMKilled 判断。
查看上次退出原因:
kubectl describe pod nginx-pod也可以:
kubectl get pod nginx-pod \ -o jsonpath='{.status.containerStatuses[0].lastState.terminated}'6. Init Container(初始化容器)
这是 Kubernetes Pod 中非常重要的机制。
1. 什么是 Init Container?
Init Container 是在应用容器启动之前运行的初始化容器。
主要用于完成应用运行之前的准备工作。
例如:
- 检查数据库是否可以连接。
- 等待其他服务启动。
- 下载初始化配置。
- 创建必要目录。
- 执行数据库初始化脚本。
执行顺序:
flowchart TB
N0["创建 Pod"]
N1["Init Container 1"]
N2["Init Container 2"]
N3["所有 Init Container 成功完成"]
N4["启动普通应用容器"]
N5["Pod Running"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4
N4 --> N5
重要:多个普通 Init Container 按照定义顺序依次执行,前一个成功完成后才会执行下一个。
如果某个 Init Container 失败,Kubernetes 通常会根据 Pod 的重启策略重新执行初始化过程。
2. Init Container YAML 示例
需求:
启动 Nginx 之前,先确保某个初始化文件存在。
apiVersion: v1kind: Podmetadata: name: init-demospec: initContainers: - name: init image: busybox:1.36 command: - sh - -c - "echo initialization completed > /work/index.html" volumeMounts: - name: workdir mountPath: /work
containers: - name: nginx image: nginx:1.27 ports: - containerPort: 80 volumeMounts: - name: workdir mountPath: /usr/share/nginx/html
volumes: - name: workdir emptyDir: {}1. Init Container 与普通 Container 的区别
| 对比 | Init Container | 普通 Container |
|---|---|---|
| 启动顺序 | 应用容器之前 | 初始化容器之后 |
| 执行方式 | 传统模式下依次执行 | 通常并行运行 |
| 主要用途 | 初始化准备 | 运行应用 |
| 生命周期 | 通常执行完成后退出 | 通常持续运行 |
| 健康检查 | 不支持常规应用容器探针 | 支持探针 |
补充:Kubernetes 也支持具有 Sidecar 行为的特殊 Init Container,它可以在应用容器启动后继续运行。
7. Sidecar Container(边车容器)
1. 什么是 Sidecar?
Sidecar 是一种容器设计模式。
它的核心思想是:
主容器负责业务,Sidecar 容器负责辅助功能。
例如:
flowchart TB
subgraph G0["Pod"]
direction TB
N0["Main Container<br/>Nginx"]
N1["Sidecar Container<br/>Log Collector"]
end
典型应用:
| 主容器 | Sidecar |
|---|---|
| Nginx | 日志采集 |
| Java 服务 | 日志处理 |
| Web 服务 | 服务代理 |
| 应用程序 | 配置同步 |
Sidecar 与普通的多容器 Pod 不同之处,在于它强调辅助容器与主容器之间的职责分工和协作关系。
2. Sidecar 与 Init Container 的区别
| 对比 | Init Container | Sidecar |
|---|---|---|
| 主要职责 | 初始化 | 辅助主应用 |
| 运行时间 | 通常短暂 | 通常长期运行 |
| 启动顺序 | 在主容器之前 | 可以先于主容器启动 |
| 生命周期 | 完成任务后退出 | 通常伴随应用运行 |
Kubernetes 从 v1.29 开始引入原生 Sidecar 容器的稳定演进机制,并在 v1.33 将其作为稳定功能。
原生 Sidecar 通过 initContainers 配合 restartPolicy: Always 声明:
apiVersion: v1kind: Podmetadata: name: sidecar-demospec: initContainers: - name: log-agent image: busybox:1.36 restartPolicy: Always command: - sh - -c - "while true; do echo collecting logs; sleep 10; done"
containers: - name: app image: nginx:1.27这里的 log-agent 虽然写在 initContainers 中,但它不会在任务完成后退出,而是持续运行。
8. 容器重启策略与 Pod 替换
Kubernetes 并不保证每次容器退出都会创建一个新 Pod。具体行为取决于 Pod 的 restartPolicy 以及是否有控制器管理它。
restartPolicy | 容器退出后的行为 | 常见用途 |
|---|---|---|
Always | 始终尝试重启容器 | 长期运行的应用,默认值 |
OnFailure | 容器非零退出时尝试重启 | 任务型容器 |
Never | 不自动重启容器 | 一次性运行任务 |
注意:restartPolicy 控制的是 同一个 Pod 内的容器是否重启,不等于创建新的 Pod。
Deployment 管理的 Pod 使用 Always。当 Pod 被删除或节点发生故障时,Deployment/ReplicaSet 等控制器会根据期望状态尝试补足副本。
适用规则:
- 普通 Pod 默认使用 Always。
- Deployment、StatefulSet、DaemonSet 的 Pod 必须使用 Always。
- Job 的 Pod 可以使用 OnFailure 或 Never。
- CronJob 通过创建 Job 执行任务,重启策略遵循 Job 的 Pod 模板规则。
9. 健康检查探针
这是 CKA 和生产环境非常重要的内容。
Kubernetes 如何判断一个容器是否健康?
不能只看容器是否在运行。
例如:
Nginx 进程还在,但是内部业务已经无法响应请求。
这时候 Kubernetes 就需要健康检查机制。
Kubernetes 提供三种探针:
1. Liveness Probe
判断容器是否还正常工作。
例如:
应用发生死锁,进程仍然存在,但无法正常提供服务。
可以使用 Liveness 检查。连续失败达到阈值后,kubelet 会根据 Pod 的重启策略处理容器重启。
livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 2 failureThreshold: 3含义:
- initialDelaySeconds:首次探测前等待 10 秒。
- periodSeconds:每隔 5 秒探测一次。
- timeoutSeconds:单次探测超时 2 秒。
- failureThreshold:连续失败 3 次后判定失败。
2. Readiness Probe
判断容器是否准备好接收请求。
readinessProbe: httpGet: path: / port: 80 periodSeconds: 5例如:
Pod-1:ReadyPod-2:NotReadyPod-3:ReadyService 正常情况下只会将流量转发到 Ready 的后端。
注意:Readiness 失败不会直接重启容器。
3. Startup Probe
主要解决应用启动时间比较长的问题。
例如 Java 应用启动需要 90 秒。
如果直接使用 Liveness Probe,可能还没启动成功就被反复重启。
可以使用:
startupProbe: httpGet: path: / port: 8080 periodSeconds: 10 failureThreshold: 15表示最多允许约 150 秒的探测失败时间(实际还受探测执行时间等因素影响)。
启动探针成功后,才开始执行 Liveness 和 Readiness 探针。
4. 三种探针的区别
| 探针 | 检查目的 | 失败后处理 |
|---|---|---|
| Liveness | 是否需要重启 | 达到失败阈值后,根据重启策略处理 |
| Readiness | 是否可以接收流量 | 暂停接收 Service 流量 |
| Startup | 是否完成启动 | 持续失败达到阈值后,根据重启策略处理 |
CKA 高频考点
记忆口诀:
- Liveness:活着没有?
- Readiness:准备好没有?
- Startup:启动完成没有?
5. 探针参数与配置注意事项
| 参数 | 含义 |
|---|---|
httpGet | 向指定端口和路径发送 HTTP 请求 |
periodSeconds | 两次探针检查的间隔秒数 |
failureThreshold | 连续失败多少次后判定探针失败 |
initialDelaySeconds | 首次检查前等待的秒数 |
timeoutSeconds | 单次探针超时阈值 |
生产环境中,存活探针不宜简单依赖外部数据库等下游服务,否则下游短暂故障可能触发大量应用容器重启。
10. Pod 故障排查
这是实际工作中最常见的任务。
1. 常见异常状态
| 状态或现象 | 常见原因 | 排查方向 |
|---|---|---|
| Pending | 资源不足、调度约束不满足、PVC 未绑定 | kubectl describe pod、Events |
| ImagePullBackOff / ErrImagePull | 镜像不存在、拉取错误、仓库认证失败 | 镜像名称、地址、凭证、Pod Events |
| CrashLoopBackOff | 应用启动失败、配置错误、启动命令或探针失败 | 日志、kubectl logs --previous、探针配置 |
| OOMKilled | 容器内存超限或节点内存不足导致被杀 | 容器状态、资源限制、内存使用、节点日志 |
| CreateContainerConfigError | ConfigMap、Secret 等配置异常 | 配置资源 |
| ContainerCreating | 容器尚在创建 | describe、Events |
| Running 但访问失败 | 应用未就绪、端口错误、网络问题 | Probe、Service、EndpointSlice |
2. 故障排查命令
第一步:查看 Pod 状态。
kubectl get pods -o wide第二步:查看详细事件。
kubectl describe pod <pod-name>第三步:查看容器日志。
kubectl logs <pod-name>第四步:查看上一次崩溃的日志。
kubectl logs <pod-name> --previous第五步:查看集群事件。
kubectl get events --sort-by=.metadata.creationTimestamp这五个命令建议熟练掌握。
不要只看 kubectl get pods 的状态。排查时应该结合 describe、日志、事件以及实际网络请求。
11. 知识检查清单
本节需要掌握的核心知识
| 知识点 | 掌握程度 |
|---|---|
| Pod 基本结构与共享机制 | 必须掌握 |
| Pod 五种 Phase | 必须掌握 |
| Container 三种状态 | 必须掌握 |
| Init Container | 必须掌握 |
| Sidecar | 理解原理 |
| RestartPolicy | 必须掌握 |
| 三种健康探针 | 必须掌握 |
| Pod 故障排查 | 必须掌握 |