Pod 是 Kubernetes(K8s)的最小部署/调度/管理单元,是理解 K8s 核心运行逻辑的基础。本文将按照「是什么→为什么需要→核心工作模式→工作流程→入门实操」的逻辑,把 Pod 讲透。
一、Pod 是什么?—— K8s 的“最小逻辑主机”
1. 核心定义
Pod 不是容器,而是 K8s 中封装一个/多个容器的最小可部署单元,可以理解为一台“轻量级的逻辑主机”:
- 一个 Pod 内的所有容器共享网络命名空间(同一个 IP、端口空间)、存储卷、UTS/IPC 命名空间;
- K8s 不会直接调度/管理容器,只会以 Pod 为单位进行调度、启停、监控。
2. 核心组成
每个 Pod 包含以下关键组件(即使是“单容器 Pod”也不例外):
| 组件 | 作用 |
|---|---|
| 业务容器 | 运行实际应用(如 Nginx、MySQL、微服务实例),可包含一个或多个 |
| Pause 容器 | 也叫 Infra 容器(K8s 自动创建),作为 Pod 的“根容器”: 1. 占据 Pod 的网络命名空间,维持网络标识; 2. 占用极少资源(CPU/内存可忽略); 3. 即使业务容器退出,Pause 容器仍会维持 Pod 存在 |
| 存储卷(Volumes) | Pod 级别的存储,挂载后所有容器可共享访问(如 ConfigMap、PVC、EmptyDir) |
| 网络 | 每个 Pod 有独立的集群内 IP,容器间通过 localhost 通信 |
3. 关键特性
- 原子性:Pod 要么全运行,要么全停止,K8s 不会只启动 Pod 内的部分容器;
- 临时性:Pod 是“一次性”的,删除后重建的 Pod 是全新的(IP、名称可能变化);
- 调度整体性:Pod 作为整体被调度到一个节点,不会跨节点拆分。
二、为什么需要 Pod?—— 解决容器直接部署的痛点
如果直接在 K8s 中部署容器(而非 Pod),会遇到以下核心问题:
| 痛点 | 直接部署容器的问题 | Pod 的解决方案 |
|---|---|---|
| 网络隔离 | 每个容器独立 IP,紧密耦合的容器通信需跨网络 | Pod 内容器共享 IP,localhost 通信,无网络隔离 |
| 存储共享 | 容器间共享文件需额外配置,无法直接挂载同卷 | Pod 级卷挂载后,所有容器可访问 |
| 生命周期不一致 | 容器启停独立,辅助容器(如日志采集)易失联 | Pod 内容器统一启停,生命周期绑定 |
| 调度效率低 | 相关容器可能被调度到不同节点,增加通信成本 | Pod 整体调度到一个节点,保证相关容器同节点运行 |
| 资源管理复杂 | 无法对一组容器统一分配资源 | 可为 Pod 整体设置资源限制(requests/limits) |
简单来说:Pod 解决了“紧密耦合的一组容器”的协同问题,让 K8s 对容器的管理更高效、更符合实际业务场景。
三、Pod 的核心工作模式
1. Pause 容器:Pod 的“灵魂容器”
Pause 容器是每个 Pod 的第一个启动的容器,是 Pod 能成为“逻辑主机”的核心:
- 它先启动并占据 Pod 的网络命名空间,后续业务容器都加入这个命名空间;
- 即使所有业务容器退出,只要 Pause 容器还在,Pod 的状态仍为
Running(除非重启策略为Never); - 官方镜像(如
k8s.gcr.io/pause:3.9)体积仅几十 KB,几乎不占用资源。
2. Pod 的两种核心类型(按容器数量)
(1)单容器 Pod(90%+ 场景)
最主流的 Pod 类型,一个 Pod 仅包含“Pause 容器 + 一个业务容器”,适用于独立的应用实例(如 Nginx、Redis 实例)。
- 特点:简单、易管理,是 Deployment、StatefulSet 等控制器的默认模式。
(2)多容器 Pod(辅助容器模式)
适用于“主业务容器 + 辅助容器”的场景,辅助容器为业务容器提供支撑,核心模式如下:
| 模式 | 作用 | 典型示例 |
|---|---|---|
| Sidecar(边车) | 与业务容器并行运行,提供日志采集、监控、代理等附加功能 | 应用容器 + Fluentd(日志采集) |
| Ambassador(大使) | 为业务容器提供网络代理/转发,隔离外部访问 | 数据库容器 + 代理容器(统一入口) |
| Adapter(适配器) | 转换业务容器的输出(如指标格式),适配外部系统(如 Prometheus) | 应用容器 + 指标转换容器 |
3. 生命周期与健康探针
(1)Pod 生命周期阶段
| 阶段 | 含义 |
|---|---|
| Pending | Pod 已提交到 K8s,但未调度到节点,或容器正在创建 |
| Running | Pod 已调度到节点,所有容器已创建,且至少一个容器在运行 |
| Succeeded | Pod 内所有容器正常退出(退出码 0),且不会重启 |
| Failed | Pod 内至少一个容器异常退出(退出码非 0),且不会重启 |
| Unknown | K8s 无法获取 Pod 状态(如节点失联) |
(2)健康探针(保证 Pod 可用性)
K8s 通过探针监控容器健康状态,支持 3 种核心探针:
| 探针类型 | 作用 | 触发行为 |
|---|---|---|
| 存活探针(livenessProbe) | 检测容器是否“活着”(如是否死锁) | 失败则按重启策略重启容器 |
| 就绪探针(readinessProbe) | 检测容器是否“就绪”(可接收请求) | 失败则将 Pod 从 Service 端点中移除 |
| 启动探针(startupProbe) | 检测容器是否“启动完成”(适合启动慢的应用,如 Java) | 启动阶段生效,失败则重启容器 |
4. 重启策略(RestartPolicy)
决定容器退出后 K8s 是否重启,作用于 Pod 内所有容器:
-
Always(默认):无论退出码是什么,都重启容器; -
OnFailure:仅当容器异常退出(退出码非 0)时重启; -
Never:容器退出后永不重启。
⚠️ 注意:重启操作在当前节点执行,不会调度到其他节点。
四、Pod 的完整工作流程
以“创建一个 Nginx Pod”为例,梳理从提交到运行的全流程:
步骤 1:用户提交 Pod 配置
用户通过 kubectl apply -f nginx-pod.yaml 提交配置,请求发送到 K8s APIServer。
步骤 2:APIServer 验证并存储
- APIServer 验证 YAML 语法、权限、资源限制等;
- 验证通过后,将 Pod 元数据写入 etcd(K8s 集群数据库);
- 返回“创建请求已接受”给用户。
步骤 3:Scheduler 调度 Pod
- Scheduler(调度器)通过 List-Watch 机制监听 APIServer,发现“未调度”的 Pod;
- 执行“筛选+打分”逻辑:
① 筛选:排除资源不足、有污点的节点;
② 打分:对符合条件的节点按优先级打分(如资源利用率、亲和性); - 选定目标节点后,向 APIServer 发送请求,将 Pod 的
spec.nodeName绑定到该节点,etcd 更新 Pod 信息。
步骤 4:Kubelet 创建 Pod
- 目标节点的 Kubelet 监听 APIServer,发现“绑定到本节点”的 Pod;
- Kubelet 调用容器运行时(如 containerd):
1. 先创建 Pause 容器,初始化网络命名空间、存储卷;
2. 创建业务容器(Nginx),加入 Pause 容器的网络命名空间; - Kubelet 将 Pod 状态(如 Running)上报给 APIServer,etcd 更新状态。
步骤 5:Pod 运行与监控
- Kubelet 通过探针持续监控容器健康状态;
- 若容器异常退出,按重启策略重启;
- 若节点故障,控制器(如 Deployment)会在其他节点重建 Pod。
步骤 6:Pod 销毁
- 用户执行
kubectl delete pod nginx-pod,请求发送到 APIServer; - APIServer 将 Pod 状态标记为
Terminating,etcd 更新; - Kubelet 向容器发送
SIGTERM信号(优雅退出),等待 30s 后发送SIGKILL强制终止; - Kubelet 清理 Pod 网络、存储资源,上报状态为
Terminated,etcd 删除 Pod 记录。
五、入门实操:从零创建并操作 Pod
前置条件
- 已搭建 K8s 集群(单节点推荐 minikube/kind,执行
kubectl get nodes能看到节点状态为Ready); - 已配置 kubectl 客户端。
实操 1:编写 Pod YAML 配置(Nginx 示例)
创建 nginx-pod.yaml 文件,关键字段带注释:
apiVersion: v1 # Pod 的稳定 API 版本为 v1
kind: Pod # 资源类型为 Pod
metadata: # 元数据(名称、标签等)
name: nginx-pod # Pod 名称(集群内唯一)
labels: # 标签(用于 Service/控制器筛选)
app: nginx
spec: # 核心规格定义
containers: # 容器列表(Pod 内的容器)
- name: nginx # 容器名称
image: nginx:1.24 # 容器镜像(指定版本避免最新版兼容问题)
ports: # 声明容器端口(仅标识,不映射到节点)
- containerPort: 80
resources: # 资源限制(避免占用过多节点资源)
requests: # 最小资源需求(调度时参考)
cpu: 100m # 100 毫核(0.1 核)
memory: 128Mi
limits: # 最大资源限制(超出则被 OOM 杀死)
cpu: 200m
memory: 256Mi
# 存活探针:检测 Nginx 是否存活
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10 # 容器启动 10s 后开始检测
periodSeconds: 5 # 每 5s 检测一次
# 就绪探针:检测 Nginx 是否可接收请求
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
restartPolicy: Always # 重启策略(默认)
实操 2:创建 Pod
执行命令:
kubectl apply -f nginx-pod.yaml
输出:pod/nginx-pod created
实操 3:查看 Pod 状态
# 查看所有 Pod(简洁版)
kubectl get pods
# 查看指定 Pod 详细信息(含事件、容器状态、资源等)
kubectl describe pod nginx-pod
# 查看 Pod 完整信息(IP、所在节点等)
kubectl get pods -o wide
正常输出示例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 1m 10.244.0.5 minikube <none> <none>
-
READY: 1/1:Pod 内 1 个业务容器已就绪; -
STATUS: Running:Pod 正常运行; -
IP: 10.244.0.5:Pod 的集群内 IP。
实操 4:进入 Pod 容器
# 进入 Nginx 容器的交互式终端
kubectl exec -it nginx-pod -- /bin/bash
# 验证 Nginx 版本
nginx -v
# 查看容器内网络(与 Pod IP 一致)
ip addr
# 退出容器
exit
实操 5:查看 Pod 日志
# 查看 Nginx 容器日志
kubectl logs nginx-pod
# 实时跟踪日志(类似 tail -f)
kubectl logs -f nginx-pod
实操 6:测试 Pod 网络
# 在 Pod 内测试 Nginx 服务
kubectl exec -it nginx-pod -- curl http://localhost:80
# 集群内其他节点/容器通过 Pod IP 访问
curl http://10.244.0.5:80
实操 7:重启/更新 Pod
⚠️ Pod 是临时性的,生产中建议用 Deployment 管理(支持滚动更新),手动重启方式:
# 方式 1:删除后重建(最简单)
kubectl delete pod nginx-pod
kubectl apply -f nginx-pod.yaml
# 方式 2:通过注解触发重启
kubectl annotate pod nginx-pod kubectl.kubernetes.io/restartedAt=$(date +%Y-%m-%dT%H:%M:%S) --overwrite
实操 8:删除 Pod
kubectl delete pod nginx-pod
# 验证删除
kubectl get pods
输出:No resources found in default namespace.
总结
Pod 是 K8s 的“基础积木”,核心要点:
- 本质:封装一组容器的“逻辑主机”,共享网络/存储,作为最小调度单元;
- 价值:解决容器直接部署的网络、存储、生命周期协同问题;
- 核心:Pause 容器维持网络标识,探针保证可用性,重启策略控制容器重启;
- 实操:生产中极少直接创建 Pod,而是通过 Deployment/StatefulSet 等控制器管理(保证高可用),但所有控制器的底层都是操作 Pod。
理解 Pod 后,再学习 Service、Ingress、控制器等组件,就能快速搭建完整的 K8s 应用架构。