mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-09 16:39:31 +00:00
302 lines
7.0 KiB
Go
302 lines
7.0 KiB
Go
## 终止容器
|
||
|
||
本节将介绍如何终止一个运行中的容器,以及几种不同的终止方式及其区别。
|
||
|
||
### 终止方式概述
|
||
|
||
终止容器有三种方式:
|
||
|
||
| 方式 | 命令 | 说明 |
|
||
|------|------|------|
|
||
| **优雅停止** | `docker stop` | 先发 SIGTERM,超时后发 SIGKILL |
|
||
| **强制停止** | `docker kill` | 直接发 SIGKILL |
|
||
| **自动终止** | - | 容器主进程退出时自动停止 |
|
||
|
||
---
|
||
|
||
### docker stop(推荐)
|
||
|
||
#### 基本用法
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ docker stop 容器名或ID
|
||
```
|
||
|
||
#### 工作原理
|
||
|
||
具体内容如下:
|
||
|
||
```
|
||
docker stop mycontainer
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 1. 发送 SIGTERM 信号给容器主进程(PID 1) │
|
||
│ ↓ │
|
||
│ 2. 等待容器优雅退出(默认 10 秒) │
|
||
│ ↓ │
|
||
│ 3. 如果超时仍未退出,发送 SIGKILL 强制终止 │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
#### 自定义超时时间
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
## 等待 30 秒后强制终止
|
||
|
||
$ docker stop -t 30 mycontainer
|
||
|
||
## 立即发送 SIGKILL(相当于 docker kill)
|
||
|
||
$ docker stop -t 0 mycontainer
|
||
```
|
||
|
||
#### 停止多个容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
## 停止多个指定容器
|
||
|
||
$ docker stop container1 container2 container3
|
||
|
||
## 停止所有运行中的容器
|
||
|
||
$ docker stop $(docker ps -q)
|
||
```
|
||
|
||
---
|
||
|
||
### docker kill
|
||
|
||
#### 基本用法
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ docker kill 容器名或ID
|
||
```
|
||
|
||
#### 与 stop 的区别
|
||
|
||
| 命令 | 信号 | 使用场景 |
|
||
|------|------|---------|
|
||
| `docker stop` | SIGTERM → SIGKILL | 正常停止,让应用优雅退出 |
|
||
| `docker kill` | SIGKILL | 应用无响应,强制终止 |
|
||
|
||
#### 发送自定义信号
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
## 发送 SIGHUP(让进程重新加载配置)
|
||
|
||
$ docker kill -s HUP mycontainer
|
||
|
||
## 发送 SIGTERM
|
||
|
||
$ docker kill -s TERM mycontainer
|
||
```
|
||
|
||
---
|
||
|
||
### 容器自动终止
|
||
|
||
容器的生命周期与主进程绑定。主进程退出时,容器自动停止:
|
||
|
||
```bash
|
||
## 主进程是交互式 bash
|
||
|
||
$ docker run -it ubuntu bash
|
||
root@abc123:/# exit # 退出 bash → 容器停止
|
||
|
||
## 主进程执行完毕
|
||
|
||
$ docker run ubuntu echo "Hello" # echo 执行完 → 容器停止
|
||
```
|
||
|
||
---
|
||
|
||
### 查看已停止的容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ 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) |
|
||
|
||
---
|
||
|
||
### 重新启动容器
|
||
|
||
#### 启动已停止的容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ docker start 容器名或ID
|
||
|
||
## 启动并附加终端
|
||
|
||
$ docker start -ai 容器名
|
||
```
|
||
|
||
#### 重启运行中的容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
## 先停止再启动
|
||
|
||
$ docker restart 容器名
|
||
|
||
## 自定义停止超时
|
||
|
||
$ docker restart -t 30 容器名
|
||
```
|
||
|
||
---
|
||
|
||
### 生命周期状态图
|
||
|
||
具体内容如下:
|
||
|
||
```
|
||
docker create
|
||
│
|
||
▼
|
||
┌──────────┐
|
||
┌────────│ Created │────────┐
|
||
│ └──────────┘ │
|
||
│ │ │
|
||
│ │ docker start│
|
||
│ ▼ │
|
||
│ ┌──────────┐ │
|
||
│ ┌────│ Running │────┐ │
|
||
│ │ └──────────┘ │ │
|
||
│ │ │ │ │
|
||
│ │ docker │ docker │ │
|
||
│ │ pause │ stop │ │
|
||
│ ▼ │ │ │
|
||
│ ┌──────┐ │ │ │
|
||
│ │Paused│ │ │ │
|
||
│ └──────┘ │ │ │
|
||
│ │ │ │ │
|
||
│ │ docker │ │ │
|
||
│ │ unpause │ │ │
|
||
│ ▼ ▼ │ │
|
||
│ └──────►┌──────────┐◄┘ │
|
||
│ │ Stopped │ │
|
||
│ └──────────┘ │
|
||
│ │ │
|
||
│ │ docker rm │
|
||
│ ▼ │
|
||
│ ┌──────────┐ │
|
||
└──────────►│ Deleted │◄────┘
|
||
└──────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 批量操作
|
||
|
||
#### 停止所有容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ docker stop $(docker ps -q)
|
||
```
|
||
|
||
#### 删除所有已停止的容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ docker container prune
|
||
```
|
||
|
||
#### 停止并删除所有容器
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
$ docker stop $(docker ps -q) && docker container prune -f
|
||
```
|
||
|
||
---
|
||
|
||
### 常见问题
|
||
|
||
#### Q: 容器停止很慢
|
||
|
||
原因:应用没有正确处理 SIGTERM 信号,需要等待超时后强制终止。
|
||
|
||
解决方案:
|
||
1. 在应用中正确处理 SIGTERM
|
||
2. 使用 `docker stop -t 0` 立即终止
|
||
3. 检查 Dockerfile 中的 `STOPSIGNAL` 配置
|
||
|
||
#### Q: 如何让容器优雅退出
|
||
|
||
确保容器主进程正确处理信号:
|
||
|
||
```dockerfile
|
||
## Dockerfile 示例
|
||
|
||
FROM node:22
|
||
...
|
||
## 使用 exec 形式确保信号能传递给 node 进程
|
||
|
||
CMD ["node", "server.js"]
|
||
```
|
||
|
||
#### Q: 容器无法停止
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
## 强制终止
|
||
|
||
$ docker kill 容器名
|
||
|
||
## 如果仍无法停止,检查系统资源
|
||
|
||
$ docker inspect 容器名
|
||
```
|
||
|
||
---
|
||
|
||
### 本章小结
|
||
|
||
| 操作 | 命令 | 说明 |
|
||
|------|------|------|
|
||
| 优雅停止 | `docker stop` | 先 SIGTERM,超时后 SIGKILL |
|
||
| 强制停止 | `docker kill` | 直接 SIGKILL |
|
||
| 重新启动 | `docker start` | 启动已停止的容器 |
|
||
| 重启 | `docker restart` | 停止后立即启动 |
|
||
| 停止全部 | `docker stop $(docker ps -q)` | 停止所有运行中容器 |
|
||
|
||
### 延伸阅读
|
||
|
||
- [启动容器](5.1_run.md):容器启动详解
|
||
- [删除容器](4.3_rm.md):清理容器
|
||
- [容器日志](logs.md):排查停止原因
|