Shell脚本如何配置容器负载均衡

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器负载均衡

  1. 使用 Nginx 反向代理
  2. 使用 HAProxy
  3. 使用 Docker Swarm 原生负载均衡
  4. 动态DNS负载均衡
  5. 完整自动化脚本
  6. 使用建议

在Shell脚本中配置容器负载均衡通常涉及以下步骤,我将介绍几种主流方案:

使用 Nginx 反向代理

基础配置示例

#!/bin/bash
# 容器负载均衡配置脚本
NGINX_CONF="/etc/nginx/conf.d/load_balancer.conf"
# 容器列表
CONTAINERS=(
    "app1:8081"
    "app2:8082" 
    "app3:8083"
)
# 生成负载均衡配置
cat > ${NGINX_CONF} << EOF
upstream app_backend {
    # 负载均衡算法: least_conn/ip_hash/weight
    least_conn;
    $(for container in "${CONTAINERS[@]}"; do
        IFS=':' read -r name port <<< "${container}"
        echo "    server 127.0.0.1:${port} weight=3 max_fails=3 fail_timeout=30s;"
    done)
}
server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://app_backend;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        # 健康检查
        health_check interval=5s fails=3 passes=2;
    }
}
EOF
# 重新加载Nginx
nginx -t && nginx -s reload

使用 HAProxy

动态配置脚本

#!/bin/bash
HAPROXY_CONF="/etc/haproxy/haproxy.cfg"
# 从Docker获取容器IP列表
get_container_ips() {
    local service_name=$1
    docker ps --filter "name=${service_name}" --format "{{.Names}}" | \
    while read container; do
        docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $container
    done
}
# 生成HAProxy配置
generate_haproxy_config() {
    cat > ${HAPROXY_CONF} << 'EOF'
global
    daemon
    maxconn 256
defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
frontend http-in
    bind *:80
    default_backend app_servers
backend app_servers
    balance roundrobin
    option httpchk GET /health
    http-check expect status 200
EOF
    # 动态添加后端服务器
    for ip in $(get_container_ips "webapp"); do
        echo "    server container-${ip} ${ip}:80 check" >> ${HAPROXY_CONF}
    done
}
# 重启HAProxy
generate_haproxy_config
haproxy -f ${HAPROXY_CONF} -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)

使用 Docker Swarm 原生负载均衡

自动发现脚本

#!/bin/bash
# Docker Swarm负载均衡配置
SERVICE_NAME="webapp"
NETWORK_NAME="app_network"
# 创建覆盖网络
docker network create --driver overlay ${NETWORK_NAME}
# 部署服务并自动负载均衡
docker service create \
    --name ${SERVICE_NAME} \
    --network ${NETWORK_NAME} \
    --replicas 3 \
    --publish 80:80 \
    --update-delay 10s \
    --update-parallelism 2 \
    --health-cmd "curl -f http://localhost/health || exit 1" \
    --health-interval 5s \
    --health-retries 3 \
    nginx:alpine
# 配置服务更新策略
docker service update \
    --env-add "MAX_CONNECTIONS=1000" \
    --limit-cpu 0.5 \
    --limit-memory 512M \
    ${SERVICE_NAME}
echo "Service ${SERVICE_NAME} deployed with load balancing"

动态DNS负载均衡

Consul + Nginx自动注册

#!/bin/bash
CONSUL_SERVER="localhost:8500"
NGINX_CONF="/etc/nginx/conf.d/consul_backend.conf"
SERVICE_NAME="myapp"
# 注册服务到Consul
register_service() {
    local container_name=$1
    local container_port=$2
    curl -X PUT \
        -d "{
            \"Name\": \"${SERVICE_NAME}\",
            \"Address\": \"${container_name}\",
            \"Port\": ${container_port},
            \"Check\": {
                \"HTTP\": \"http://${container_name}:${container_port}/health\",
                \"Interval\": \"10s\"
            }
        }" \
        http://${CONSUL_SERVER}/v1/agent/service/register
}
# 从Consul获取健康实例
get_healthy_instances() {
    curl -s http://${CONSUL_SERVER}/v1/health/service/${SERVICE_NAME}?passing=true | \
    jq -r '.[].Service | "\(.Address):\(.Port)"'
}
# 更新Nginx配置
update_nginx_config() {
    cat > ${NGINX_CONF} << EOF
upstream ${SERVICE_NAME}_backend {
    $(for instance in $(get_healthy_instances); do
        echo "    server ${instance};"
    done)
}
server {
    listen 80;
    location / {
        proxy_pass http://${SERVICE_NAME}_backend;
    }
}
EOF
    nginx -s reload
}
# 监控并更新
while true; do
    update_nginx_config
    sleep 30
