Pause 容器
Kubernetes Pause 容器的用途
Pause 容器是 Kubernetes 中一个非常小但极其重要的基础设施容器。很多人会忽略它,但它是 Pod 网络和命名空间共享的核心。
🎯 核心作用
1. 作为 Pod 的"根容器"(Infrastructure Container)
Pause 容器是每个 Pod 中第一个启动的容器,它的生命周期代表整个 Pod 的生命周期。
Pod 生命周期:
创建 Pod → 启动 Pause 容器 → 启动业务容器 → ... → 业务容器结束 → 删除 Pause 容器 → Pod 销毁2. 持有和共享 Linux 命名空间
Pause 容器创建并持有以下命名空间,供 Pod 内其他容器共享:
- Network Namespace (网络命名空间) - 最重要!
- IPC Namespace (进程间通信)
- UTS Namespace (主机名)
# 查看 Pod 中的容器
docker ps | grep pause
# 你会看到类似输出:
# k8s_POD_mypod_default_xxx k8s.gcr.io/pause:3.9
# k8s_app_mypod_default_xxx myapp:latest🌐 网络命名空间共享(最关键的用途)
工作原理
┌─────────────────── Pod ───────────────────┐
│ │
│ ┌─────────────┐ │
│ │ Pause │ ← 创建网络命名空间 │
│ │ Container │ ← 拥有 Pod IP │
│ └──────┬──────┘ │
│ │ (共享网络栈) │
│ ┌──────┴──────┬──────────┬──────────┐ │
│ │ Container A │Container B│Container C│ │
│ │ (业务容器) │ (业务容器)│ (业务容器) │ │
│ └─────────────┴──────────┴──────────┘ │
│ │
│ 所有容器共享: │
│ - 同一个 IP 地址 (Pod IP) │
│ - 同一个网络接口 │
│ - 同一个端口空间 │
│ - 可以通过 localhost 互相访问 │
└────────────────────────────────────────────┘实际效果
# 示例 Pod
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- name: sidecar
image: busybox
command: ['sh', '-c', 'while true; do wget -O- localhost:80; sleep 5; done']在这个例子中:
- Pause 容器创建网络命名空间并获得 Pod IP (如 10.244.1.5)
- nginx 容器加入这个网络命名空间,监听 80 端口
- sidecar 容器也加入同一网络命名空间
- sidecar 可以通过
localhost:80访问 nginx,因为它们共享网络栈
🔍 为什么需要 Pause 容器?
问题场景:如果没有 Pause 容器
假设 Pod 中有两个容器 A 和 B:
场景 1:容器 A 先启动,创建网络命名空间
├─ 容器 A 持有网络命名空间 → 拥有 Pod IP
└─ 容器 B 加入容器 A 的网络命名空间
问题:如果容器 A 崩溃重启或被删除,网络命名空间消失
→ 容器 B 失去网络连接
→ Pod IP 改变
→ Service 路由失效 ❌解决方案:引入 Pause 容器
Pause 容器(持有命名空间) ← 永远不会主动退出
├─ 容器 A 加入
└─ 容器 B 加入
优势:
✅ 容器 A 或 B 崩溃不影响网络命名空间
✅ Pod IP 始终保持稳定
✅ 业务容器可以独立重启
✅ 简化容器间的依赖关系📦 Pause 容器的特点
1. 极其精简
# pause 容器的代码只有几十行 C 代码
// 核心功能就是:永远 sleep
int main() {
for (;;) pause(); // 无限暂停,等待信号
return 0;
}镜像大小:约 700KB (相比普通镜像动辄几百 MB)
2. 资源占用极低
# 查看 Pause 容器资源占用
docker stats <pause-container-id>
# 典型输出:
# CPU: 0.00%
# MEM: 0.5 MiB3. 生命周期管理
- Kubelet 创建 Pod 时首先启动 Pause 容器
- Pause 容器退出 = Pod 销毁
- 业务容器重启不影响 Pause 容器
🛠️ 实际用途场景
场景 1:Sidecar 模式
# 应用 + 日志收集器
spec:
containers:
- name: app
image: myapp
volumeMounts:
- name: logs
mountPath: /var/log
- name: log-collector
image: fluentd
volumeMounts:
- name: logs
mountPath: /var/log- Pause 容器保证两个容器可以通过共享卷和 localhost 通信
- 即使 app 重启,log-collector 仍能正常工作
场景 2:Service Mesh (如 Istio)
# 应用 + Envoy 代理
spec:
containers:
- name: app
image: myapp
ports:
- containerPort: 8080
- name: istio-proxy # Envoy sidecar
image: istio/proxyv2- Pause 容器持有网络命名空间
- Envoy 代理拦截所有进出流量
- 应用无需感知代理存在
场景 3:初始化和主容器协作
spec:
initContainers:
- name: init-config
image: busybox
command: ['sh', '-c', 'echo "config" > /config/app.conf']
volumeMounts:
- name: config
mountPath: /config
containers:
- name: app
image: myapp
volumeMounts:
- name: config
mountPath: /config- Pause 容器在整个过程中保持网络和 IPC 命名空间稳定
🔧 查看和调试 Pause 容器
查看 Pod 中的 Pause 容器
# 方式 1:通过 crictl (推荐)
crictl pods
crictl ps -a | grep pause
# 方式 2:通过 docker (如果使用 Docker 运行时)
docker ps -a | grep pause
docker inspect <pause-container-id>
# 方式 3:查看 Pod 的容器列表
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].name}'Pause 镜像版本
# 查看 kubelet 使用的 pause 镜像
kubectl get pod <pod-name> -o yaml | grep pause
# 常见版本:
# registry.k8s.io/pause:3.9 (最新)
# registry.k8s.io/pause:3.8
# k8s.gcr.io/pause:3.7⚠️ 常见问题
Q1: 为什么看不到 Pause 容器?
A: 使用 kubectl get pods 不会显示 Pause 容器,它对用户是透明的。需要使用底层运行时命令(如 crictl 或 docker ps)才能看到。
Q2: Pause 容器会影响性能吗?
A: 几乎不会。Pause 容器只占用约 0.5MB 内存,CPU 使用为 0,不执行任何业务逻辑。
Q3: 可以删除 Pause 容器吗?
A: 不能手动删除。删除 Pause 容器会导致整个 Pod 被销毁。
Q4: 不同 Pod 的 Pause 容器是否共享?
A: 不共享。每个 Pod 都有独立的 Pause 容器,确保 Pod 之间的网络和命名空间隔离。
📝 总结
| 用途 | 说明 |
|---|---|
| 命名空间持有者 | 创建并持有 Network、IPC、UTS 命名空间 |
| 网络基础 | 使 Pod 内所有容器共享同一 IP 和网络栈 |
| 生命周期锚点 | 代表 Pod 的生命周期,容器可独立重启 |
| 简化架构 | 解耦容器间依赖,避免级联故障 |
| 资源高效 | 极小的镜像和资源占用 |
核心价值: Pause 容器是 Kubernetes Pod 抽象的基石,让多个容器能像在同一主机上一样协作,同时保持各自的独立性和可重启性。
需要我详细讲解某个具体场景或深入探讨实现原理吗? 🚀