Files
docker_practice/05_container/stop.md

6.5 KiB
Raw Blame History

终止容器

终止方式概述

终止容器有三种方式:

方式 命令 说明
优雅停止 docker stop 先发 SIGTERM超时后发 SIGKILL
强制停止 docker kill 直接发 SIGKILL
自动终止 - 容器主进程退出时自动停止

docker stop推荐

基本用法

$ docker stop 容器名或ID

工作原理

docker stop mycontainer
        │
        ▼
┌─────────────────────────────────────────────────────────────────┐
│  1. 发送 SIGTERM 信号给容器主进程PID 1                        │
│        ↓                                                        │
│  2. 等待容器优雅退出(默认 10 秒)                                │
│        ↓                                                        │
│  3. 如果超时仍未退出,发送 SIGKILL 强制终止                       │
└─────────────────────────────────────────────────────────────────┘

自定义超时时间

# 等待 30 秒后强制终止
$ docker stop -t 30 mycontainer

# 立即发送 SIGKILL相当于 docker kill
$ docker stop -t 0 mycontainer

停止多个容器

# 停止多个指定容器
$ docker stop container1 container2 container3

# 停止所有运行中的容器
$ docker stop $(docker ps -q)

docker kill

基本用法

$ docker kill 容器名或ID

与 stop 的区别

命令 信号 使用场景
docker stop SIGTERM → SIGKILL 正常停止,让应用优雅退出
docker kill SIGKILL 应用无响应,强制终止

发送自定义信号

# 发送 SIGHUP让进程重新加载配置
$ docker kill -s HUP mycontainer

# 发送 SIGTERM
$ docker kill -s TERM mycontainer

容器自动终止

容器的生命周期与主进程绑定。主进程退出时,容器自动停止:

# 主进程是交互式 bash
$ docker run -it ubuntu bash
root@abc123:/# exit    # 退出 bash → 容器停止

# 主进程执行完毕
$ docker run ubuntu echo "Hello"    # echo 执行完 → 容器停止

查看已停止的容器

$ docker ps -a
CONTAINER ID   IMAGE    COMMAND       STATUS                      NAMES
ba267838cc1b   ubuntu   "/bin/bash"   Exited (0) 2 minutes ago    myubuntu
c5d3a5e8f7b2   nginx    "nginx"       Up 5 minutes                mynginx

STATUS 字段说明

状态 说明
Up X minutes 运行中
Exited (0) 正常退出(退出码 0
Exited (1) 异常退出(非零退出码)
Exited (137) 被 SIGKILL 终止128 + 9
Exited (143) 被 SIGTERM 终止128 + 15

重新启动容器

启动已停止的容器

$ docker start 容器名或ID

# 启动并附加终端
$ docker start -ai 容器名

重启运行中的容器

# 先停止再启动
$ docker restart 容器名

# 自定义停止超时
$ docker restart -t 30 容器名

生命周期状态图

                    docker create
                         │
                         ▼
                   ┌──────────┐
         ┌────────│ Created  │────────┐
         │        └──────────┘        │
         │              │             │
         │              │ docker start│
         │              ▼             │
         │        ┌──────────┐        │
         │   ┌────│ Running  │────┐   │
         │   │    └──────────┘    │   │
         │   │          │         │   │
         │   │ docker   │ docker  │   │
         │   │ pause    │ stop    │   │
         │   ▼          │         │   │
         │ ┌──────┐     │         │   │
         │ │Paused│     │         │   │
         │ └──────┘     │         │   │
         │   │          │         │   │
         │   │ docker   │         │   │
         │   │ unpause  │         │   │
         │   ▼          ▼         │   │
         │   └──────►┌──────────┐◄┘   │
         │           │ Stopped  │     │
         │           └──────────┘     │
         │                │           │
         │                │ docker rm │
         │                ▼           │
         │           ┌──────────┐     │
         └──────────►│ Deleted  │◄────┘
                     └──────────┘

批量操作

停止所有容器

$ docker stop $(docker ps -q)

删除所有已停止的容器

$ docker container prune

停止并删除所有容器

$ docker stop $(docker ps -q) && docker container prune -f

常见问题

Q: 容器停止很慢

原因:应用没有正确处理 SIGTERM 信号,需要等待超时后强制终止。

解决方案:

  1. 在应用中正确处理 SIGTERM
  2. 使用 docker stop -t 0 立即终止
  3. 检查 Dockerfile 中的 STOPSIGNAL 配置

Q: 如何让容器优雅退出

确保容器主进程正确处理信号:

# Dockerfile 示例
FROM node:22
...
# 使用 exec 形式确保信号能传递给 node 进程
CMD ["node", "server.js"]

Q: 容器无法停止

# 强制终止
$ docker kill 容器名

# 如果仍无法停止,检查系统资源
$ docker inspect 容器名

本章小结

操作 命令 说明
优雅停止 docker stop 先 SIGTERM超时后 SIGKILL
强制停止 docker kill 直接 SIGKILL
重新启动 docker start 启动已停止的容器
重启 docker restart 停止后立即启动
停止全部 docker stop $(docker ps -q) 停止所有运行中容器

延伸阅读