Shell脚本如何重载容器配置不重启

wen 实用脚本 2

本文目录导读:

Shell脚本如何重载容器配置不重启

  1. 使用SIGHUP信号(推荐)
  2. 通过docker exec执行重载命令
  3. 脚本化重载函数
  4. 结合健康检查的重载脚本
  5. 配置文件热更新的完整流程
  6. 支持多种容器编排工具
  7. 注意事项

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

使用SIGHUP信号(推荐)

大多数支持热重载的服务(如Nginx、HAProxy、Systemd服务)都支持SIGHUP信号:

#!/bin/bash
# 向容器发送SIGHUP信号
docker kill --signal=HUP container_name
# 或者使用更具体的PID
docker exec container_name kill -HUP 1
# 示例:重载Nginx配置
docker kill --signal=HUP nginx-container

通过docker exec执行重载命令

#!/bin/bash
# Nginx重载
docker exec nginx-container nginx -s reload
# Apache重载
docker exec apache-container apachectl graceful
# HAProxy重载
docker exec haproxy-container haproxy -f /usr/local/etc/haproxy/haproxy.cfg -sf $(pidof haproxy)
# Systemd服务重载
docker exec systemd-container systemctl reload nginx

脚本化重载函数

#!/bin/bash
# 重载函数定义
reload_container() {
    local container_name=$1
    local service_type=$2
    case $service_type in
        nginx)
            docker exec $container_name nginx -s reload
            ;;
        apache)
            docker exec $container_name apachectl graceful
            ;;
        haproxy)
            docker exec $container_name haproxy -f /etc/haproxy/haproxy.cfg -sf $(docker exec $container_name pidof haproxy)
            ;;
        *)
            docker kill --signal=HUP $container_name
            ;;
    esac
    echo "Container $container_name reloaded successfully"
}
# 使用示例
reload_container "web-server" "nginx"
reload_container "proxy" "haproxy"

结合健康检查的重载脚本

#!/bin/bash
reload_with_health_check() {
    local container=$1
    local reload_cmd=$2
    local health_check_cmd=$3
    local max_retries=5
    local retry_interval=2
    # 执行重载
    echo "Reloading $container..."
    docker exec $container sh -c "$reload_cmd"
    # 健康检查
    for ((i=1; i<=max_retries; i++)); do
        if docker exec $container sh -c "$health_check_cmd"; then
            echo "Health check passed"
            return 0
        fi
        echo "Health check attempt $i failed, retrying in ${retry_interval}s..."
        sleep $retry_interval
    done
    echo "Health check failed after $max_retries attempts"
    return 1
}
# Nginx示例
reload_with_health_check \
    "nginx-container" \
    "nginx -s reload" \
    "nginx -t"
# Apache示例
reload_with_health_check \
    "apache-container" \
    "apachectl graceful" \
    "curl -f http://localhost/health"

配置文件热更新的完整流程

#!/bin/bash
# 配置文件热更新脚本
update_and_reload() {
    local container=$1
    local config_path=$2
    local local_config=$3
    local reload_cmd=$4
    local backup_dir="/tmp/config_backups"
    # 创建备份目录
    mkdir -p $backup_dir
    # 备份当前配置
    timestamp=$(date +%Y%m%d_%H%M%S)
    docker cp $container:$config_path $backup_dir/${container}_config_$timestamp
    # 复制新配置到容器
    docker cp $local_config $container:$config_path
    # 测试配置
    if docker exec $container sh -c "nginx -t" > /dev/null 2>&1; then
        echo "配置验证通过,执行重载..."
        docker exec $container sh -c "$reload_cmd"
        echo "重载成功"
    else
        echo "配置验证失败,回滚配置..."
        docker cp $backup_dir/${container}_config_$timestamp $container:$config_path
        return 1
    fi
}
# 使用示例
update_and_reload \
    "web-nginx" \
    "/etc/nginx/nginx.conf" \
    "./nginx_new.conf" \
    "nginx -s reload"

支持多种容器编排工具

#!/bin/bash
# Docker Compose重载
docker_compose_reload() {
    local service_name=$1
    # 发送SIGHUP信号
    docker-compose kill -s HUP $service_name
    # 或执行重载命令
    docker-compose exec $service_name nginx -s reload
}
# Kubernetes重载
k8s_reload() {
    local deployment=$1
    local namespace=$2
    # 获取pod
    pod=$(kubectl get pods -n $namespace -l app=$deployment -o jsonpath='{.items[0].metadata.name}')
    # 执行重载
    kubectl exec -n $namespace $pod -- nginx -s reload
}
# 使用
docker_compose_reload "web"
k8s_reload "nginx-deployment" "production"

注意事项

  1. 确保容器内服务支持热重载:不是所有服务都支持,如MySQL需要特殊处理
  2. 配置验证:重载前验证配置语法正确性
  3. 监控和日志:记录重载操作和可能的错误
  4. 回滚机制:保留旧配置以便回滚
  5. 信号处理:了解不同服务支持的重载信号

这些方法可以零停机更新容器配置,适用于生产环境。

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