Shell脚本如何配置容器自动重启

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器自动重启

  1. Docker容器重启策略(推荐)
  2. Shell脚本实现自动重启
  3. 使用cron实现定时重启
  4. 使用systemd服务管理
  5. Docker Compose自动重启
  6. 最佳实践建议

在Shell脚本中配置容器自动重启,主要有以下几种方法:

Docker容器重启策略(推荐)

在运行容器时指定

# 总是重启
docker run --restart=always -d nginx
# 除非手动停止,否则总是重启
docker run --restart=unless-stopped -d nginx
# 退出码非0时重启(最多重试3次)
docker run --restart=on-failure:3 -d nginx
# 不自动重启(默认)
docker run --restart=no -d nginx

更新已存在容器的重启策略

docker update --restart=always container_name

Shell脚本实现自动重启

基础重启脚本

#!/bin/bash
# 监控并重启容器的脚本
CONTAINER_NAME="my-app"
MAX_RETRIES=5
RETRY_INTERVAL=10
restart_container() {
    echo "[$(date)] 尝试重启容器: $CONTAINER_NAME"
    # 停止并删除旧容器
    docker stop $CONTAINER_NAME 2>/dev/null
    docker rm $CONTAINER_NAME 2>/dev/null
    # 重新启动容器
    docker run -d --name $CONTAINER_NAME \
        --restart=unless-stopped \
        -p 8080:80 \
        nginx:latest
    # 检查是否启动成功
    if [ $? -eq 0 ]; then
        echo "[$(date)] 容器重启成功"
        return 0
    else
        echo "[$(date)] 容器重启失败"
        return 1
    fi
}
# 检查容器状态并重启
for ((i=1; i<=MAX_RETRIES; i++)); do
    if docker ps | grep -q $CONTAINER_NAME; then
        echo "[$(date)] 容器运行正常"
        break
    else
        echo "[$(date)] 容器未运行 (尝试 $i/$MAX_RETRIES)"
        restart_container
        if [ $? -eq 0 ]; then
            break
        fi
        sleep $RETRY_INTERVAL
    fi
done

带健康检查的重启脚本

#!/bin/bash
# 复杂重启脚本,包含健康检查
CONTAINER_NAME="my-app"
HEALTH_URL="http://localhost:8080/health"
RETRY_COUNT=3
RETRY_INTERVAL=5
check_health() {
    local response=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL)
    if [ "$response" == "200" ]; then
        return 0
    else
        return 1
    fi
}
restart_with_health_check() {
    echo "[$(date)] 开始重启流程..."
    # 停止旧容器
    docker-compose down --remove-orphans 2>/dev/null
    # 重新构建并启动
    docker-compose up -d --build
    # 等待服务启动
    sleep 10
    # 健康检查
    for ((i=1; i<=RETRY_COUNT; i++)); do
        if check_health; then
            echo "[$(date)] 服务健康检查通过"
            return 0
        fi
        echo "[$(date)] 健康检查失败 (尝试 $i/$RETRY_COUNT)"
        sleep $RETRY_INTERVAL
    done
    echo "[$(date)] 服务启动失败,健康检查未通过"
    return 1
}
# 主循环
while true; do
    if ! docker ps | grep -q $CONTAINER_NAME; then
        restart_with_health_check
    fi
    sleep 30  # 每30秒检查一次
done

使用cron实现定时重启

创建cron任务脚本

#!/bin/bash
# /usr/local/bin/docker-auto-restart.sh
CONTAINER_NAME=$1
RESTART_TIME=$(date +%H:%M)
log_message() {
    echo "[$(date)] $1" >> /var/log/docker-restart.log
}
# 重启指定容器
restart_specific_container() {
    local name=$1
    log_message "计划重启容器: $name"
    docker restart $name
    if [ $? -eq 0 ]; then
        log_message "容器 $name 重启成功"
    else
        log_message "容器 $name 重启失败"
    fi
}
# 重启所有运行中的容器
restart_all_containers() {
    log_message "开始计划重启所有容器"
    docker ps -q | while read container_id; do
        docker restart $container_id
        log_message "容器 $container_id 已重启"
    done
    log_message "所有容器重启完成"
}
# 根据参数执行
case "$1" in
    all)
        restart_all_containers
        ;;
    *)
        if [ -n "$CONTAINER_NAME" ]; then
            restart_specific_container $CONTAINER_NAME
        else
            echo "用法: $0 {container_name|all}"
            exit 1
        fi
        ;;
esac

配置crontab

# 编辑crontab
crontab -e
# 添加以下规则:
# 每天凌晨2点重启特定容器
0 2 * * * /usr/local/bin/docker-auto-restart.sh my-app
# 每6小时重启所有容器
0 */6 * * * /usr/local/bin/docker-auto-restart.sh all
# 每天早上6点和下午6点重启
0 6,18 * * * /usr/local/bin/docker-auto-restart.sh my-app

使用systemd服务管理

创建systemd服务文件

# /etc/systemd/system/docker-monitor.service
[Unit]
Description=Docker Container Monitor and Auto Restart
After=docker.service
Requires=docker.service
[Service]
Type=simple
ExecStart=/usr/local/bin/docker-monitor.sh
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target

创建监控脚本

#!/bin/bash
# /usr/local/bin/docker-monitor.sh
# 监控的容器列表
CONTAINERS=("nginx" "mysql" "redis")
while true; do
    for container in "${CONTAINERS[@]}"; do
        if ! docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
            echo "[$(date)] 容器 $container 未运行,尝试重启..."
            docker start $container 2>/dev/null || docker run -d --name $container $container:latest
        fi
    done
    sleep 60
done

Docker Compose自动重启

docker-compose.yml配置

version: '3.8'
services:
  web:
    image: nginx:latest
    restart: always  # 自动重启策略
    ports:
      - "8080:80"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
  app:
    build: .
    restart: unless-stopped
    depends_on:
      - db
    environment:
      - DB_HOST=db
  db:
    image: mysql:8.0
    restart: on-failure:5  # 最多重启5次
    environment:
      MYSQL_ROOT_PASSWORD: password

最佳实践建议

  1. 使用Docker原生重启策略:优先使用 --restart=unless-stopped
  2. 添加健康检查:避免容器启动失败但进程仍在运行
  3. 设置重试限制:防止无限重启导致资源浪费
  4. 记录日志:记录重启事件便于排查问题
  5. 监控和告警:配置监控系统及时发现重启异常

选择哪种方法取决于你的具体需求和环境复杂度。

抱歉,评论功能暂时关闭!