Pod 是 Kubernetes 中最核心、最基础的概念,k8s 中的一切操作几乎都围绕 Pod 展开——调度、扩缩容、服务发现、持久化存储,无一不是以 Pod 为载体。理解 Pod,是学习 Kubernetes 的第一站,也是最重要的一站。
前言
在 Kubernetes 的世界里,Pod 是最基本、最小的调度单元。无论你部署的是无状态的 Web 服务,还是复杂的分布式数据库,最终运行在集群中的都是 Pod。可以说,Kubernetes 中的一切都围绕着 Pod 展开。
本文将从 Pod 是什么、为什么需要 Pod、Pod 的内部结构、生命周期、声明式管理等多个维度,系统性地梳理 Pod 的核心概念。
一、Pod 是什么
1.1 最小调度单元
在 Kubernetes 中,Pod 是最小的可调度单元(Smallest Schedulable Unit)。这意味着 k8s 调度器在分配计算资源时,以 Pod 为单位将它们调度到合适的 Node 上运行,而不是直接调度单个容器。
1.2 Pod ≠ 容器
Pod 不是容器,而是容器的"包装"或"沙箱"。一个 Pod 中可以包含一个或多个容器,这些容器共享同一组资源。你可以将 Pod 理解为一个逻辑主机,里面运行着一个或多个紧密协作的应用进程。
关键区别:Docker 管理的是单个容器,而 Kubernetes 管理的是 Pod。容器只是 Pod 中的一个组成部分。
1.3 每个 Pod 拥有唯一 IP
每个 Pod 在创建时都会被分配一个独立的 IP 地址(Pod IP),Pod 内的所有容器共享这个 IP。这意味着:
- 同一 Pod 内的容器可以通过
localhost互相访问 - 不同 Pod 之间的通信通过 Pod IP 进行,无需 NAT
- Pod 被删除重建后,IP 地址会发生变化
1.4 Pod 的临时性
Pod 是**临时性(Ephemeral)**的。当一个 Pod 被删除、所在的 Node 故障、或资源不足被驱逐时,它不会自动恢复。Kubernetes 通过更高层级的控制器(如 Deployment、StatefulSet)来确保期望的 Pod 副本数量,而不是去"修复"某个已经死掉的 Pod。
核心认知:不要把 Pod 当作持久化的实体。Pod 随时可能被重建,有状态的数据应当通过 PersistentVolume 等机制持久化到外部存储。
二、为什么需要 Pod
2.1 单容器的局限性
容器技术本身是隔离进程的优秀方案,但现实中的应用往往不是"一个容器能搞定"的。比如:
- 一个 Web 应用需要日志采集 agent 伴生运行
- 一个应用需要通过代理容器访问外部服务
- 一个应用需要在启动前完成配置文件的注入
这些场景下,多个容器需要紧密协作、同生共死,单独管理每个容器会带来极大的运维复杂度。
2.2 容器的协同调度需求
如果这些协作容器分别调度到不同的 Node 上,就会面临:
- 网络通信延迟增大
- 无法通过
localhost直接通信 - 生命周期难以同步(一个挂了另一个还在跑)
- 存储共享困难
Pod 的出现正是为了解决容器的协同调度问题——它将必须在一起的容器"捆绑"到一个调度单元中。
2.3 Pod 提供的共享上下文
Pod 为其内部的容器提供三个关键维度的共享上下文:
| 共享维度 | 说明 |
|---|---|
| Network Namespace | 所有容器共享同一个 IP 和端口空间,通过 localhost 互通 |
| Storage(Volume) | 可以挂载共享存储卷,实现容器间的文件共享 |
| IPC | 容器间可以通过进程间通信机制(如 System V 信号量、POSIX 共享内存)互相通信 |
网络共享示例:Pod 内的 Web 容器监听 8080 端口,日志采集 Sidecar 容器通过
localhost:8080就能访问到 Web 容器的 metrics 接口。
2.4 与 Docker Compose 的对比
Docker Compose 和 Pod 都是为了解决多容器协作的问题,但定位不同:
| 对比维度 | Docker Compose | Kubernetes Pod |
|---|---|---|
| 调度粒度 | 在同一主机上编排多个服务容器 | 将必须共存的容器绑定为原子调度单元 |
| 网络模型 | 每个容器独立 IP,通过 Docker 网络互联 | Pod 内容器共享 IP 和端口空间 |
| 生命周期 | 服务级管理,容器可独立启停 | Pod 内容器同生共死,整体调度 |
| 适用场景 | 单机开发与测试环境 | 分布式集群环境 |
核心洞察:Docker Compose 在服务级别编排容器,而 Pod 将必须共存、必须同调度的容器绑定在一起,确保它们永远运行在同一个 Node 上、共享同一个网络和存储。
三、Pod 的结构
3.1 单容器 Pod
这是最常见的 Pod 形式——一个 Pod 中只运行一个业务容器。大多数无状态的 Web 服务、API 服务都采用这种模式。
apiVersion: v1
kind: Pod
metadata:
name: single-container-pod
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
在这种模式下,Pod 就是容器的简单包装,调度和管理的最小单位从容器"升级"为 Pod,为后续的标签选择、服务发现等机制提供了一致的抽象。
3.2 多容器 Pod(Sidecar 模式)
多容器 Pod 中,通常有一个主容器(Main Container)负责核心业务逻辑,其余容器作为Sidecar辅助主容器完成工作。常见的 Sidecar 模式包括:
日志采集 Sidecar
主容器将日志写入共享 Volume,Sidecar 容器从 Volume 中读取日志并推送到日志中心。
apiVersion: v1
kind: Pod
metadata:
name: log-sidecar-pod
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: log-volume
mountPath: /var/log/app
- name: log-collector
image: fluent/fluentd:latest
volumeMounts:
- name: log-volume
mountPath: /var/log/app
readOnly: true
volumes:
- name: log-volume
emptyDir: {}
代理 / 适配器 Sidecar
Sidecar 容器充当网络代理或协议适配器,帮助主容器与外部系统通信。例如 Envoy Sidecar 作为服务网格的数据面代理。
配置注入 Sidecar
Sidecar 容器在主容器启动前,从配置中心拉取配置文件写入共享 Volume,主容器启动后直接读取。
3.3 Pause 容器(Infrastructure Container)
当你创建一个 Pod 时,k8s 会首先启动一个特殊的容器——Pause 容器,也叫基础容器(Infrastructure Container)或沙箱容器(Sandbox Container)。
Pause 容器的职责:
| 职责 | 说明 |
|---|---|
| 持有 Network Namespace | Pause 容器创建并持有 Pod 的 Network Namespace,Pod 内所有业务容器都加入这个 Namespace,从而共享网络 |
| 僵尸进程回收 | Pause 容器作为 PID 1 进程,负责回收孤儿进程和僵尸进程,避免容器内僵尸进程堆积 |
| Pod 生命周期锚点 | Pause 容器最先创建、最后销毁,它的存在确保了 Pod 的网络和 IPC 资源在所有业务容器消亡后仍能正确清理 |
Pause 容器的镜像为 registry.k8s.io/pause(国内常用 pause:3.x),非常轻量,只做一件事——等待(pause)。它的代码极其简单,本质上就是一个 sigsuspend 的死循环。
重要:Pause 容器对用户是不可见的(
kubectl get pod不会显示它),但你可以通过docker ps或crictl ps在 Node 上看到它。Pause 容器的存在是 Pod 网络共享模型的基石。
3.4 单容器 vs 多容器 Pod 对比
| 维度 | 单容器 Pod | 多容器 Pod |
|---|---|---|
| 容器数量 | 1 个业务容器 | 1 个主容器 + N 个 Sidecar |
| 复杂度 | 低,易于理解和调试 | 高,需要协调容器间依赖关系 |
| 典型场景 | 无状态 Web 服务、API 服务 | 日志采集、服务网格代理、配置注入 |
| 资源开销 | 仅业务容器 | 额外的 Sidecar 资源消耗 |
| 使用频率 | 最常见 | 特定场景使用 |
| 网络模型 | Pod IP 即容器 IP | 所有容器共享 Pod IP |
最佳实践:不要把无关的容器强行塞进同一个 Pod。只有那些必须共存、必须同时调度的容器才应该放在同一个 Pod 中。
四、Pod 生命周期
Phase 状态流转
Pod 的生命周期由一组 Phase 来描述,Phase 是 Pod 在其生命周期中所处阶段的高级抽象。
| Phase | 说明 |
|---|---|
| Pending | Pod 已被 k8s 系统接受,但尚未创建并运行容器。可能正在调度、正在拉取镜像 |
| Running | Pod 已被调度到 Node,且至少有一个容器仍在运行或正在启动 |
| Succeeded | Pod 中所有容器都已成功终止(exit code 0),且不会重启。常见于一次性任务 |
| Failed | Pod 中至少有一个容器以非零退出码终止,或者被系统终止 |
| Unknown | 无法获取 Pod 状态,通常是因为与所在 Node 的通信失败 |
状态流转如下:
Pending → Running → Succeeded
→ Failed
→ Failed
→ Unknown(Node 失联时)
注意:Phase 是一个粗粒度的状态,它并不反映单个容器的状态。一个 Running 状态的 Pod 中,可能存在已经 CrashLoopBackOff 的容器。关于重启策略和健康检查(探针)的详细内容,将在后续博文中专门讲解。
五、Pod 的声明式管理
5.1 资源清单(YAML)
Kubernetes 采用声明式管理模式,Pod 通过 YAML 资源清单来定义期望状态。关于资源清单的详细说明,可以参考 Kubernetes 资源清单 一文。
完整 Pod YAML 示例
下面是一个包含资源限制的完整 Pod 定义:
apiVersion: v1
kind: Pod
metadata:
name: webapp-pod
namespace: default
labels:
app: webapp
tier: frontend
spec:
containers:
- name: webapp
image: nginx:1.25
ports:
- containerPort: 80
protocol: TCP
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: nginx-config
常用 kubectl 命令
# 查看 Pod 列表
kubectl get pods
# 查看所有命名空间的 Pod
kubectl get pods -A
# 查看 Pod 详细信息(包括事件)
kubectl describe pod <pod-name>
# 查看 Pod 的宽格式输出(含 IP、所在 Node)
kubectl get pod <pod-name> -o wide
# 查看 Pod 日志
kubectl logs <pod-name>
# 多容器 Pod 中查看指定容器日志
kubectl logs <pod-name> -c <container-name>
# 实时跟踪日志
kubectl logs <pod-name> -f
# 进入 Pod 内的容器
kubectl exec -it <pod-name> -- /bin/bash
# 多容器 Pod 中进入指定容器
kubectl exec -it <pod-name> -c <container-name> -- /bin/bash
# 通过 YAML 创建 Pod
kubectl apply -f pod.yaml
# 删除 Pod
kubectl delete pod <pod-name>
# 通过 YAML 删除
kubectl delete -f pod.yaml
# 查看 Pod 标签
kubectl get pods --show-labels
# 通过标签筛选 Pod
kubectl get pods -l app=webapp
小结
| 核心概念 | 要点 |
|---|---|
| Pod 定义 | k8s 最小调度单元,不是容器,是容器的包装/沙箱 |
| Pod IP | 每个 Pod 拥有独立 IP,内部容器共享 |
| 临时性 | Pod 是临时的,随时可能被重建,状态应持久化到外部存储 |
| 共享上下文 | Network Namespace、Storage(Volume)、IPC |
| 单容器 Pod | 最常见形式,Pod 即容器的简单包装 |
| 多容器 Pod | Sidecar 模式,主容器 + 辅助容器紧密协作 |
| Pause 容器 | 持有 Network Namespace、回收僵尸进程、生命周期锚点 |
| Phase | Pending → Running → Succeeded / Failed / Unknown |
Pod 是 Kubernetes 一切的基石。无论是 Deployment 管理无状态服务、StatefulSet 管理有状态应用,还是 DaemonSet 确保每个 Node 运行一个副本,它们的底层调度单元都是 Pod。理解 Pod 的概念和结构,是深入学习 Kubernetes 的必经之路。
