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. 容器六种状态

容器从创建到删除,经历六种状态的转换。

100%
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> shdocker attach 也可以连接,但它连接的是主进程的 stdin,Ctrl+C 会停止容器,一般不用。
Q 退出码 137 是什么意思?
A 137 = 128 + 9,其中 9 是 SIGKILL 的信号编号。容器被 OOM Killer 杀掉时退出码就是 137。其他常见退出码:0=正常退出,1=应用错误,2=误用命令,125=Docker 守护进程错误。

📖 小节


📝 作业

  1. 基础题(难度⭐):启动 Nginx 容器后用 docker stop 停止,再用 docker start 重启,记录每次操作后 docker ps -a 显示的状态变化。
  2. 进阶题(难度⭐⭐):用 docker logs --tail 50 -f 实时查看 Nginx 容器日志,在浏览器访问 http://localhost:8080 10 次,观察日志中的请求记录。
  3. 挑战题(难度⭐⭐⭐):用 docker exec -it 进入 Nginx 容器,修改 /usr/share/nginx/html/index.html 的内容,然后从浏览器访问确认修改生效。思考:容器删除后修改会保留吗?如何让修改持久化?
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