深入理解 Kubernetes Pause 容器:Pod 的核心基石

深入理解 Kubernetes Pause 容器:Pod 的核心基石 🔍

在 Kubernetes 的世界里,每个 Pod 启动时都有一个"隐形守护者"------Pause 容器。它不执行业务逻辑,却是整个 Pod 的根基。本文将带你揭开这个神秘容器的面纱。


关注公众号「Linux 容器运维」,回复【对应关键词】(如 docker/k8s/linux/ 面试),即可获取完整版干货,复制到生产环境直接使用~ 更多内容已同步至【公众号官方合集】,点击公众号主页「合集」→「kubernetes」,即可查看全部最新内容,持续更新中~


一、Pause 容器是什么?

Pause 容器(也称为 Infrastructure Container 或 Sandbox 容器)是 Kubernetes Pod 中的第一个启动的容器 ,也是最后终止的容器 。它通常使用极简的镜像(如 registry.k8s.io/pause:3.9),大小仅约 700KB,其核心逻辑是执行一个无限休眠的进程。

在 Node 节点上,你可以看到大量与 Pod 一一对应的 Pause 容器:

bash 复制代码
# 查看所有 Pause 容器
docker ps | grep pause
# 或使用 crictl 查看 sandbox 容器
crictl pods

关键特性:

  • 对用户完全透明,无法直接操作
  • 生命周期与 Pod 完全绑定
  • 作为 Pod 内所有其他容器的"父进程"

二、为什么需要 Pause 容器?

1. 网络命名空间的稳定持有者 📡

想象这样一个场景:一个 Pod 包含 Nginx 和日志收集容器。如果没有 Pause 容器,Nginx 容器需要作为网络命名空间的 Owner。一旦 Nginx 重启或崩溃,整个 Pod 的网络栈就会瞬间失效,其他容器也会失去网络连接。

Pause 容器的解决方案:

  • 首先创建网络命名空间
  • 所有业务容器通过 Join Namespace 方式加入
  • Pause 容器只做一件事:保持存活,确保网络命名空间持续存在

同一 Pod 内的容器看到的网络视图完全一致:相同的网络设备、IP 地址、MAC 地址。这就是为什么它们可以通过 localhost 直接通信。

2. PID 命名空间与僵尸进程回收 🧟

当 Pod 启用 shareProcessNamespace: true 时,Pause 容器作为 PID 1 进程(类似 Linux 的 init 进程),承担重要的系统职责:

  • 进程收养:当业务容器的父进程先于子进程退出时,子进程成为"孤儿",Pause 容器负责收养
  • 僵尸进程回收 :通过处理 SIGCHLD 信号,调用 waitpid() 回收已终止子进程的资源,防止内存泄漏

3. 其他命名空间共享

命名空间 作用
Network 共享 IP、端口空间、网络设备
IPC 支持 System V IPC 和 POSIX 消息队列跨容器通信
UTS 共享主机名和域名
Volume 共享 Pod 级别定义的存储卷挂载点

三、Pause 容器的工作原理

启动流程

css 复制代码
Kubelet 收到创建 Pod 指令
    ↓
创建 Pause 容器(初始化网络命名空间)
    ↓
CNI 插件为 Pause 容器分配 IP、配置网络
    ↓
业务容器 A 加入 Pause 的网络命名空间
    ↓
业务容器 B 加入 Pause 的网络命名空间
    ↓
Pod 进入 Running 状态

源码揭秘 📝

Pause 容器的实现极其精简,核心代码仅几十行:

c 复制代码
#include <signal.h>
#include <unistd.h>

// 处理终止信号
static void sigdown(int signo) {
    exit(0);
}

// 回收僵尸进程
static void sigreap(int signo) {
    while (waitpid(-1, NULL, WNOHANG) > 0);
}

int main(int argc, char **argv) {
    // 注册信号处理器
    sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL);
    sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap}, NULL);
    
    // 主循环:无限休眠,等待信号
    for (;;) {
        pause();
    }
    return 42;
}

