Skip to content

容器生命周期

生命周期状态

Docker 容器有以下几种状态:

                    ┌─────────┐
         docker run │         │
    ┌───────────────▶ running ◀───────────────┐
    │               │         │               │
    │               └────┬────┘               │
    │                    │                    │
    │             stop / kill          docker start
    │                    │                    │
    │               ┌────▼────┐               │
    │               │ exited  ├───────────────┘
    │               │(stopped)│
    │               └────┬────┘
    │                    │
    │                 docker rm
    │                    │
    │               ┌────▼────┐
    │               │ removed │
    │               └─────────┘

    │               ┌─────────┐
    └───────────────│ created │
      docker create │         │
                    └─────────┘

    running → paused(docker pause)
    paused  → running(docker unpause)
状态说明
created容器已创建但未启动
running容器正在运行
paused容器进程被暂停(冻结)
restarting容器正在重启
exited容器已停止,退出码表示结束原因
dead容器无法被删除(极少见)
removing容器正在被删除

查看容器状态

bash
# 查看所有容器及状态
docker ps -a

# 过滤指定状态的容器
docker ps -a --filter "status=exited"
docker ps -a --filter "status=running"
docker ps -a --filter "status=created"

# 查看容器详细状态信息
docker inspect my-container --format '{{.State.Status}}'
docker inspect my-container --format '{{.State.ExitCode}}'

容器退出码

退出码(Exit Code)表示容器主进程退出的原因:

退出码含义
0正常退出
1应用程序错误
125Docker 守护进程错误
126命令不可执行
127命令未找到
130收到 SIGINT(Ctrl+C)
137收到 SIGKILL(OOM 或 docker kill
143收到 SIGTERM(docker stop
bash
# 查看容器退出码
docker inspect my-container --format '{{.State.ExitCode}}'

# 查看容器完整状态
docker inspect my-container --format '{{json .State}}' | python3 -m json.tool

容器停止行为

docker stop vs docker kill

bash
# docker stop:优雅停止
# 先发送 SIGTERM,等待 10 秒(默认),然后发送 SIGKILL
docker stop my-container

# 自定义等待时间(秒)
docker stop -t 30 my-container

# docker kill:立即强制终止
# 直接发送 SIGKILL,容器立即停止
docker kill my-container

# 发送指定信号
docker kill --signal SIGINT my-container

信号处理最佳实践

容器内的应用应该正确处理 SIGTERM 信号,以便优雅退出:

javascript
// Node.js 优雅退出示例
process.on('SIGTERM', () => {
  console.log('Received SIGTERM, shutting down gracefully...');
  server.close(() => {
    process.exit(0);
  });
});
python
# Python 优雅退出示例
import signal
import sys

def signal_handler(sig, frame):
    print('Shutting down gracefully...')
    sys.exit(0)

signal.signal(signal.SIGTERM, signal_handler)

容器重启策略详解

配置重启策略

bash
# 创建时指定重启策略
docker run -d --restart unless-stopped nginx

# 更新已有容器的重启策略
docker update --restart always my-container

# 查看当前重启策略
docker inspect my-container --format '{{.HostConfig.RestartPolicy.Name}}'

重启策略对比

策略Docker 重启后手动 stop 后异常退出后
no不重启不重启不重启
always重启重启重启
unless-stopped重启不重启重启
on-failure不重启(若正常退出)不重启重启

生产环境推荐使用 unless-stopped,这样手动停止的容器不会自动恢复,而异常退出和 Docker 重启后容器能自动恢复。

容器资源使用监控

bash
# 实时监控所有容器资源
docker stats

# 监控指定容器
docker stats my-nginx my-mysql

# 单次快照(不持续刷新)
docker stats --no-stream

# 自定义输出格式
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"

输出说明:

NAME       CPU %   MEM USAGE / LIMIT   MEM %   NET I/O         BLOCK I/O
my-nginx   0.01%   5.6MiB / 7.7GiB    0.07%   1.2kB / 648B    0B / 0B

容器健康检查

Docker 支持为容器配置健康检查,定期检测容器内应用是否正常:

bash
# 运行时添加健康检查
docker run -d \
  --health-cmd "curl -f http://localhost/ || exit 1" \
  --health-interval 30s \
  --health-timeout 10s \
  --health-retries 3 \
  --health-start-period 40s \
  nginx

健康状态:

  • starting:容器刚启动,健康检查未完成首次检查
  • healthy:健康检查通过
  • unhealthy:健康检查失败超过重试次数
bash
# 查看容器健康状态
docker inspect my-container --format '{{.State.Health.Status}}'

# 查看健康检查历史
docker inspect my-container --format '{{json .State.Health}}' | python3 -m json.tool

在 Dockerfile 中定义健康检查:

dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
  CMD curl -f http://localhost/ || exit 1

事件监听

bash
# 监听 Docker 事件(实时)
docker events

# 过滤容器事件
docker events --filter type=container

# 过滤指定容器的事件
docker events --filter container=my-nginx

# 查看过去 1 小时的事件
docker events --since 1h

总结

理解容器生命周期对于排查问题和运维管理非常重要:

  1. 容器有 createdrunningpausedexited 等状态
  2. 退出码帮助判断容器退出原因(0 正常,非 0 异常)
  3. docker stop 优雅停止,docker kill 强制终止
  4. 合理配置重启策略确保服务高可用
  5. 健康检查让容器状态更可观测

下一节将介绍数据卷的使用,解决容器数据持久化问题。