Docker容器Paused与Unpause状态切换实战

4次阅读

容器Paused时进程被cgroup freezer冻结,CPU停止、TCP连接保持但无法收发数据,内存网络等资源保留;Unpause可恢复运行,不丢失状态。

Docker容器Paused与Unpause状态切换实战

容器处于Paused状态时,所有进程会被冻结(通过cgroup freezer实现),但内存、网络、文件系统等资源仍被保留;Unpause则恢复运行。这不是重启,也不影响容器内应用的内存数据或TCP连接状态。

Paused状态的本质与限制

Pause操作会向容器内所有进程发送SIGSTOP信号,并利用linux cgroup的freezer子系统将其整体挂起。此时:

  • 进程不再占用CPU,也无法响应任何系统调用(如read/write/accept)
  • 已建立的TCP连接保持在ESTABLISHED状态,但无法收发新数据
  • 容器的PID Namespace和网络命名空间未被销毁,ip addr、netstat等命令在宿主机上仍可见对应信息
  • 不能执行docker exec -it,因为init进程已被冻结,无法启动新进程
  • 日志输出停止,但log driver缓存的内容不会丢失(如json-file模式下flush前的数据仍在缓冲区)

常用Pause/Unpause操作命令

基本语法简洁直接:

  • 暂停容器: docker pause <container_id_or_name>
  • 恢复容器: docker unpause <container_id_or_name>
  • 批量操作: 支持多个容器名,例如 docker pause app1 app2 nginx
  • 查看状态: docker ps -a –format “table {{.Names}}t{{.Status}}”,Paused容器状态显示为 Paused (5 seconds ago)

典型适用场景与注意事项

Pause/Unpause不是调试或备份手段,而是轻量级运行控制工具:

  • 临时隔离异常容器:当某容器CPU或IO突增但又不想kill时,可pause观察宿主机负载变化
  • 配合快照类操作:某些存储驱动(如btrfs/zfs)支持在pause状态下做原子快照,避免应用写入不一致
  • 蓝绿部署中间态:旧版本容器pause后,再启动新版本,减少服务中断窗口(需配合反向代理流量切换)
  • 注意不可逆风险:长时间pause可能触发客户端超时(如http Keep-Alive断连、数据库连接池失效),建议单次不超过数分钟
  • 不适用于windows容器:Docker for Windows不支持pause/unpause,该功能仅限Linux容器

验证Pause效果的小技巧

快速确认是否真正生效,无需进入容器:

  • 执行 docker top <container>,Paused容器返回空结果或报错“Cannot get process list”
  • 在宿主机运行 ps aux | grep <container_pid>,能看到进程状态列为T(stopped)
  • 对暴露端口的服务,用 curl -v http://localhost:port 会卡住或返回Connection refused(取决于监听程序是否已冻结在accept阶段)
  • 检查cgroup状态:cat /sys/fs/cgroup/freezer/docker/*/freezer.state,应显示FROZEN
text=ZqhQzanResources