讲解
容器的状态机很简单:created(已创建未启动)→ running(运行中)→ paused(暂停)→ exited(已退出),外加 restarting(重启策略触发中)。对应命令:docker start 启动已存在的容器、docker stop 优雅停止(先发 SIGTERM,默认 10 秒宽限后 SIGKILL,可用 -t 调整)、docker kill 直接强杀、docker restart 重启、docker pause/unpause 冻结与恢复(用 cgroup freezer,进程不收到任何信号)、docker rm 删除(运行中的容器要先停,或 rm -f)。
docker ps 只看运行中的容器,docker ps -a 才看全部——「容器去哪儿了」的困惑十有八九是忘了 -a。列表里的 STATUS 列(Up 5 minutes、Exited (0) 3 minutes ago)是排查的第一手信息:退出码 0 是正常结束,非 0 是异常,137 = 被 SIGKILL(常见于内存超限被 OOM Killer 杀掉),143 = 被 SIGTERM 优雅终止。
重启策略 --restart 有四个取值:no(默认)、on-failure(仅异常退出时重启,可配 :次数)、always(无论退出原因,且守护进程启动时也拉起)、unless-stopped(类似 always,但手动 stop 过的不会在守护进程重启后拉起)。生产服务常用 unless-stopped——它尊重运维的手动停止意图。
示例
创建一个常驻容器并观察状态流转:
docker run -d --name ohmydocs-verify-life alpine:3.21 sleep 300
docker ps --filter name=ohmydocs-verify-life --format '{{.Names}}: {{.Status}}'
暂停与恢复——paused 状态下进程被冻结:
docker pause ohmydocs-verify-life
docker ps --filter name=ohmydocs-verify-life --format '{{.Names}}: {{.Status}}'
docker unpause ohmydocs-verify-life
docker ps --filter name=ohmydocs-verify-life --format '{{.Names}}: {{.Status}}'
停止后容器还在(Exited 状态),ps -a 才能看到;start 可以原地拉起:
docker stop ohmydocs-verify-life
docker ps -a --filter name=ohmydocs-verify-life --format '{{.Names}}: {{.Status}}'
docker start ohmydocs-verify-life
docker ps --filter name=ohmydocs-verify-life --format '{{.Names}}: {{.Status}}'
清理:停止并删除(-f 强制,运行中也能删):
docker rm -f ohmydocs-verify-life
常见坑
- stop 要等 10 秒:应用不响应 SIGTERM(没写信号处理)就会吃满宽限期再被 SIGKILL;Go/Node 应用应监听 SIGTERM 做优雅退出。
- rm 报容器在运行:先 stop 再 rm,或确认后用 rm -f——但注意 -f 是 SIGKILL,数据可能丢。
- 重启策略选了 always 又手动停不掉:always 下 stop 后守护进程重启会拉起它;想保留手动停止语义用 unless-stopped。
- 退出码看不懂:137 优先查内存限制与 OOM,1 是应用自身报错(看 logs),126/127 是命令不可执行/不存在(检查 ENTRYPOINT)。
小结
状态机 created→running→exited,ps -a 看全量;stop 优雅、kill 强杀、rm 清理;退出码 137/143/1 各有含义;重启策略推荐 unless-stopped。下一章学会「进入」运行中的容器。