容器生命周期 #
容器状态详解 #
状态类型 #
text
┌─────────────────────────────────────────────────────┐
│ 容器状态类型 │
├─────────────────────────────────────────────────────┤
│ │
│ created - 已创建,未启动 │
│ running - 正在运行 │
│ paused - 已暂停 │
│ restarting - 正在重启 │
│ exiting - 正在退出 │
│ exited - 已退出 │
│ dead - 已死亡 │
│ removing - 正在删除 │
│ │
└─────────────────────────────────────────────────────┘
状态转换图 #
text
┌──────────────┐
│ created │
└──────┬───────┘
│ start
↓
┌──────────────┐
unpause ──→│ running │←── start
└──────┬───────┘
│
┌────────────┼────────────┐
│ pause │ │ stop/kill
↓ │ ↓
┌──────────────┐ │ ┌──────────────┐
│ paused │ │ │ stopped │
└──────────────┘ │ └──────┬───────┘
│ │
│ │ rm
│ ↓
│ ┌──────────────┐
└────→│ removed │
└──────────────┘
查看容器状态 #
bash
# 查看所有容器状态
docker ps -a --format "table {{.Names}}\t{{.Status}}"
# 查看特定状态容器
docker ps --filter "status=running"
docker ps --filter "status=exited"
docker ps --filter "status=paused"
# 查看容器详细状态
docker inspect --format '{{.State.Status}}' mycontainer
docker inspect --format '{{json .State}}' mycontainer | jq
重启策略 #
策略类型 #
| 策略 | 说明 |
|---|---|
| no | 不自动重启(默认) |
| on-failure[:max-retries] | 退出状态非0时重启 |
| always | 总是重启 |
| unless-stopped | 除非手动停止,否则总是重启 |
配置重启策略 #
bash
# no - 不自动重启
docker run --restart=no nginx
# on-failure - 退出状态非0时重启
docker run --restart=on-failure nginx
# on-failure - 最多重启5次
docker run --restart=on-failure:5 nginx
# always - 总是重启
docker run --restart=always nginx
# unless-stopped - 除非手动停止
docker run --restart=unless-stopped nginx
更新重启策略 #
bash
# 更新运行中容器的重启策略
docker update --restart=always mycontainer
# 更新多个容器
docker update --restart=unless-stopped container1 container2
重启策略对比 #
text
┌─────────────────────────────────────────────────────────────────┐
│ 重启策略对比 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 场景: 容器退出 │
│ │
│ ┌─────────────┬──────────┬──────────┬───────────────────────┐ │
│ │ 策略 │ 手动停止 │ 崩溃退出 │ Docker服务重启 │ │
│ ├─────────────┼──────────┼──────────┼───────────────────────┤ │
│ │ no │ 不重启 │ 不重启 │ 不重启 │ │
│ │ on-failure │ 不重启 │ 重启 │ 重启(如果之前在运行) │ │
│ │ always │ 不重启 │ 重启 │ 重启 │ │
│ │ unless-stop │ 不重启 │ 重启 │ 重启(除非手动停止过) │ │
│ └─────────────┴──────────┴──────────┴───────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
健康检查 #
Dockerfile中定义 #
dockerfile
# 基本健康检查
HEALTHCHECK CMD curl -f http://localhost/ || exit 1
# 完整配置
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# 禁用健康检查
HEALTHCHECK NONE
参数说明 #
| 参数 | 默认值 | 说明 |
|---|---|---|
| –interval | 30s | 检查间隔 |
| –timeout | 30s | 超时时间 |
| –start-period | 0s | 启动等待时间 |
| –retries | 3 | 重试次数 |
运行时配置 #
bash
# 运行时添加健康检查
docker run -d \
--name mycontainer \
--health-cmd="curl -f http://localhost:8080/health || exit 1" \
--health-interval=30s \
--health-timeout=3s \
--health-retries=3 \
--health-start-period=10s \
myapp:v1.0
# 禁用健康检查
docker run --no-healthcheck myapp:v1.0
查看健康状态 #
bash
# 查看容器健康状态
docker inspect --format '{{.State.Health.Status}}' mycontainer
# 查看健康检查结果
docker inspect --format '{{json .State.Health}}' mycontainer | jq
# 查看最近一次健康检查
docker inspect --format '{{range .State.Health.Log}}{{.Output}}{{end}}' mycontainer
健康状态类型 #
text
┌─────────────────────────────────────────────────────┐
│ 健康状态 │
├─────────────────────────────────────────────────────┤
│ │
│ starting - 容器启动中,等待start-period │
│ healthy - 健康检查通过 │
│ unhealthy - 健康检查失败 │
│ none - 未配置健康检查 │
│ │
└─────────────────────────────────────────────────────┘
退出状态码 #
常见退出状态码 #
| 状态码 | 说明 |
|---|---|
| 0 | 正常退出 |
| 1 | 应用错误 |
| 125 | Docker错误 |
| 126 | 命令无法执行 |
| 127 | 命令未找到 |
| 137 | 被SIGKILL终止(内存不足) |
| 139 | 被SIGSEGV终止(段错误) |
| 143 | 被SIGTERM终止 |
查看退出状态码 #
bash
# 查看容器退出状态码
docker inspect --format '{{.State.ExitCode}}' mycontainer
# 查看OOM状态
docker inspect --format '{{.State.OOMKilled}}' mycontainer
# 查看完整状态信息
docker inspect --format '{{json .State}}' mycontainer | jq
容器事件监控 #
docker events #
bash
# 实时监控容器事件
docker events
# 过滤特定事件
docker events --filter "type=container"
docker events --filter "event=start"
docker events --filter "event=stop"
docker events --filter "container=mycontainer"
# 指定时间范围
docker events --since "2024-01-01"
docker events --since "1h"
docker events --until "2024-01-02"
# 格式化输出
docker events --format '{{.Time}} {{.Type}} {{.Action}} {{.Actor.ID}}'
事件类型 #
text
┌─────────────────────────────────────────────────────┐
│ 容器事件类型 │
├─────────────────────────────────────────────────────┤
│ │
│ attach - 附加到容器 │
│ commit - 提交镜像 │
│ copy - 复制文件 │
│ create - 创建容器 │
│ destroy - 删除容器 │
│ detach - 分离容器 │
│ die - 容器退出 │
│ exec_create - 创建exec │
│ exec_start - 启动exec │
│ export - 导出容器 │
│ kill - 杀死容器 │
│ oom - 内存溢出 │
│ pause - 暂停容器 │
│ rename - 重命名容器 │
│ restart - 重启容器 │
│ start - 启动容器 │
│ stop - 停止容器 │
│ top - 查看进程 │
│ unpause - 恢复容器 │
│ update - 更新容器 │
│ │
└─────────────────────────────────────────────────────┘
容器等待 #
docker wait #
等待容器退出并返回退出状态码。
bash
# 等待容器退出
docker wait mycontainer
# 等待多个容器
docker wait container1 container2
# 在脚本中使用
exit_code=$(docker wait mycontainer)
echo "Container exited with code: $exit_code"
容器更新 #
docker update #
更新运行中容器的配置。
bash
# 更新资源限制
docker update --cpus=1.5 --memory=512m mycontainer
# 更新重启策略
docker update --restart=always mycontainer
# 更新环境变量(需要重建)
docker update --env-add NEW_VAR=value mycontainer
# 更新多个容器
docker update --cpus=1 container1 container2 container3
生命周期钩子 #
使用脚本处理生命周期 #
bash
#!/bin/bash
# container-lifecycle.sh
# 启动前钩子
pre_start() {
echo "Preparing to start container..."
# 执行初始化操作
}
# 启动后钩子
post_start() {
echo "Container started, waiting for health check..."
# 等待健康检查通过
until [ "$(docker inspect --format='{{.State.Health.Status}}' mycontainer)" == "healthy" ]; do
sleep 1
done
echo "Container is healthy!"
}
# 停止前钩子
pre_stop() {
echo "Preparing to stop container..."
# 执行清理操作
}
# 停止后钩子
post_stop() {
echo "Container stopped"
# 执行后处理
}
# 主流程
case "$1" in
start)
pre_start
docker start mycontainer
post_start
;;
stop)
pre_stop
docker stop mycontainer
post_stop
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
;;
esac
最佳实践 #
1. 使用合适的重启策略 #
bash
# 生产环境服务
docker run --restart=unless-stopped myapp
# 批处理任务
docker run --restart=on-failure:3 batch-job
# 开发环境
docker run --restart=no dev-app
2. 配置健康检查 #
dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
3. 优雅关闭 #
dockerfile
# 设置停止信号
STOPSIGNAL SIGTERM
# 设置停止超时
# 在docker run时使用 --stop-timeout
bash
# 设置停止超时
docker stop --time=30 mycontainer
4. 监控容器状态 #
bash
#!/bin/bash
# monitor-containers.sh
while true; do
# 检查容器状态
status=$(docker inspect --format='{{.State.Status}}' mycontainer)
if [ "$status" != "running" ]; then
echo "Container is not running: $status"
# 发送告警或自动恢复
fi
# 检查健康状态
health=$(docker inspect --format='{{.State.Health.Status}}' mycontainer 2>/dev/null)
if [ "$health" == "unhealthy" ]; then
echo "Container is unhealthy!"
# 发送告警或自动恢复
fi
sleep 60
done
小结 #
本节学习了Docker容器的生命周期管理:
- 容器状态类型和转换
- 重启策略配置
- 健康检查配置
- 退出状态码
- 容器事件监控
下一步 #
接下来,让我们学习 容器资源限制,了解如何限制容器的资源使用。