done

完整自动化脚本

一键部署负载均衡集群

#!/bin/bash
set -e
# 配置参数
APP_NAME="myapp"
IMAGE="nginx:alpine"
REPLICAS=3
NETWORK="app_network"
LB_PORT=80
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
log() {
    echo -e "${GREEN}[INFO]${NC} $1"
}
error() {
    echo -e "${RED}[ERROR]${NC} $1"
    exit 1
}
# 创建网络
create_network() {
    if ! docker network ls | grep -q "${NETWORK}"; then
        docker network create ${NETWORK}
        log "Created network: ${NETWORK}"
    fi
}
# 部署应用容器
deploy_apps() {
    for i in $(seq 1 ${REPLICAS}); do
        docker run -d \
            --name "${APP_NAME}_${i}" \
            --network ${NETWORK} \
            --label "app=${APP_NAME}" \
            --health-cmd "curl -f http://localhost:80 || exit 1" \
            --health-interval 5s \
            --health-retries 3 \
            ${IMAGE}
        log "Deployed ${APP_NAME}_${i}"
    done
}
# 配置HAProxy
configure_haproxy() {
    cat > /etc/haproxy/haproxy.cfg << 'EOF'
global
    daemon
    maxconn 4096
defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option dontlognull
    option httpchk GET /health
    http-check expect status 200
frontend http_front
    bind *:${LB_PORT}
    default_backend app_backend
backend app_backend
    balance roundrobin
    option forwardfor
EOF
    # 动态添加后端服务器
    for container in $(docker ps --filter "label=app=${APP_NAME}" --format "{{.Names}}"); do
        IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${container})
        echo "    server ${container} ${IP}:80 check inter 2000 rise 2 fall 3" >> /etc/haproxy/haproxy.cfg
    done
    # 启动/重载HAProxy
    if pgrep -x haproxy > /dev/null; then
        haproxy -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
    else
        haproxy -f /etc/haproxy/haproxy.cfg
    fi
    log "HAProxy configured and started"
}
# 健康检查循环
health_check_loop() {
    while true; do
        for container in $(docker ps --filter "label=app=${APP_NAME}" --format "{{.Names}}"); do
            health=$(docker inspect -f '{{.State.Health.Status}}' ${container})
            if [ "${health}" != "healthy" ]; then
                log "Container ${container} is unhealthy, reconfiguring..."
                configure_haproxy
                break
            fi
        done
        sleep 5
    done
}
# 主函数
main() {
    log "Starting load balancer deployment..."
    create_network
    deploy_apps
    # 检查HAProxy是否安装
    if ! command -v haproxy &> /dev/null; then
        error "HAProxy is not installed. Please install it first."
    fi
    configure_haproxy
    # 启动健康检查(后台运行)
    health_check_loop &
    log "Deployment complete!"
    log "Load balancer running on port ${LB_PORT}"
}
# 执行主函数
main "$@"

使用建议

  1. 选择合适的方案

    • 小型项目:Docker Swarm 原生
    • 需要高级功能:HAProxy/Nginx
    • 动态环境:Consul + 自动发现
  2. 配置持久化

    # 定期备份配置
    cp /etc/nginx/nginx.conf /backup/nginx.$(date +%Y%m%d).conf
  3. 监控告警

    # 配置通知(如Slack)
    if [ $? -ne 0 ]; then
        curl -X POST -H 'Content-type: application/json' \
            --data '{"text":"Load balancer reconfiguration failed!"}' \
            https://hooks.slack.com/services/YOUR/WEBHOOK/URL
    fi

这些脚本可以根据你的具体需求调整,记得先测试环境再部署到生产。

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