Docker: 容器生命周期管理
最后更新:2026-08-26
容器和进程一样有完整的生命周期——掌握容器的状态转换和操作命令,是 Docker 运维的基本功。
1. 你将学到
- 容器的六种状态及转换
- 启动/停止/重启操作
- 暂停与恢复的区别
- 容器日志查看与过滤
- 容器进程与资源排查
2. 一个运维工程师的真实故事
(1) 痛点:生产容器凌晨崩溃
Charlie 的生产环境容器在凌晨 3 点突然挂了。监控告警响起,但 Charlie 不知道容器为什么退出——是 OOM?是应用异常?还是被手动杀了?他需要在不重建容器的情况下快速排查原因。
(2) log+监控的解法
docker logs 显示了 OOM error,docker stats 确认了内存超限。
BASH
# Check container exit logs
docker logs --tail 50 myapp
# Check container resource usage
docker stats --no-stream
(3) 收益:5 分钟定位根因
Charlie 用 docker logs 发现 "Out of memory" 错误,docker inspect 确认退出码 137(OOM Kill),调整 --memory 参数后容器恢复正常。从告警到修复只用了 5 分钟。
3. 容器六种状态
容器从创建到删除,经历六种状态的转换。
stateDiagram-v2
[*] --> Created : docker create
Created --> Running : docker start
Created --> Running : docker run
Running --> Paused : docker pause
Paused --> Running : docker unpause
Running --> Stopped : docker stop / Ctrl+C
Running --> Stopped : docker kill
Stopped --> Running : docker start
Running --> Restarting : Process crash + restart policy
Restarting --> Running : Restart succeeds
Restarting --> Stopped : Restart fails
Running --> Dead : Unrecoverable error
Stopped --> [*] : docker rm
Dead --> [*] : docker rm
(1) 状态详解
| 状态 | 说明 | 常见触发 |
|---|---|---|
| Created | 已创建但未启动 | docker create / docker run(未完成启动前) |
| Running | 正在运行 | docker start / docker run -d |
| Paused | 已暂停(冻结进程) | docker pause |
| Stopped | 已停止(Exited) | docker stop / docker kill / 进程退出 |
| Restarting | 正在重启 | 容器崩溃 + restart 策略生效 |
| Dead | 不可恢复 | Docker 内部错误(极少见) |
(2) 查看容器状态
BASH
# List running containers (Running state only)
docker ps
# List all containers (all states)
docker ps -a
# Filter by status
docker ps -a --filter "status=exited"
docker ps -a --filter "status=running"
4. 启动、停止与重启
▶ 示例:start / stop / restart(难度⭐)
BASH
# Create and start a container
docker run -d --name web -p 8080:80 nginx:latest
# Stop the container (graceful shutdown)
docker stop web
# Start it again
docker start web
# Restart (stop + start in one command)
docker restart web
# Check status after each operation
docker ps -a --filter name=web
(1) docker stop vs docker kill
| 维度 | docker stop |
docker kill |
|---|---|---|
| 信号 | SIGTERM → 等待 → SIGKILL | SIGKILL(默认) |
| 优雅 | ✅ 给应用 30 秒清理时间 | ❌ 立即强制终止 |
| 数据安全 | 应用可完成写入/关闭连接 | 可能丢失未写入的数据 |
| 等待时间 | 默认 30 秒(-t 可调) |
无等待 |
| 适用场景 | 日常停止 | 容器无响应时强制终止 |
BASH
# Graceful stop with custom timeout (60 seconds)
docker stop -t 60 web
# Force kill immediately
docker kill web
# Send a custom signal
docker kill -s SIGUSR1 web
💡 提示: 生产环境优先用
docker stop,只有在容器不响应时才用 docker kill。应用应正确处理 SIGTERM 信号,实现优雅关闭。
5. 暂停与恢复
▶ 示例:pause / unpause(难度⭐⭐)
BASH
# Pause the container (freeze all processes)
docker pause web
# Check: status should be "Paused"
docker ps -a --filter name=web
# Unpause the container
docker unpause web
(1) docker pause vs docker stop
| 维度 | docker pause |
docker stop |
|---|---|---|
| 机制 | 冻结进程(cgroup freeze) | 发送 SIGTERM 信号 |
| 内存 | 保留在内存中 | 释放内存 |
| 恢复速度 | 即时(解冻) | 需重新启动进程 |
| 端口占用 | 仍然占用 | 释放 |
| 适用场景 | 临时释放 CPU、调试 | 正常关闭服务 |
⚠️ 注意: 暂停的容器仍然占用内存和端口,不适合长时间暂停。需要释放资源时应使用
docker stop。
6. 容器日志查看
▶ 示例:实时追踪容器日志(难度⭐⭐)
BASH
# Follow logs in real-time
docker logs -f web
# Show last 100 lines
docker logs --tail 100 web
# Show logs from the last 2 hours
docker logs --since 2h web
# Show logs between specific times
docker logs --since "2024-01-15T10:00:00" --until "2024-01-15T12:00:00" web
💻 输出:
TEXT
📖 仅展示
10.0.0.1 - - [15/Jan/2024:10:05:22 +0000] "GET / HTTP/1.1" 200 615
10.0.0.1 - - [15/Jan/2024:10:05:23 +0000] "GET /favicon.ico HTTP/1.1" 404 555
(1) 日志参数速查表
| 参数 | 作用 | 示例 |
|---|---|---|
-f / --follow |
实时追踪 | docker logs -f web |
--tail N |
显示最后 N 行 | --tail 100 |
--since |
显示某个时间之后的日志 | --since 2h / --since "2024-01-15" |
--until |
显示某个时间之前的日志 | --until 30m |
-t / --timestamps |
显示时间戳 | docker logs -t web |
7. 容器资源监控与排查
▶ 示例:实时监控容器资源(难度⭐⭐)
BASH
# Real-time resource stats for all containers
docker stats
# One-time snapshot (no streaming)
docker stats --no-stream
# Stats for a specific container
docker stats web --no-stream
💻 输出:
TEXT
📖 仅展示
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a1b2c3d4e5f6 web 0.02% 4.2MiB / 512MiB 0.82% 1.2kB / 0B 0B / 0B 9
▶ 示例:查看容器内进程(难度⭐)
BASH
# List processes running inside a container
docker top web
💻 输出:
TEXT
📖 仅展示
UID PID PPID C STIME TTY TIME CMD
root 1234 5678 0 10:05 ? 00:00:00 nginx: master process
www 1235 1234 0 10:05 ? 00:00:00 nginx: worker process
▶ 示例:查看容器详细配置(难度⭐⭐)
BASH
# Full container configuration (JSON)
docker inspect web
# Extract specific fields
docker inspect web --format='{{.State.Status}}'
docker inspect web --format='{{.State.ExitCode}}'
docker inspect web --format='{{.NetworkSettings.IPAddress}}'
docker inspect web --format='{{.HostConfig.Memory}}'
💻 输出:
TEXT
📖 仅展示
running
0
172.17.0.2
536870912
8. 进入运行中的容器
▶ 示例:用 docker exec 进入容器(难度⭐⭐)
BASH
# Open an interactive shell inside a running container
docker exec -it web bash
# Run a single command inside the container
docker exec web cat /etc/nginx/nginx.conf
# Copy files from container to host
docker cp web:/etc/nginx/nginx.conf ./nginx.conf
💡 提示:
docker exec 不会创建新容器,而是在已运行的容器内启动一个新进程。适合调试和临时操作。生产环境应避免依赖 docker exec——改用 Volume 挂载和日志收集。
9. 完整示例:模拟容器故障排查
BASH
# ============================================
# Complete walkthrough: Container crash diagnosis
# Covers: run, crash, logs, inspect, fix, restart
# ============================================
# 1. Start a container with limited memory
docker run -d \
--name crash-test \
--memory=50m \
--restart=on-failure:3 \
nginx:latest
# 2. Verify it's running
docker ps --filter name=crash-test
# 3. Simulate memory pressure from inside the container
docker exec -it crash-test bash -c "dd if=/dev/zero of=/tmp/bigfile bs=1M count=100"
# 4. Container may be OOM-killed, check status
docker ps -a --filter name=crash-test
# 5. Check the exit code (137 = OOM Kill)
docker inspect crash-test --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}'
# 6. Check logs for the crash reason
docker logs --tail 20 crash-test
# 7. Check Docker events for OOM
docker events --filter event=oom --since 5m
# 8. Fix: increase memory limit (need to recreate)
docker stop crash-test
docker rm crash-test
docker run -d \
--name crash-test \
--memory=256m \
--restart=on-failure:3 \
nginx:latest
# 9. Verify the fix
docker ps --filter name=crash-test
docker stats crash-test --no-stream
💻 输出(节选):
TEXT
📖 仅展示
# docker inspect --format
ExitCode: 137, OOMKilled: true
# docker events
2024-01-15T10:05:22Z container oom crash-test...
# After fix
CONTAINER ID IMAGE STATUS NAMES
b2c3d4e5f6a7 nginx:latest Up 10 seconds crash-test
❓ 常见问题
Q 容器停止后数据还在吗?
A 在。容器停止(stop)只是暂停了进程,文件系统仍然保留在磁盘上。用
docker start 可以恢复。但 docker rm 删除容器后数据就消失了——除非用了 Volume 挂载。Q docker stop 和 docker kill 什么区别?
A stop 发送 SIGTERM,给应用 30 秒优雅关闭(完成写入、关闭连接),超时再 SIGKILL。kill 直接发送 SIGKILL 立即终止。生产环境优先用 stop,只有容器无响应时才用 kill。
Q 怎么让容器崩溃后自动重启?
A 启动时加
--restart=always 或 --restart=unless-stopped。always 无论什么原因退出都重启;unless-stopped 手动 stop 后不自动重启。生产 Web 服务推荐 unless-stopped。Q 容器日志文件太大怎么办?
A Docker 默认日志驱动 json-file 不自动轮转,日志可能无限增长。启动时配置日志限制:
docker run --log-opt max-size=10m --log-opt max-file=3,限制单个日志文件 10 MB、最多保留 3 个文件。Q 怎么进入正在运行的容器?
A
docker exec -it <container> bash(或 sh)。这是最常用的调试方式。如果容器没有 bash,用 docker exec -it <container> sh。docker attach 也可以连接,但它连接的是主进程的 stdin,Ctrl+C 会停止容器,一般不用。Q 退出码 137 是什么意思?
A 137 = 128 + 9,其中 9 是 SIGKILL 的信号编号。容器被 OOM Killer 杀掉时退出码就是 137。其他常见退出码:0=正常退出,1=应用错误,2=误用命令,125=Docker 守护进程错误。
📖 小节
- 容器有六种状态:Created / Running / Paused / Stopped / Restarting / Dead
docker stop优雅关闭(SIGTERM),docker kill强制终止(SIGKILL)docker pause冻结进程保留内存,docker stop释放内存docker logs支持-f实时追踪、--since/--until时间过滤、--tail行数限制docker stats监控资源,docker top查看进程,docker inspect查看配置- 退出码 137 = OOM Kill,排查容器故障的关键线索
📝 作业
- 基础题(难度⭐):启动 Nginx 容器后用
docker stop停止,再用docker start重启,记录每次操作后docker ps -a显示的状态变化。 - 进阶题(难度⭐⭐):用
docker logs --tail 50 -f实时查看 Nginx 容器日志,在浏览器访问http://localhost:808010 次,观察日志中的请求记录。 - 挑战题(难度⭐⭐⭐):用
docker exec -it进入 Nginx 容器,修改/usr/share/nginx/html/index.html的内容,然后从浏览器访问确认修改生效。思考:容器删除后修改会保留吗?如何让修改持久化?