容器暂停与恢复本质是调用Linux内核cgroups freezer子系统实现:pause将cgroup设为FROZEN,使进程进入D状态“定格”;unpause设为THAWED,毫秒级唤醒进程并保留全部上下文,不触发生命周期重启。

容器暂停与恢复不是 Docker 自己“写代码”去冻结进程,而是直接调用 Linux 内核的 cgroups freezer 子系统来实现的。
暂停本质是 cgroups freezer 控制组挂起
Docker pause 命令背后,实际是把容器所属的 cgroup(通常是 systemd 或 cgmanager 管理下的 freezer 控制组)状态设为 FROZEN。此时内核会:
- 遍历该 cgroup 下所有进程,向它们发送
freeze信号(非标准信号,由内核内部处理) - 让所有进程进入不可中断的
UNINTERRUPTIBLE(D 状态),停止调度执行 - 不释放内存、不关闭文件描述符、不销毁命名空间——只是“定格”整个进程树
- 网络连接保持 ESTABLISHED 状态,TCP 连接不会断开(但数据无法收发)
恢复就是解冻 cgroup,不重启也不重载
docker unpause 并不重新拉起进程或加载镜像,它只是把对应 freezer cgroup 的状态从 FROZEN 改回 THAWED:
- 内核唤醒所有被冻结进程,恢复其调度资格
- PID 1 进程继续从上次被挂起的指令处执行(比如一个正在 sleep 的 nginx master 进程)
- 所有打开的文件、socket、共享内存、信号队列等上下文完整保留
- 整个过程毫秒级完成,无启动开销,也无需重新初始化容器环境
和 stop 的根本区别在于是否触发生命周期终止
docker stop 是向 PID 1 发送 SIGTERM,走的是标准进程退出流程;而 pause/unpause 完全绕过信号机制和进程生命周期管理:
- stop 后容器状态变为
exited,docker start需要重新 fork 新进程、重挂载、重建网络栈 - pause 后状态是
paused,docker unpause不触发任何容器重启逻辑,也不影响 restart 策略判断 - 即使配置了
--restart=always,pause/unpause 也不会被识别为“故障”,不会触发自动重启
实际限制与注意事项
这种内核级冻结虽轻量,但有明确约束:
- 仅对支持 freezer 的 cgroup v1 或 v2 启用(现代主流发行版默认支持)
- 若容器内进程处于不可中断的内核态(如等待磁盘 I/O),可能无法立即 freeze,导致 pause 命令卡住
- 某些特权操作(如直接写 /dev/mem、使用 real-time 调度策略)可能绕过 freezer 控制
- 暂停期间,容器仍占用内存和部分内核资源,只是不消耗 CPU 时间片


















