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 MiB

3. 生命周期管理

  • 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 容器,它对用户是透明的。需要使用底层运行时命令(如 crictldocker 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 抽象的基石,让多个容器能像在同一主机上一样协作,同时保持各自的独立性和可重启性。

需要我详细讲解某个具体场景或深入探讨实现原理吗? 🚀