Docker 容器管理完全指南
容器是 Docker 的核心概念,熟练管理容器生命周期、日志、资源限制是 Docker 进阶的必备技能。本文系统讲解容器的完整管理流程。
容器生命周期
容器从创建到销毁经历多个状态,理解这个流程才能更好地管理它们。
创建(created)→ 运行(running)→ 暂停(paused)→ 停止(stopped)→ 删除(deleted)
↓
退出(exited)1
2
3
2
3
创建与启动
bash
# 创建容器(不启动)
docker create --name mynginx nginx:latest
# 创建并立即启动
docker run --name mynginx -d nginx:latest
# -d: 后台运行(detached)
# -i: 交互模式(stdin保持打开)
# -t: 分配伪终端
# 创建并进入交互式容器
docker run -it --name mycentos centos:7 /bin/bash
# 退出容器: exit 或 Ctrl+D
# 创建时指定环境变量
docker run -e MYSQL_ROOT_PASSWORD=123456 --name mysql -d mysql:8
# 创建时指定标签/元数据
docker run --label env=prod --label team=backend -d nginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
启动与停止
bash
# 启动已停止的容器
docker start mynginx
# 停止运行中的容器(优雅停止)
docker stop mynginx
# 等待10秒(默认)后强制终止
# 指定超时时间
docker stop -t 60 mynginx # 等待60秒
# 强制终止
docker kill mynginx
# 重启容器
docker restart mynginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
容器状态查看
bash
# 查看运行中的容器
docker ps
# 查看所有容器(含已停止)
docker ps -a
# 查看容器详细信息
docker inspect mynginx
# 只看容器的IP地址
docker inspect -f '{{.NetworkSettings.IPAddress}}' mynginx
# 查看容器运行状态(是否在运行)
docker ps --filter "name=mynginx" --format "{{.Status}}"1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
进入容器
容器在后台运行时,经常需要进入容器内部进行操作。
bash
# 使用 exec(推荐,Docker官方方式)
docker exec -it mynginx /bin/bash
docker exec -it mynginx sh # 部分容器无bash,用sh
# 以前台方式进入(占用终端)
docker attach mynginx
# 注意: attach 会进入容器的主进程,exit会导致容器停止
# 推荐用 exec 进入,完成后 Ctrl+P Ctrl+Q detach
# 快速进入 - 直接执行命令
docker exec mynginx cat /etc/nginx/nginx.conf
# 以root身份进入
docker exec -u root -it mynginx /bin/bash1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
容器日志
日志是排查问题的第一手资料。
bash
# 查看容器日志(实时跟踪)
docker logs -f mynginx
# 查看最新100行
docker logs --tail 100 mynginx
# 显示时间戳
docker logs -t mynginx
# 跟踪最新日志
docker logs --since 1h mynginx # 最近1小时
docker logs --since "2024-01-01" mynginx
# 搜索日志中的关键词
docker logs mynginx 2>&1 | grep "ERROR"
# 日志重定向到文件
docker logs -f mynginx > /tmp/nginx.log 2>&1 &
# 查看日志driver
docker inspect -f '{{.HostConfig.LogConfig.Type}}' mynginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
日志配置
Docker 默认使用 json-file 日志驱动,可配置日志轮转:
bash
# 启动时配置日志大小限制
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx1
2
3
4
5
6
2
3
4
5
6
生产环境建议在 /etc/docker/daemon.json 中全局配置:
json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5"
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
资源限制
不限制资源的话,容器可能耗尽宿主机资源影响其他服务。
内存限制
bash
# 限制最大内存为 512MB
docker run -d --name app --memory 512m nginx
# 限制内存 + swap
docker run -d --name app --memory 512m --memory-swap 1g nginx
# 限制内存软上限(可突破但会被压缩)
docker run -d --name app --memory 256m --memory-reservation 128m nginx
# OOM 行为控制(不允许被kill)
docker run -d --name app --memory 512m --oom-kill-disable nginx
# 查看内存使用
docker stats mynginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
CPU 限制
bash
# 限制最多使用1个CPU核心
docker run -d --name app --cpus 1 nginx
# 限制使用 0.5 个 CPU(50%)
docker run -d --name app --cpus 0.5 nginx
# 指定在特定核心上运行
docker run -d --name app --cpuset-cpus 0,2 nginx
# CPU权重(相对值,默认1024)
docker run -d --name app --cpu-shares 512 nginx
# 查看 CPU 使用
docker stats mynginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
IO 限制
bash
# 限制每秒读的次数和带宽
docker run -d --name app \
--device-read-iops /dev/sda:1000 \
--device-write-iops /dev/sda:500 \
nginx
# 限制读的带宽
docker run -d --name app \
--device-read-bps /dev/sda:10mb \
nginx1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
查看资源使用
bash
# 实时显示资源使用(容器级)
docker stats
# 显示所有容器(停止的也显示)
docker stats -a
# 只显示特定容器
docker stats mynginx mysql redis
# 显示容器ID和名称
docker stats --format "table {{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# 查看容器进程
docker top mynginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
优雅停止
生产环境中,优雅停止(Graceful Shutdown)至关重要,确保应用有时间清理资源、保存状态。
原理
- Docker 发送
SIGTERM信号给容器主进程 - 应用收到信号,执行优雅关闭(关闭连接、保存数据)
- 如果超时(默认10秒),发送
SIGKILL强制终止
应用层面配合
python
# Python Flask 应用示例
import signal
import sys
def graceful_shutdown(signum, frame):
print("收到 SIGTERM,开始优雅关闭...")
# 保存状态
save_state()
# 关闭数据库连接
db.close()
sys.exit(0)
signal.signal(signal.SIGTERM, graceful_shutdown)
signal.signal(signal.SIGINT, graceful_shutdown)
app.run()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
javascript
// Node.js 应用示例
process.on('SIGTERM', () => {
console.log('收到 SIGTERM,开始优雅关闭...');
server.close(() => {
console.log('HTTP server closed');
process.exit(0);
});
});1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Docker 配置优雅停止
bash
# 指定停止超时时间(默认10秒)
docker run -d --name app --stop-timeout 30 nginx
# 修改已运行容器的超时
docker update --stop-timeout 20 mynginx1
2
3
4
5
2
3
4
5
强制停止 vs 优雅停止
bash
# 优雅停止(发送 SIGTERM)
docker stop mynginx
# 强制停止(发送 SIGKILL)
docker kill mynginx
# 发送自定义信号
docker kill -s SIGUSR1 mynginx1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
容器导入导出
bash
# 导出容器快照(不包含数据卷)
docker export -o mynginx.tar mynginx
# 导入为镜像
docker import mynginx.tar mynginx:backup
# 保存镜像(包含完整层信息)
docker save -o nginx.tar nginx:latest
# 加载镜像
docker load -i nginx.tar1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
两者的区别:
export/import:导出容器快照,更小但丢失历史层save/load:完整保存镜像,适合完整迁移
容器批量管理
bash
# 停止所有运行中的容器
docker stop $(docker ps -q)
# 删除所有已停止的容器
docker container prune
# 删除所有已停止的容器(更精确)
docker ps -aq --filter "status=exited" | xargs docker rm
# 清理所有未使用的镜像、容器、网络
docker system prune
# 更彻底的清理(包含数据卷)
docker system prune --volumes
# 批量停止并删除
docker stop $(docker ps -aq) && docker rm $(docker ps -aq)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
常见问题处理
容器自动退出
bash
# 查看退出原因
docker logs mycontainer
docker inspect mycontainer
# 常见原因:
# 1. 没有长期运行的进程(前台没有任务)
# 解决: docker run -d nginx # nginx 默认前台运行
# 2. 进程崩溃
# 解决: 检查日志
# 3. 入口脚本执行完毕
# 解决: 使用 tail -f /dev/null 或保持前台进程1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
容器无法停止
bash
# 强制删除(不推荐,可能丢数据)
docker rm -f mynginx
# 或者分步处理
docker kill --signal=SIGKILL mynginx
docker rm mynginx1
2
3
4
5
6
2
3
4
5
6
容器连接数过多
bash
# 查看容器进程数
docker top mynginx
# 限制容器最大进程数
docker run -d --name app --pids-limit 100 nginx1
2
3
4
5
2
3
4
5
容器时区问题
bash
# 挂载宿主机的时区文件
docker run -d --name app \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
nginx1
2
3
4
5
2
3
4
5
容器中文乱码
bash
docker run -d --name app \
-e LANG=C.UTF-8 \
-e LC_ALL=C.UTF-8 \
nginx1
2
3
4
2
3
4
常用命令速查
| 命令 | 说明 |
|---|---|
docker run -d nginx | 后台运行 nginx |
docker ps -a | 查看所有容器 |
docker exec -it c sh | 进入容器 |
docker logs -f c | 实时查看日志 |
docker stop c | 优雅停止 |
docker rm c | 删除容器 |
docker stats | 资源使用监控 |
docker inspect c | 容器详细信息 |
docker update --memory 512m c | 更新容器配置 |
熟练掌握以上命令和方法,能够高效地管理和运维 Docker 容器。建议结合监控工具(如 Prometheus + cAdvisor)长期观察容器资源使用情况。
[[返回 Docker 首页|../index]]