内置重启策略种类
Docker提供了四种重启策略:
no
- 默认策略,容器退出后不会自动重启always
- 无论容器因何原因退出,都会尝试自动重启on-failure
- 仅当容器以非零状态码退出时(即异常退出)才会重启unless-stopped
- 除非容器被明确停止(如使用docker stop
命令),否则总是重启容器
重启策略触发时机
Docker的重启策略会在以下情况下起作用:
1. 容器内部进程退出
- 当容器中的主进程(PID 1)终止时,根据设置的重启策略决定是否重启容器
- 例如:应用程序崩溃、内存溢出、进程被意外终止等情况
2. Docker守护进程重启
- 当Docker守护进程(dockerd)本身重启时
always
和unless-stopped
策略的容器会在Docker守护进程重启后自动启动on-failure
策略的容器不会因Docker守护进程重启而自动启动
3. 系统重启
- 当安装Docker的主机系统重启时
- 如果Docker服务设置为开机自启,则
always
和unless-stopped
策略的容器会随Docker服务启动而启动
4. 资源限制导致容器被杀死
- 当容器因OOM(内存不足)被系统终止时
- 将根据重启策略决定是否重启容器
主进程是如何被定义的?
在Docker容器中,主进程指的是在容器内运行的PID(Process ID)为1的进程。这个进程有着特殊的地位和重要性。
Docker容器中的主进程通常由以下方式确定:
1. 通过Dockerfile的CMD或ENTRYPOINT指令
# 使用CMD指令设置主进程
CMD ["nginx", "-g", "daemon off;"]
# 或者使用ENTRYPOINT指令
ENTRYPOINT ["java", "-jar", "app.jar"]
当两者同时存在时,ENTRYPOINT定义基本命令,CMD提供默认参数。
2. 通过docker run命令覆盖
# 覆盖默认的CMD
docker run myimage /bin/bash
# 覆盖默认的ENTRYPOINT
docker run --entrypoint /bin/sh myimage
主进程(PID 1)的特殊性
在Docker容器中,主进程具有几个重要特性:
- 信号处理责任:PID 1需要正确处理Unix信号(如SIGTERM),否则容器可能无法优雅关闭
- 僵尸进程回收:负责”收养”并清理容器内的僵尸进程(zombie processes)
- 容器生命周期:主进程退出意味着整个容器停止
- 当PID 1退出时,Docker会根据重启策略决定是否重启容器
- 主进程的退出状态码决定容器是否被视为正常退出
- 健康检查:健康检查通常针对主进程提供的服务进行监控
常见的错误设置
1.使用shell形式而非exec形式:
# 错误方式(shell形式) - /bin/sh成为PID 1
CMD nginx -g "daemon off;"
# 正确方式(exec形式) - nginx成为PID 1
CMD ["nginx", "-g", "daemon off;"]
2.使用非守护进程工具作为入口点:
# 不具备信号处理能力的脚本作为PID 1
CMD ["start.sh"]
健康检查
Docker 健康检查
# 定义健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1
Shell 脚本
#!/bin/bash
set -e
# 启动您的服务并放入后台
your-service &
SERVICE_PID=$!
# 监控服务
while true; do
if ! kill -0 $SERVICE_PID 2>/dev/null; then
echo "服务已停止,正在重启..."
your-service &
SERVICE_PID=$!
fi
sleep 5
done