本文目录导读:

在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 "$@"
使用建议
-
选择合适的方案:
- 小型项目:Docker Swarm 原生
- 需要高级功能:HAProxy/Nginx
- 动态环境:Consul + 自动发现
-
配置持久化:
# 定期备份配置 cp /etc/nginx/nginx.conf /backup/nginx.$(date +%Y%m%d).conf
-
监控告警:
# 配置通知(如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
这些脚本可以根据你的具体需求调整,记得先测试环境再部署到生产。