基础 深入理解容器从创建到删除的完整生命周期,掌握容器管理的核心操作
容器的生命周期是从 docker create 到 docker rm 的完整过程。理解每个状态转换是管理容器的关键:
| 状态 | 说明 | 触发命令 | CPU/内存 |
|---|---|---|---|
created | 已创建但未启动 | docker create | 不占用 |
running | 正在运行 | docker start/run | 占用 |
paused | 暂停(冻结) | docker pause | 内存占用,CPU释放 |
stopped | 已停止 | docker stop/kill | 不占用 |
restarting | 重启中 | 重启策略触发 | 切换中 |
dead | 无法删除的异常状态 | 系统错误 | 可能泄漏 |
docker create 只创建容器不启动,适合需要预配置的场景:
# 创建容器(不启动)
docker create --name my-nginx -p 8081:80 nginx:alpine
# 输出容器ID:a1b2c3d4e5f6...
# 查看状态——Created
docker ps -a --filter name=my-nginx
# STATUS: Created
# 启动已创建的容器
docker start my-nginx
# my-nginx
# 确认运行
docker ps --filter name=my-nginx
# STATUS: Up 2 seconds
docker run = docker create + docker start。两步法的优势在于可以在启动前修改容器配置。
# 交互式运行(进入容器)
docker run -it --name my-alpine alpine:latest /bin/sh
# 后台运行
docker run -d --name my-redis -p 6379:6379 redis:alpine
# 运行后自动删除
docker run --rm alpine:latest echo "Hello Docker"
# 设置主机名和域名
docker run -d --name my-app \
--hostname app-server \
--dns 8.8.8.8 \
nginx:alpine
# 指定重启策略
docker run -d --name my-api \
--restart=on-failure:5 \
-p 3000:3000 \
node:20-alpine
| 策略 | 行为 | 适用场景 |
|---|---|---|
no | 不自动重启(默认) | 临时任务、一次性命令 |
on-failure[:max] | 非零退出时重启 | 可能临时失败的服务 |
always | 总是重启,包括Docker启动时 | 核心服务 |
unless-stopped | 类似always,但手动stop后不随Docker启动 | 可维护的服务 |
docker pause 使用 Linux cgroups freezer 冻结容器内所有进程,不停止容器:
# 运行一个CPU密集型容器
docker run -d --name cpu-worker alpine:latest \
sh -c "while true; do echo working; done"
# 查看CPU使用
docker stats cpu-worker --no-stream
# CPU %: 80-100%
# 暂停容器
docker pause cpu-worker
# cpu-worker
# 再次查看——CPU为0
docker stats cpu-worker --no-stream
# CPU %: 0.00%
# 状态变为Paused
docker inspect cpu-worker --format '{{.State.Status}}'
# paused
# 恢复容器
docker unpause cpu-worker
# cpu-worker
pause vs stop:暂停保留内存中的进程状态(类似"冻结"),恢复后程序从中断处继续;停止则发送 SIGTERM,进程优雅退出,内存释放。
# 优雅停止:发送SIGTERM,等待10秒后SIGKILL
docker stop my-nginx
# my-nginx
# 自定义超时时间(30秒)
docker stop -t 30 my-redis
# 立即发送SIGKILL
docker kill my-nginx
# my-nginx
# 发送自定义信号
docker kill --signal=SIGHUP my-nginx
| 特性 | docker stop | docker kill |
|---|---|---|
| 信号 | SIGTERM → (等待) → SIGKILL | SIGKILL(默认) |
| 优雅退出 | ✅ 给应用清理时间 | ❌ 立即终止 |
| 超时 | 默认10秒可配置 | 无 |
| 数据安全 | 应用可保存状态 | 可能丢失未写入数据 |
| 适用场景 | 日常运维 | 容器无响应时 |
# 重启 = stop + start
docker restart my-nginx
# my-nginx
# 带超时重启
docker restart -t 15 my-nginx
# 查看重启次数
docker inspect my-nginx --format '{{.RestartCount}}'
# 0
# 删除已停止的容器
docker rm my-nginx
# my-nginx
# 强制删除运行中的容器(先kill再rm)
docker rm -f my-redis
# 删除时清理匿名卷
docker rm -v my-nginx
# 批量删除所有已停止容器
docker container prune
# WARNING! This will remove all stopped containers.
# 删除所有容器(包括运行中)
docker rm -f $(docker ps -aq)
docker rm -f 会强制终止运行中的容器,可能导致数据丢失。生产环境应先 docker stop 再 docker rm。
# 查看容器完整状态
docker inspect my-nginx
# 提取特定字段
docker inspect my-nginx --format '{{.State.Status}}'
docker inspect my-nginx --format '{{.State.StartedAt}}'
docker inspect my-nginx --format '{{.State.ExitCode}}'
docker inspect my-nginx --format '{{.NetworkSettings.IPAddress}}'
# 查看容器进程
docker top my-nginx
# UID PID PPID C STIME TTY TIME CMD
# root 1234 567 0 10:30 ? 00:00:00 nginx: master process
# 查看资源使用
docker stats my-nginx --no-stream
# CONTAINER NAME CPU% MEM USAGE / LIMIT MEM%
# a1b2c3d4 my-nginx 0.01% 2.1MiB / 1.94GiB 0.11%
# 实时监听容器事件
docker events --filter type=container
# 按时间范围查询
docker events --since "2024-01-01" --until "2024-01-02"
# 过滤特定容器
docker events --filter container=my-nginx
让我们用一个Web应用体验完整的容器生命周期:
# 1. 创建容器
docker create --name lifecycle-demo \
-p 8082:80 \
--restart=unless-stopped \
nginx:alpine
# ✅ 验证通过:容器已创建
# 2. 启动容器
docker start lifecycle-demo
# ✅ 验证通过:容器运行中
# 3. 验证服务可访问
curl -s -o /dev/null -w "%{http_code}" http://localhost:8082
# 200 ✅ 验证通过
# 4. 查看运行状态
docker ps --filter name=lifecycle-demo --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# NAMES STATUS PORTS
# lifecycle-demo Up 10 seconds 0.0.0.0:8082->80/tcp
# 5. 暂停容器
docker pause lifecycle-demo
curl -s -o /dev/null -w "%{http_code}" http://localhost:8082
# 000 (连接被拒绝) ✅ 暂停后服务不可用
# 6. 恢复容器
docker unpause lifecycle-demo
curl -s -o /dev/null -w "%{http_code}" http://localhost:8082
# 200 ✅ 恢复后服务可用
# 7. 优雅停止
docker stop lifecycle-demo
docker ps -a --filter name=lifecycle-demo --format "{{.Status}}"
# Exited (0) 5 seconds ago ✅ 正常退出
# 8. 重新启动
docker start lifecycle-demo
# lifecycle-demo ✅ 验证通过
# 9. 清理
docker stop lifecycle-demo && docker rm lifecycle-demo
# lifecycle-demo ✅ 验证通过
容器启动后立即退出(Exit Code 0)前台进程结束导致容器退出。确保Dockerfile中使用
CMD 或 ENTRYPOINT 以前台模式运行,或用 docker run -it 交互运行调试。
容器 Exit Code 137容器被 SIGKILL 终止,通常是内存不足(OOM Killer)或被
docker kill。检查 dmesg | grep -i oom 和 docker inspect --format '{{.State.OOMKilled}}'。
容器 Exit Code 1应用错误退出。使用
docker logs <container> 查看日志定位问题。
无法删除容器("container is paused")先
docker unpause 再 docker rm,或使用 docker rm -f 强制删除。
# 查看退出码
docker inspect <container> --format '{{.State.ExitCode}}'
# 查看完整日志
docker logs --tail 100 <container>
# 进入运行中容器
docker exec -it <container> /bin/sh
# 查看容器变更(相对镜像的文件系统变化)
docker diff <container>
# 查看容器资源限制
docker inspect <container> --format '{{.HostConfig.Memory}}'
--restart=no、--restart=on-failure、--restart=always 创建容器,手动停止后重启Docker服务,观察哪些容器自动启动docker run --rm alpine sh -c "exit 42"
docker ps -a --filter "exited=42"
docker stats 实时监控其CPU和内存使用