核心逻辑:

  • pause() 系统调用使进程进入休眠状态
  • 收到 SIGTERM 时优雅退出
  • 收到 SIGCHLD 时回收僵尸进程

四、实战观察

查看 Pod 中的 Pause 容器 🔍

bash 复制代码
# 1. 查看 Pod 的 sandbox ID
crictl pods | grep <pod-name>

# 2. 查看该 Pod 的所有容器
crictl ps | grep <sandbox-id>

# 3. 在宿主机查看进程树
pstree -p | grep pause

输出示例:

bash 复制代码
[root@master01 ~]# pstree -p|grep pause
           |                       |-pause(1884)
           |                       |-pause(1892)
           |-containerd-shim(1803)-+-pause(1900)
           |                       |-pause(3287)
           |                       |-pause(3666)

验证网络共享 ✅

bash 复制代码
# 进入 Pod 中的任意容器
kubectl exec -it <pod-name> -c <container> -- /bin/sh

# 查看网络设备
ip addr
# 所有容器显示相同的 eth0 和 IP 地址

# 通过 localhost 访问同 Pod 其他容器的端口
curl localhost:<port>

五、常见误区与思考

Q1: 没有 Pause 容器行不行?

技术上可以通过挂载 /proc/<pid>/ns/net 到文件系统来持久化网络命名空间引用,但 Kubernetes 选择 Pause 容器是因为:

  1. 简化生命周期管理:进程存活即命名空间存活,逻辑清晰
  2. 标准化:与 CRI(容器运行时接口)规范深度耦合
  3. 额外收益:顺便解决了僵尸进程回收问题

Q2: Pause 容器占用资源多吗?

极少。Pause 容器:

  • 镜像大小:约 700KB
  • 内存占用:仅几 MB
  • CPU 使用:几乎为 0(仅休眠等待信号)

Q3: 为什么有时看不到 Pause 进程?

默认情况下,Pod 未启用 shareProcessNamespace,容器间 PID 命名空间隔离。需要在宿主机上通过 pstreeps 查看。

六、总结

Pause 容器是 Kubernetes Pod 架构的精妙设计,它用最小的代价解决了最复杂的问题:

价值点 说明
网络稳定性 作为网络命名空间的持久持有者
生命周期管理 Pod 生命周期与 Pause 容器绑定
进程治理 充当 init 进程,回收僵尸进程
资源隔离 提供统一的命名空间共享基础

理解 Pause 容器,就是理解 Pod 的本质------一组共享资源的容器集合。下次当你看到那些"默默无闻"的 Pause 容器时,请记住:它们是 Kubernetes 多容器编排的幕后英雄。


参考阅读:

  • Kubernetes 控制平面组件:Kubelet 详解
  • 理解 Pause 容器 - 腾讯云技术博客
  • 从 Pause 容器理解 Pod 的本质 - 图解 K8S
  • Kubernetes Pod 网络精髓:pause 容器详解 - 掘金

如果这篇文章对你有帮助,欢迎点赞、在看、转发三连!关于 Kubernetes 的更多深度解析,欢迎关注我们的技术专栏。

相关推荐
KubeSphere 云原生2 小时前
云原生周刊:Kubernetes 1.36 要来了
云原生·容器·kubernetes
Q16849645152 小时前
k8s-通过ansible-playbook脚本将其他节点加入集群失败?
容器·kubernetes·ansible
糟糕喔3 小时前
k8s运维-亲和(5)
运维·容器·kubernetes
高旭博3 小时前
对openfuyao-bkeadm的内容分析
kubernetes
海鸥813 小时前
k8s中实现进程环境的自动更新
云原生·容器·kubernetes
程序员爱酸奶4 小时前
Git + 云原生:构建坚如磐石的 Kubernetes 配置版本管理
git·云原生·kubernetes
@土豆7 小时前
K8s 单机二进制部署步骤(复制粘贴即可)
云原生·容器·kubernetes
丈剑走天涯18 小时前
kubernetes java app 部署使用harbor私服 问题集合
java·容器·kubernetes
Jinkxs20 小时前
Java 部署:滚动更新(K8s RollingUpdate 策略)
java·开发语言·kubernetes