mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-11 12:21:17 +00:00
Use a better structure
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 启动容器
|
||||
## 启动容器
|
||||
|
||||
## 启动方式概述
|
||||
### 启动方式概述
|
||||
|
||||
启动容器有两种方式:
|
||||
- **新建并启动**:基于镜像创建新容器
|
||||
@@ -8,15 +8,15 @@
|
||||
|
||||
由于 Docker 容器非常轻量,实际使用中常常是随时删除和新建容器,而不是反复重启同一个容器。
|
||||
|
||||
## 新建并启动
|
||||
### 新建并启动
|
||||
|
||||
### 基本语法
|
||||
#### 基本语法
|
||||
|
||||
```bash
|
||||
docker run [选项] 镜像 [命令] [参数...]
|
||||
```
|
||||
|
||||
### 最简单的例子
|
||||
#### 最简单的例子
|
||||
|
||||
输出 "Hello World" 后容器自动终止:
|
||||
|
||||
@@ -27,7 +27,7 @@ Hello world
|
||||
|
||||
这与直接执行 `/bin/echo 'Hello world'` 几乎没有区别,但实际上已经启动了一个完整的 Ubuntu 容器来执行这条命令。
|
||||
|
||||
### 交互式容器
|
||||
#### 交互式容器
|
||||
|
||||
启动一个可以交互的 bash 终端:
|
||||
|
||||
@@ -54,7 +54,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr
|
||||
root@af8bae53bdd3:/# exit # 退出容器
|
||||
```
|
||||
|
||||
## docker run 的完整流程
|
||||
### docker run 的完整流程
|
||||
|
||||
执行 `docker run` 时,Docker 在后台完成以下操作:
|
||||
|
||||
@@ -84,9 +84,9 @@ root@af8bae53bdd3:/# exit # 退出容器
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 常用启动选项
|
||||
### 常用启动选项
|
||||
|
||||
### 基础选项
|
||||
#### 基础选项
|
||||
|
||||
| 选项 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
@@ -95,70 +95,70 @@ root@af8bae53bdd3:/# exit # 退出容器
|
||||
| `--name` | 指定容器名称 | `docker run --name myapp nginx` |
|
||||
| `--rm` | 退出后自动删除容器 | `docker run --rm ubuntu echo hi` |
|
||||
|
||||
### 端口映射
|
||||
#### 端口映射
|
||||
|
||||
```bash
|
||||
# 将容器的 80 端口映射到宿主机的 8080 端口
|
||||
## 将容器的 80 端口映射到宿主机的 8080 端口
|
||||
$ docker run -d -p 8080:80 nginx
|
||||
|
||||
# 随机映射端口
|
||||
## 随机映射端口
|
||||
$ docker run -d -P nginx
|
||||
|
||||
# 只绑定到 localhost
|
||||
## 只绑定到 localhost
|
||||
$ docker run -d -p 127.0.0.1:8080:80 nginx
|
||||
```
|
||||
|
||||
### 数据卷挂载
|
||||
#### 数据卷挂载
|
||||
|
||||
```bash
|
||||
# 挂载命名卷
|
||||
## 挂载命名卷
|
||||
$ docker run -v mydata:/data nginx
|
||||
|
||||
# 挂载宿主机目录
|
||||
## 挂载宿主机目录
|
||||
$ docker run -v /host/path:/container/path nginx
|
||||
|
||||
# 只读挂载
|
||||
## 只读挂载
|
||||
$ docker run -v /host/path:/container/path:ro nginx
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
#### 环境变量
|
||||
|
||||
```bash
|
||||
# 设置单个环境变量
|
||||
## 设置单个环境变量
|
||||
$ docker run -e MYSQL_ROOT_PASSWORD=secret mysql
|
||||
|
||||
# 从文件加载环境变量
|
||||
## 从文件加载环境变量
|
||||
$ docker run --env-file .env myapp
|
||||
```
|
||||
|
||||
### 资源限制
|
||||
#### 资源限制
|
||||
|
||||
```bash
|
||||
# 限制内存
|
||||
## 限制内存
|
||||
$ docker run -m 512m nginx
|
||||
|
||||
# 限制 CPU
|
||||
## 限制 CPU
|
||||
$ docker run --cpus=1.5 nginx
|
||||
```
|
||||
|
||||
## 启动已终止容器
|
||||
### 启动已终止容器
|
||||
|
||||
使用 `docker start` 重新启动已停止的容器:
|
||||
|
||||
```bash
|
||||
# 查看所有容器(包括已停止的)
|
||||
## 查看所有容器(包括已停止的)
|
||||
$ docker ps -a
|
||||
CONTAINER ID IMAGE STATUS NAMES
|
||||
af8bae53bdd3 ubuntu Exited (0) 2 minutes ago myubuntu
|
||||
|
||||
# 重新启动
|
||||
## 重新启动
|
||||
$ docker start myubuntu
|
||||
|
||||
# 启动并附加终端
|
||||
## 启动并附加终端
|
||||
$ docker start -ai myubuntu
|
||||
```
|
||||
|
||||
## 容器内进程的特点
|
||||
### 容器内进程的特点
|
||||
|
||||
容器内只运行指定的应用程序及其必需资源:
|
||||
|
||||
@@ -171,48 +171,48 @@ root@ba267838cc1b:/# ps
|
||||
|
||||
可见容器中仅运行了 `bash` 进程。这种特点使得 Docker 对资源的利用率极高。
|
||||
|
||||
> 💡 笔者提示:容器内的 PID 1 进程很重要——它是容器的主进程,该进程退出则容器停止。详见[后台运行](daemon.md)章节。
|
||||
> 💡 笔者提示:容器内的 PID 1 进程很重要——它是容器的主进程,该进程退出则容器停止。详见[后台运行](5.2_daemon.md)章节。
|
||||
|
||||
## 常见问题
|
||||
### 常见问题
|
||||
|
||||
### Q: 容器启动后立即退出
|
||||
#### Q: 容器启动后立即退出
|
||||
|
||||
**原因**:主进程执行完毕或无法保持运行
|
||||
|
||||
```bash
|
||||
# 这个容器会立即退出(echo 执行完就结束了)
|
||||
## 这个容器会立即退出(echo 执行完就结束了)
|
||||
$ docker run ubuntu echo "hello"
|
||||
|
||||
# 解决:使用能持续运行的命令
|
||||
## 解决:使用能持续运行的命令
|
||||
$ docker run -d nginx # nginx 是持续运行的服务
|
||||
```
|
||||
|
||||
详细解释见[后台运行](daemon.md)。
|
||||
详细解释见[后台运行](5.2_daemon.md)。
|
||||
|
||||
### Q: 无法连接容器内的服务
|
||||
#### Q: 无法连接容器内的服务
|
||||
|
||||
**原因**:未正确映射端口
|
||||
|
||||
```bash
|
||||
# 错误:没有 -p 参数,外部无法访问
|
||||
## 错误:没有 -p 参数,外部无法访问
|
||||
$ docker run -d nginx
|
||||
|
||||
# 正确:映射端口
|
||||
## 正确:映射端口
|
||||
$ docker run -d -p 80:80 nginx
|
||||
```
|
||||
|
||||
### Q: 容器内修改的文件丢失
|
||||
#### Q: 容器内修改的文件丢失
|
||||
|
||||
**原因**:未使用数据卷,数据保存在容器存储层
|
||||
|
||||
```bash
|
||||
# 使用数据卷持久化
|
||||
## 使用数据卷持久化
|
||||
$ docker run -v mydata:/app/data myapp
|
||||
```
|
||||
|
||||
详见[数据管理](../07_data_network/README.md)。
|
||||
|
||||
## 本章小结
|
||||
### 本章小结
|
||||
|
||||
| 操作 | 命令 | 说明 |
|
||||
|------|------|------|
|
||||
@@ -221,9 +221,9 @@ $ docker run -v mydata:/app/data myapp
|
||||
| 后台运行 | `docker run -d` | 用于服务类应用 |
|
||||
| 启动已停止的容器 | `docker start` | 重用已有容器 |
|
||||
|
||||
## 延伸阅读
|
||||
### 延伸阅读
|
||||
|
||||
- [后台运行](daemon.md):理解 `-d` 参数和容器生命周期
|
||||
- [进入容器](attach_exec.md):操作运行中的容器
|
||||
- [后台运行](5.2_daemon.md):理解 `-d` 参数和容器生命周期
|
||||
- [进入容器](5.4_attach_exec.md):操作运行中的容器
|
||||
- [网络配置](../network/README.md):理解端口映射的原理
|
||||
- [数据管理](../07_data_network/README.md):数据持久化方案
|
||||
@@ -1,8 +1,8 @@
|
||||
# 后台运行
|
||||
## 后台运行
|
||||
|
||||
在生产环境中,我们通常需要容器持续运行,不受终端关闭的影响。本节将深入讲解如何让容器在后台运行,以及理解容器生命周期的核心概念。
|
||||
|
||||
## 核心概念:前台 vs 后台
|
||||
### 核心概念:前台 vs 后台
|
||||
|
||||
当你在终端运行一个程序时,有两种模式:
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
Docker 容器默认是**前台运行**的。使用 `-d`(detach)参数可以让容器在后台运行。
|
||||
|
||||
## 基本使用
|
||||
### 基本使用
|
||||
|
||||
### 前台运行(默认)
|
||||
#### 前台运行(默认)
|
||||
|
||||
```bash
|
||||
$ docker run ubuntu:24.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
|
||||
@@ -28,7 +28,7 @@ hello world
|
||||
- 按 `Ctrl+C` 会终止容器
|
||||
- 关闭终端窗口,容器也会停止
|
||||
|
||||
### 后台运行(使用 -d 参数)
|
||||
#### 后台运行(使用 -d 参数)
|
||||
|
||||
```bash
|
||||
$ docker run -d ubuntu:24.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
|
||||
@@ -41,7 +41,7 @@ $ docker run -d ubuntu:24.04 /bin/sh -c "while true; do echo hello world; sleep
|
||||
- 终端立即释放,可以继续执行其他命令
|
||||
- 输出不会直接显示(需要用 `docker logs` 查看)
|
||||
|
||||
## 深入理解:容器为什么会"立即退出"?
|
||||
### 深入理解:容器为什么会"立即退出"?
|
||||
|
||||
> **这是初学者最常遇到的困惑。** 理解这个问题,你就理解了 Docker 的核心设计理念。
|
||||
|
||||
@@ -53,7 +53,7 @@ $ docker run -d ubuntu:24.04
|
||||
|
||||
然后用 `docker ps` 查看,发现容器根本不在运行!这是为什么?
|
||||
|
||||
### 核心原理:容器的生命周期与主进程绑定
|
||||
#### 核心原理:容器的生命周期与主进程绑定
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
@@ -75,7 +75,7 @@ $ docker run -d ubuntu:24.04
|
||||
- ❌ `-d` 参数**不是**让容器"一直运行"
|
||||
- ✅ `-d` 参数是让容器"在后台运行",能运行多久取决于主进程
|
||||
|
||||
### 常见的"立即退出"场景
|
||||
#### 常见的"立即退出"场景
|
||||
|
||||
| 场景 | 原因 | 解决方案 |
|
||||
|------|------|---------|
|
||||
@@ -83,9 +83,9 @@ $ docker run -d ubuntu:24.04
|
||||
| `docker run -d nginx` 后改了配置 | 配置错误导致 nginx 启动失败 | 查看 `docker logs` |
|
||||
| 自定义镜像容器启动即退 | Dockerfile 的 CMD 执行完毕 | 确保 CMD 是前台进程 |
|
||||
|
||||
## 查看后台容器
|
||||
### 查看后台容器
|
||||
|
||||
### 查看运行中的容器
|
||||
#### 查看运行中的容器
|
||||
|
||||
```bash
|
||||
$ docker container ls
|
||||
@@ -93,7 +93,7 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS PO
|
||||
77b2dc01fe0f ubuntu:24.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute agitated_wright
|
||||
```
|
||||
|
||||
### 查看容器输出日志
|
||||
#### 查看容器输出日志
|
||||
|
||||
```bash
|
||||
$ docker container logs 77b2dc01fe0f
|
||||
@@ -109,7 +109,7 @@ hello world
|
||||
$ docker container logs -f 77b2dc01fe0f
|
||||
```
|
||||
|
||||
### 查看已停止的容器
|
||||
#### 查看已停止的容器
|
||||
|
||||
```bash
|
||||
$ docker container ls -a
|
||||
@@ -117,59 +117,59 @@ $ docker container ls -a
|
||||
|
||||
加上 `-a` 参数可以看到所有容器,包括已停止的。这对于调试"容器启动即退出"的问题非常有用。
|
||||
|
||||
## 最佳实践
|
||||
### 最佳实践
|
||||
|
||||
### 1. 长期运行的服务使用 -d
|
||||
#### 1. 长期运行的服务使用 -d
|
||||
|
||||
```bash
|
||||
# Web 服务器
|
||||
## Web 服务器
|
||||
$ docker run -d -p 80:80 nginx
|
||||
|
||||
# 数据库
|
||||
## 数据库
|
||||
$ docker run -d -p 3306:3306 mysql:8
|
||||
|
||||
# 缓存服务
|
||||
## 缓存服务
|
||||
$ docker run -d -p 6379:6379 redis
|
||||
```
|
||||
|
||||
### 2. 调试时先用前台模式
|
||||
#### 2. 调试时先用前台模式
|
||||
|
||||
当容器启动有问题时,**去掉 `-d` 参数**可以直接看到输出和错误:
|
||||
|
||||
```bash
|
||||
# 有问题的容器,先前台运行看看发生了什么
|
||||
## 有问题的容器,先前台运行看看发生了什么
|
||||
$ docker run myimage:latest
|
||||
```
|
||||
|
||||
### 3. 使用 --rm 自动清理
|
||||
#### 3. 使用 --rm 自动清理
|
||||
|
||||
对于一次性任务,使用 `--rm` 参数让容器退出后自动删除:
|
||||
|
||||
```bash
|
||||
$ docker run --rm ubuntu:24.04 echo "Hello, World!"
|
||||
Hello, World!
|
||||
# 容器执行完后自动删除
|
||||
## 容器执行完后自动删除
|
||||
```
|
||||
|
||||
### 4. 配合日志查看
|
||||
#### 4. 配合日志查看
|
||||
|
||||
```bash
|
||||
# 后台启动
|
||||
## 后台启动
|
||||
$ docker run -d --name myapp myimage:latest
|
||||
|
||||
# 查看最近 100 行日志
|
||||
## 查看最近 100 行日志
|
||||
$ docker logs --tail 100 myapp
|
||||
|
||||
# 实时跟踪日志
|
||||
## 实时跟踪日志
|
||||
$ docker logs -f myapp
|
||||
|
||||
# 查看带时间戳的日志
|
||||
## 查看带时间戳的日志
|
||||
$ docker logs -t myapp
|
||||
```
|
||||
|
||||
## 常见问题排查
|
||||
### 常见问题排查
|
||||
|
||||
### Q: 容器启动后立即退出
|
||||
#### Q: 容器启动后立即退出
|
||||
|
||||
1. **查看退出状态码**:
|
||||
```bash
|
||||
@@ -188,7 +188,7 @@ $ docker logs -t myapp
|
||||
# 进入容器手动执行命令,查找问题
|
||||
```
|
||||
|
||||
### Q: 容器在后台运行但无法访问服务
|
||||
#### Q: 容器在后台运行但无法访问服务
|
||||
|
||||
1. **检查端口映射**:
|
||||
```bash
|
||||
@@ -200,7 +200,7 @@ $ docker logs -t myapp
|
||||
$ docker exec mycontainer ps aux
|
||||
```
|
||||
|
||||
### Q: 如何让已经在后台运行的容器回到前台?
|
||||
#### Q: 如何让已经在后台运行的容器回到前台?
|
||||
|
||||
使用 `docker attach`:
|
||||
|
||||
@@ -210,9 +210,9 @@ $ docker attach mycontainer
|
||||
|
||||
> **注意**:`attach` 会连接到容器的主进程。如果主进程不是交互式的,你可能只能看到输出。使用 `Ctrl+P` `Ctrl+Q` 可以安全退出而不停止容器。
|
||||
|
||||
## 延伸阅读
|
||||
### 延伸阅读
|
||||
|
||||
- [进入容器](attach_exec.md):如何进入正在运行的容器执行命令
|
||||
- [容器日志](../15_appendix/best_practices.md):生产环境的日志管理最佳实践
|
||||
- [进入容器](5.4_attach_exec.md):如何进入正在运行的容器执行命令
|
||||
- [容器日志](../15_appendix/15.1_best_practices.md):生产环境的日志管理最佳实践
|
||||
- [HEALTHCHECK 健康检查](../04_image/dockerfile/healthcheck.md):自动检测容器内服务是否正常
|
||||
- [Docker Compose](../compose/README.md):管理多个后台容器的更好方式
|
||||
@@ -1,6 +1,6 @@
|
||||
# 终止容器
|
||||
## 终止容器
|
||||
|
||||
## 终止方式概述
|
||||
### 终止方式概述
|
||||
|
||||
终止容器有三种方式:
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
|
||||
---
|
||||
|
||||
## docker stop(推荐)
|
||||
### docker stop(推荐)
|
||||
|
||||
### 基本用法
|
||||
#### 基本用法
|
||||
|
||||
```bash
|
||||
$ docker stop 容器名或ID
|
||||
```
|
||||
|
||||
### 工作原理
|
||||
#### 工作原理
|
||||
|
||||
```
|
||||
docker stop mycontainer
|
||||
@@ -35,71 +35,71 @@ docker stop mycontainer
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 自定义超时时间
|
||||
#### 自定义超时时间
|
||||
|
||||
```bash
|
||||
# 等待 30 秒后强制终止
|
||||
## 等待 30 秒后强制终止
|
||||
$ docker stop -t 30 mycontainer
|
||||
|
||||
# 立即发送 SIGKILL(相当于 docker kill)
|
||||
## 立即发送 SIGKILL(相当于 docker kill)
|
||||
$ docker stop -t 0 mycontainer
|
||||
```
|
||||
|
||||
### 停止多个容器
|
||||
#### 停止多个容器
|
||||
|
||||
```bash
|
||||
# 停止多个指定容器
|
||||
## 停止多个指定容器
|
||||
$ docker stop container1 container2 container3
|
||||
|
||||
# 停止所有运行中的容器
|
||||
## 停止所有运行中的容器
|
||||
$ docker stop $(docker ps -q)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## docker kill
|
||||
### docker kill
|
||||
|
||||
### 基本用法
|
||||
#### 基本用法
|
||||
|
||||
```bash
|
||||
$ docker kill 容器名或ID
|
||||
```
|
||||
|
||||
### 与 stop 的区别
|
||||
#### 与 stop 的区别
|
||||
|
||||
| 命令 | 信号 | 使用场景 |
|
||||
|------|------|---------|
|
||||
| `docker stop` | SIGTERM → SIGKILL | 正常停止,让应用优雅退出 |
|
||||
| `docker kill` | SIGKILL | 应用无响应,强制终止 |
|
||||
|
||||
### 发送自定义信号
|
||||
#### 发送自定义信号
|
||||
|
||||
```bash
|
||||
# 发送 SIGHUP(让进程重新加载配置)
|
||||
## 发送 SIGHUP(让进程重新加载配置)
|
||||
$ docker kill -s HUP mycontainer
|
||||
|
||||
# 发送 SIGTERM
|
||||
## 发送 SIGTERM
|
||||
$ docker kill -s TERM mycontainer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 容器自动终止
|
||||
### 容器自动终止
|
||||
|
||||
容器的生命周期与主进程绑定。主进程退出时,容器自动停止:
|
||||
|
||||
```bash
|
||||
# 主进程是交互式 bash
|
||||
## 主进程是交互式 bash
|
||||
$ docker run -it ubuntu bash
|
||||
root@abc123:/# exit # 退出 bash → 容器停止
|
||||
|
||||
# 主进程执行完毕
|
||||
## 主进程执行完毕
|
||||
$ docker run ubuntu echo "Hello" # echo 执行完 → 容器停止
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 查看已停止的容器
|
||||
### 查看已停止的容器
|
||||
|
||||
```bash
|
||||
$ docker ps -a
|
||||
@@ -120,30 +120,30 @@ c5d3a5e8f7b2 nginx "nginx" Up 5 minutes mynginx
|
||||
|
||||
---
|
||||
|
||||
## 重新启动容器
|
||||
### 重新启动容器
|
||||
|
||||
### 启动已停止的容器
|
||||
#### 启动已停止的容器
|
||||
|
||||
```bash
|
||||
$ docker start 容器名或ID
|
||||
|
||||
# 启动并附加终端
|
||||
## 启动并附加终端
|
||||
$ docker start -ai 容器名
|
||||
```
|
||||
|
||||
### 重启运行中的容器
|
||||
#### 重启运行中的容器
|
||||
|
||||
```bash
|
||||
# 先停止再启动
|
||||
## 先停止再启动
|
||||
$ docker restart 容器名
|
||||
|
||||
# 自定义停止超时
|
||||
## 自定义停止超时
|
||||
$ docker restart -t 30 容器名
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 生命周期状态图
|
||||
### 生命周期状态图
|
||||
|
||||
```
|
||||
docker create
|
||||
@@ -182,21 +182,21 @@ $ docker restart -t 30 容器名
|
||||
|
||||
---
|
||||
|
||||
## 批量操作
|
||||
### 批量操作
|
||||
|
||||
### 停止所有容器
|
||||
#### 停止所有容器
|
||||
|
||||
```bash
|
||||
$ docker stop $(docker ps -q)
|
||||
```
|
||||
|
||||
### 删除所有已停止的容器
|
||||
#### 删除所有已停止的容器
|
||||
|
||||
```bash
|
||||
$ docker container prune
|
||||
```
|
||||
|
||||
### 停止并删除所有容器
|
||||
#### 停止并删除所有容器
|
||||
|
||||
```bash
|
||||
$ docker stop $(docker ps -q) && docker container prune -f
|
||||
@@ -204,9 +204,9 @@ $ docker stop $(docker ps -q) && docker container prune -f
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
### 常见问题
|
||||
|
||||
### Q: 容器停止很慢
|
||||
#### Q: 容器停止很慢
|
||||
|
||||
原因:应用没有正确处理 SIGTERM 信号,需要等待超时后强制终止。
|
||||
|
||||
@@ -215,31 +215,31 @@ $ docker stop $(docker ps -q) && docker container prune -f
|
||||
2. 使用 `docker stop -t 0` 立即终止
|
||||
3. 检查 Dockerfile 中的 `STOPSIGNAL` 配置
|
||||
|
||||
### Q: 如何让容器优雅退出
|
||||
#### Q: 如何让容器优雅退出
|
||||
|
||||
确保容器主进程正确处理信号:
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile 示例
|
||||
## Dockerfile 示例
|
||||
FROM node:22
|
||||
...
|
||||
# 使用 exec 形式确保信号能传递给 node 进程
|
||||
## 使用 exec 形式确保信号能传递给 node 进程
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
### Q: 容器无法停止
|
||||
#### Q: 容器无法停止
|
||||
|
||||
```bash
|
||||
# 强制终止
|
||||
## 强制终止
|
||||
$ docker kill 容器名
|
||||
|
||||
# 如果仍无法停止,检查系统资源
|
||||
## 如果仍无法停止,检查系统资源
|
||||
$ docker inspect 容器名
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 本章小结
|
||||
### 本章小结
|
||||
|
||||
| 操作 | 命令 | 说明 |
|
||||
|------|------|------|
|
||||
@@ -249,8 +249,8 @@ $ docker inspect 容器名
|
||||
| 重启 | `docker restart` | 停止后立即启动 |
|
||||
| 停止全部 | `docker stop $(docker ps -q)` | 停止所有运行中容器 |
|
||||
|
||||
## 延伸阅读
|
||||
### 延伸阅读
|
||||
|
||||
- [启动容器](run.md):容器启动详解
|
||||
- [删除容器](rm.md):清理容器
|
||||
- [启动容器](5.1_run.md):容器启动详解
|
||||
- [删除容器](4.3_rm.md):清理容器
|
||||
- [容器日志](logs.md):排查停止原因
|
||||
@@ -1,6 +1,6 @@
|
||||
# 进入容器
|
||||
## 进入容器
|
||||
|
||||
## 为什么需要进入容器
|
||||
### 为什么需要进入容器
|
||||
|
||||
使用 `-d` 参数启动容器后,容器在后台运行。以下场景需要进入容器内部操作:
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| **检查状态** | 查看进程、网络连接、文件系统 |
|
||||
| **开发测试** | 交互式测试命令、验证环境 |
|
||||
|
||||
## 两种进入方式
|
||||
### 两种进入方式
|
||||
|
||||
Docker 提供两种进入容器的命令:
|
||||
|
||||
@@ -22,19 +22,19 @@ Docker 提供两种进入容器的命令:
|
||||
|
||||
---
|
||||
|
||||
## docker exec(推荐)
|
||||
### docker exec(推荐)
|
||||
|
||||
### 基本用法
|
||||
#### 基本用法
|
||||
|
||||
```bash
|
||||
# 进入容器并启动交互式 shell
|
||||
## 进入容器并启动交互式 shell
|
||||
$ docker exec -it 容器名 /bin/bash
|
||||
|
||||
# 或使用 sh(适用于 Alpine 等精简镜像)
|
||||
## 或使用 sh(适用于 Alpine 等精简镜像)
|
||||
$ docker exec -it 容器名 /bin/sh
|
||||
```
|
||||
|
||||
### 参数说明
|
||||
#### 参数说明
|
||||
|
||||
| 参数 | 作用 |
|
||||
|------|------|
|
||||
@@ -45,44 +45,44 @@ $ docker exec -it 容器名 /bin/sh
|
||||
| `-w` | 指定工作目录 |
|
||||
| `-e` | 设置环境变量 |
|
||||
|
||||
### 示例
|
||||
#### 示例
|
||||
|
||||
```bash
|
||||
# 启动一个后台容器
|
||||
## 启动一个后台容器
|
||||
$ docker run -dit --name myubuntu ubuntu
|
||||
69d137adef7a...
|
||||
|
||||
# 进入容器(交互式 shell)
|
||||
## 进入容器(交互式 shell)
|
||||
$ docker exec -it myubuntu bash
|
||||
root@69d137adef7a:/# ls
|
||||
bin boot dev etc home lib ...
|
||||
root@69d137adef7a:/# exit
|
||||
|
||||
# 容器仍在运行!
|
||||
## 容器仍在运行!
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE STATUS NAMES
|
||||
69d137adef7a ubuntu Up 2 minutes myubuntu
|
||||
```
|
||||
|
||||
### 执行单条命令
|
||||
#### 执行单条命令
|
||||
|
||||
不进入交互模式,直接执行命令:
|
||||
|
||||
```bash
|
||||
# 查看容器内进程
|
||||
## 查看容器内进程
|
||||
$ docker exec myubuntu ps aux
|
||||
|
||||
# 查看配置文件
|
||||
## 查看配置文件
|
||||
$ docker exec myubuntu cat /etc/nginx/nginx.conf
|
||||
|
||||
# 以 root 用户执行
|
||||
## 以 root 用户执行
|
||||
$ docker exec -u root myubuntu apt update
|
||||
```
|
||||
|
||||
### 只用 -i 不用 -t 的区别
|
||||
#### 只用 -i 不用 -t 的区别
|
||||
|
||||
```bash
|
||||
# 只用 -i:可以执行命令,但没有提示符
|
||||
## 只用 -i:可以执行命令,但没有提示符
|
||||
$ docker exec -i myubuntu bash
|
||||
ls # 输入命令
|
||||
bin # 输出结果
|
||||
@@ -90,7 +90,7 @@ boot
|
||||
dev
|
||||
...
|
||||
|
||||
# 用 -it:有完整的终端体验
|
||||
## 用 -it:有完整的终端体验
|
||||
$ docker exec -it myubuntu bash
|
||||
root@69d137adef7a:/# # 有提示符
|
||||
```
|
||||
@@ -99,15 +99,15 @@ root@69d137adef7a:/# # 有提示符
|
||||
|
||||
---
|
||||
|
||||
## docker attach(谨慎使用)
|
||||
### docker attach(谨慎使用)
|
||||
|
||||
### 基本用法
|
||||
#### 基本用法
|
||||
|
||||
```bash
|
||||
$ docker attach 容器名
|
||||
```
|
||||
|
||||
### 工作原理
|
||||
#### 工作原理
|
||||
|
||||
`attach` 会附加到容器的**主进程**(PID 1)的标准输入输出:
|
||||
|
||||
@@ -121,19 +121,19 @@ $ docker attach 容器名
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 示例
|
||||
#### 示例
|
||||
|
||||
```bash
|
||||
# 启动容器
|
||||
## 启动容器
|
||||
$ docker run -dit --name myubuntu ubuntu
|
||||
243c32535da7...
|
||||
|
||||
# 附加到容器
|
||||
## 附加到容器
|
||||
$ docker attach myubuntu
|
||||
root@243c32535da7:/#
|
||||
```
|
||||
|
||||
### ⚠️ 重要警告
|
||||
#### ⚠️ 重要警告
|
||||
|
||||
**从 attach 会话中输入 `exit` 或按 `Ctrl+D` 会导致容器停止!**
|
||||
|
||||
@@ -148,14 +148,14 @@ CONTAINER ID IMAGE STATUS NAMES
|
||||
|
||||
**原因**:attach 附加到主进程,退出主进程就等于退出容器。
|
||||
|
||||
### 安全退出 attach
|
||||
#### 安全退出 attach
|
||||
|
||||
使用 `Ctrl+P` 然后 `Ctrl+Q` 可以从 attach 会话中**分离**,而不停止容器:
|
||||
|
||||
```bash
|
||||
$ docker attach myubuntu
|
||||
root@243c32535da7:/#
|
||||
# 按 Ctrl+P 然后 Ctrl+Q
|
||||
## 按 Ctrl+P 然后 Ctrl+Q
|
||||
read escape sequence
|
||||
|
||||
$ docker ps # 容器仍在运行
|
||||
@@ -165,7 +165,7 @@ CONTAINER ID IMAGE STATUS NAMES
|
||||
|
||||
---
|
||||
|
||||
## exec vs attach 对比
|
||||
### exec vs attach 对比
|
||||
|
||||
| 特性 | docker exec | docker attach |
|
||||
|------|-------------|---------------|
|
||||
@@ -190,50 +190,50 @@ docker exec docker attach
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
### 最佳实践
|
||||
|
||||
### 1. 首选 docker exec
|
||||
#### 1. 首选 docker exec
|
||||
|
||||
```bash
|
||||
# 进入容器调试
|
||||
## 进入容器调试
|
||||
$ docker exec -it myapp bash
|
||||
|
||||
# 查看日志
|
||||
## 查看日志
|
||||
$ docker exec myapp tail -f /var/log/app.log
|
||||
|
||||
# 执行数据库迁移
|
||||
## 执行数据库迁移
|
||||
$ docker exec myapp python manage.py migrate
|
||||
```
|
||||
|
||||
### 2. 生产环境避免进入容器
|
||||
#### 2. 生产环境避免进入容器
|
||||
|
||||
笔者建议:生产环境应尽量避免进入容器直接操作,而是通过:
|
||||
- 日志系统查看日志(如 `docker logs` 或集中式日志)
|
||||
- 监控系统查看状态
|
||||
- 重新部署而非手动修改
|
||||
|
||||
### 3. 无 shell 镜像的处理
|
||||
#### 3. 无 shell 镜像的处理
|
||||
|
||||
某些精简镜像(如基于 `scratch` 或 `distroless`)没有 shell:
|
||||
|
||||
```bash
|
||||
# 这会失败
|
||||
## 这会失败
|
||||
$ docker exec -it myapp bash
|
||||
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found
|
||||
|
||||
# 解决方案:使用调试容器(Docker Desktop 或 Kubernetes debug)
|
||||
## 解决方案:使用调试容器(Docker Desktop 或 Kubernetes debug)
|
||||
$ docker debug myapp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
### 常见问题
|
||||
|
||||
### Q: exec 进入后看不到其他终端的操作
|
||||
#### Q: exec 进入后看不到其他终端的操作
|
||||
|
||||
这是正常的。exec 启动的是独立进程,多个 exec 会话互不影响。
|
||||
|
||||
### Q: 容器没有 bash
|
||||
#### Q: 容器没有 bash
|
||||
|
||||
尝试使用 sh:
|
||||
|
||||
@@ -241,7 +241,7 @@ $ docker debug myapp
|
||||
$ docker exec -it myapp /bin/sh
|
||||
```
|
||||
|
||||
### Q: 需要 root 权限
|
||||
#### Q: 需要 root 权限
|
||||
|
||||
```bash
|
||||
$ docker exec -u root -it myapp bash
|
||||
@@ -249,7 +249,7 @@ $ docker exec -u root -it myapp bash
|
||||
|
||||
---
|
||||
|
||||
## 本章小结
|
||||
### 本章小结
|
||||
|
||||
| 需求 | 推荐命令 |
|
||||
|------|---------|
|
||||
@@ -257,8 +257,8 @@ $ docker exec -u root -it myapp bash
|
||||
| 执行单条命令 | `docker exec 容器名 命令` |
|
||||
| 查看主进程输出 | `docker attach 容器名`(慎用) |
|
||||
|
||||
## 延伸阅读
|
||||
### 延伸阅读
|
||||
|
||||
- [后台运行](daemon.md):理解容器主进程
|
||||
- [后台运行](5.2_daemon.md):理解容器主进程
|
||||
- [查看容器](ls.md):列出和过滤容器
|
||||
- [容器日志](logs.md):查看容器输出
|
||||
@@ -1,6 +1,6 @@
|
||||
# 导出和导入容器
|
||||
## 导出和导入容器
|
||||
|
||||
## 导出容器
|
||||
### 导出容器
|
||||
|
||||
如果要导出本地某个容器,可以使用 `docker export` 命令。
|
||||
```bash
|
||||
@@ -12,7 +12,7 @@ $ docker export 7691a814370e > ubuntu.tar
|
||||
|
||||
这样将导出容器快照到本地文件。
|
||||
|
||||
## 导入容器快照
|
||||
### 导入容器快照
|
||||
|
||||
可以使用 `docker import` 从容器快照文件中再导入为镜像,例如
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 删除容器
|
||||
## 删除容器
|
||||
|
||||
## 基本用法
|
||||
### 基本用法
|
||||
|
||||
使用 `docker rm` 删除已停止的容器:
|
||||
|
||||
@@ -12,7 +12,7 @@ $ docker rm 容器名或ID
|
||||
|
||||
---
|
||||
|
||||
## 删除选项
|
||||
### 删除选项
|
||||
|
||||
| 选项 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
@@ -20,31 +20,31 @@ $ docker rm 容器名或ID
|
||||
| `-f` | 强制删除运行中的容器 | `docker rm -f mycontainer` |
|
||||
| `-v` | 同时删除关联的匿名卷 | `docker rm -v mycontainer` |
|
||||
|
||||
### 删除已停止的容器
|
||||
#### 删除已停止的容器
|
||||
|
||||
```bash
|
||||
$ docker rm mycontainer
|
||||
mycontainer
|
||||
```
|
||||
|
||||
### 强制删除运行中的容器
|
||||
#### 强制删除运行中的容器
|
||||
|
||||
```bash
|
||||
# 不加 -f 会报错
|
||||
## 不加 -f 会报错
|
||||
$ docker rm running_container
|
||||
Error: cannot remove running container
|
||||
|
||||
# 加 -f 强制删除
|
||||
## 加 -f 强制删除
|
||||
$ docker rm -f running_container
|
||||
running_container
|
||||
```
|
||||
|
||||
> ⚠️ 强制删除会向容器发送 SIGKILL 信号,可能导致数据丢失。建议先 `docker stop` 优雅停止。
|
||||
|
||||
### 删除容器及其数据卷
|
||||
#### 删除容器及其数据卷
|
||||
|
||||
```bash
|
||||
# 删除容器时同时删除其匿名卷
|
||||
## 删除容器时同时删除其匿名卷
|
||||
$ docker rm -v mycontainer
|
||||
```
|
||||
|
||||
@@ -52,12 +52,12 @@ $ docker rm -v mycontainer
|
||||
|
||||
---
|
||||
|
||||
## 批量删除
|
||||
### 批量删除
|
||||
|
||||
### 删除所有已停止的容器
|
||||
#### 删除所有已停止的容器
|
||||
|
||||
```bash
|
||||
# 方式一:使用 prune 命令(推荐)
|
||||
## 方式一:使用 prune 命令(推荐)
|
||||
$ docker container prune
|
||||
|
||||
WARNING! This will remove all stopped containers.
|
||||
@@ -67,37 +67,37 @@ abc123...
|
||||
def456...
|
||||
Total reclaimed space: 150MB
|
||||
|
||||
# 方式二:不提示确认
|
||||
## 方式二:不提示确认
|
||||
$ docker container prune -f
|
||||
```
|
||||
|
||||
### 删除所有容器(包括运行中的)
|
||||
#### 删除所有容器(包括运行中的)
|
||||
|
||||
```bash
|
||||
# 先停止所有容器,再删除
|
||||
## 先停止所有容器,再删除
|
||||
$ docker stop $(docker ps -q)
|
||||
$ docker rm $(docker ps -aq)
|
||||
|
||||
# 或者直接强制删除
|
||||
## 或者直接强制删除
|
||||
$ docker rm -f $(docker ps -aq)
|
||||
```
|
||||
|
||||
### 按条件删除
|
||||
#### 按条件删除
|
||||
|
||||
```bash
|
||||
# 删除所有已退出的容器
|
||||
## 删除所有已退出的容器
|
||||
$ docker rm $(docker ps -aq -f status=exited)
|
||||
|
||||
# 删除名称包含 "test" 的容器
|
||||
## 删除名称包含 "test" 的容器
|
||||
$ docker rm $(docker ps -aq -f name=test)
|
||||
|
||||
# 删除 24 小时前创建的容器
|
||||
## 删除 24 小时前创建的容器
|
||||
$ docker container prune --filter "until=24h"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常用过滤条件
|
||||
### 常用过滤条件
|
||||
|
||||
`docker ps` 的过滤条件可以配合 `rm` 使用:
|
||||
|
||||
@@ -110,62 +110,62 @@ $ docker container prune --filter "until=24h"
|
||||
| `before=xxx` | 在某容器之前创建 | `-f before=mycontainer` |
|
||||
| `since=xxx` | 在某容器之后创建 | `-f since=mycontainer` |
|
||||
|
||||
### 示例
|
||||
#### 示例
|
||||
|
||||
```bash
|
||||
# 删除所有基于 nginx 镜像的容器
|
||||
## 删除所有基于 nginx 镜像的容器
|
||||
$ docker rm $(docker ps -aq -f ancestor=nginx)
|
||||
|
||||
# 删除所有创建后未启动的容器
|
||||
## 删除所有创建后未启动的容器
|
||||
$ docker rm $(docker ps -aq -f status=created)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 容器与镜像的依赖关系
|
||||
### 容器与镜像的依赖关系
|
||||
|
||||
> 有容器依赖的镜像无法删除。
|
||||
|
||||
```bash
|
||||
# 尝试删除有容器依赖的镜像
|
||||
## 尝试删除有容器依赖的镜像
|
||||
$ docker image rm nginx
|
||||
Error: image is being used by stopped container abc123
|
||||
|
||||
# 需要先删除依赖该镜像的容器
|
||||
## 需要先删除依赖该镜像的容器
|
||||
$ docker rm abc123
|
||||
$ docker image rm nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 清理策略建议
|
||||
### 清理策略建议
|
||||
|
||||
### 开发环境
|
||||
#### 开发环境
|
||||
|
||||
```bash
|
||||
# 定期清理已停止的容器
|
||||
## 定期清理已停止的容器
|
||||
$ docker container prune -f
|
||||
|
||||
# 一键清理所有未使用资源
|
||||
## 一键清理所有未使用资源
|
||||
$ docker system prune -f
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
#### 生产环境
|
||||
|
||||
```bash
|
||||
# 使用 --rm 参数运行临时容器
|
||||
## 使用 --rm 参数运行临时容器
|
||||
$ docker run --rm ubuntu echo "Hello"
|
||||
# 容器退出后自动删除
|
||||
## 容器退出后自动删除
|
||||
|
||||
# 定期清理(设置保留时间)
|
||||
## 定期清理(设置保留时间)
|
||||
$ docker container prune --filter "until=168h" # 保留 7 天内的
|
||||
```
|
||||
|
||||
### 完整清理脚本
|
||||
#### 完整清理脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# cleanup.sh - Docker 资源清理脚本
|
||||
## cleanup.sh - Docker 资源清理脚本
|
||||
|
||||
echo "清理已停止的容器..."
|
||||
docker container prune -f
|
||||
@@ -185,9 +185,9 @@ docker system df
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
### 常见问题
|
||||
|
||||
### Q: 容器无法删除
|
||||
#### Q: 容器无法删除
|
||||
|
||||
```bash
|
||||
Error: container is running
|
||||
@@ -198,11 +198,11 @@ Error: container is running
|
||||
```bash
|
||||
$ docker stop mycontainer
|
||||
$ docker rm mycontainer
|
||||
# 或
|
||||
## 或
|
||||
$ docker rm -f mycontainer
|
||||
```
|
||||
|
||||
### Q: 删除后磁盘空间没释放
|
||||
#### Q: 删除后磁盘空间没释放
|
||||
|
||||
可能原因:
|
||||
1. 容器的数据卷未删除(使用 `-v` 参数)
|
||||
@@ -212,16 +212,16 @@ $ docker rm -f mycontainer
|
||||
解决:
|
||||
|
||||
```bash
|
||||
# 查看空间占用
|
||||
## 查看空间占用
|
||||
$ docker system df
|
||||
|
||||
# 完整清理
|
||||
## 完整清理
|
||||
$ docker system prune -a --volumes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 本章小结
|
||||
### 本章小结
|
||||
|
||||
| 操作 | 命令 |
|
||||
|------|------|
|
||||
@@ -231,8 +231,8 @@ $ docker system prune -a --volumes
|
||||
| 清理所有已停止容器 | `docker container prune` |
|
||||
| 删除所有容器 | `docker rm -f $(docker ps -aq)` |
|
||||
|
||||
## 延伸阅读
|
||||
### 延伸阅读
|
||||
|
||||
- [终止容器](stop.md):优雅停止容器
|
||||
- [删除镜像](../04_image/rm.md):清理镜像
|
||||
- [终止容器](5.3_stop.md):优雅停止容器
|
||||
- [删除镜像](../04_image/4.3_rm.md):清理镜像
|
||||
- [数据卷](../07_data_network/data/volume.md):数据卷管理
|
||||
@@ -1,4 +1,4 @@
|
||||
# 操作 Docker 容器
|
||||
# 第五章 操作容器
|
||||
|
||||
容器是 Docker 又一核心概念。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user