高可用负载均衡 (HA-LB) 部署手册

作者:Administrator 发布时间: 2025-11-29 阅读量:4 评论数:0

架构组件: Nginx Proxy Manager (Web UI/LB) + Keepalived (VIP HA)

核心特性: 界面化管理、自动故障切换、配置自动同步

1. 环境拓扑

角色

主机名 (Hostname)

物理 IP

优先级 (Priority)

备注

Master

ning-ha-01.lan

192.168.6.10

100

初始主节点

Backup

ning-ha-02.lan

192.168.6.11

90

备节点 1

Backup

ning-ha-03.lan

192.168.6.12

80

备节点 2

VIP

-

192.168.6.222

-

业务访问入口

  • 部署目录:所有节点统一为 /opt/ha-lb

  • 网卡名称:假设为 ens2 (请根据实际 ip addr 输出修改)


2. 前置准备 (所有节点)

为了实现配置自动同步,必须打通 SSH 免密登录。

2.1 配置 Hosts 解析

修改 /etc/hosts,确保三台机器能通过域名互通:

192.168.6.10 ning-ha-01.lan
192.168.6.11 ning-ha-02.lan
192.168.6.12 ning-ha-03.lan

2.2 配置 SSH 免密互信

每一台机器 上执行生成密钥:

ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa

然后建立网状互信(确保 A能连B/C,B能连A/C,C能连A/B)。

例如在 ning-ha-01 上执行:

ssh-copy-id root@ning-ha-02.lan
ssh-copy-id root@ning-ha-03.lan

(请在 02 和 03 上重复类似操作,确保彼此互通)

2.3 创建目录结构

所有节点 执行:

mkdir -p /opt/ha-lb/npm/data
mkdir -p /opt/ha-lb/npm/letsencrypt
mkdir -p /opt/ha-lb/keepalived

3. 核心构建配置 (所有节点相同)

3.1 创建 Dockerfile (自定义纯净镜像)

文件路径:/opt/ha-lb/Dockerfile

FROM alpine:latest
# 安装 keepalived 及常用网络工具
RUN apk add --no-cache keepalived iproute2 net-tools bash curl openssh-client rsync

# 启动命令:强制删除可能残留的 PID 文件,防止无限重启
ENTRYPOINT ["/bin/sh", "-c", "rm -f /var/run/keepalived.pid && /usr/sbin/keepalived --dont-fork --log-console --log-detail -f /etc/keepalived/keepalived.conf"]

3.2 创建 Docker Compose

文件路径:/opt/ha-lb/docker-compose.yml

version: '3.8'

services:
  # --- 1. Nginx Proxy Manager (业务层) ---
  npm:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - '80:80'       # HTTP
      - '443:443'     # HTTPS
      - '81:81'       # 管理后台
      - '6443:6443'   # K8s API 转发 (Stream)
    environment:
      DB_SQLITE_FILE: "/data/database.sqlite"
      DISABLE_IPV6: 'true'
    volumes:
      - ./npm/data:/data
      - ./npm/letsencrypt:/etc/letsencrypt

  # --- 2. Keepalived (HA层 - 本地构建) ---
  keepalived:
    build: .        # 使用当前目录 Dockerfile 构建
    container_name: keepalived
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - NET_BROADCAST
      - NET_RAW
    network_mode: host  # 必须使用 Host 网络
    volumes:
      - ./keepalived/keepalived.conf:/etc/keepalived/keepalived.conf
      - ./keepalived/check_npm.sh:/usr/local/bin/check_npm.sh
      - ./auto_sync.sh:/opt/ha-lb/auto_sync.sh  # 挂载同步脚本
      - /root/.ssh:/root/.ssh:ro                 # 挂载 SSH Key 以便执行 rsync
    depends_on:
      - npm

3.3 创建健康检查脚本

文件路径:/opt/ha-lb/keepalived/check_npm.sh

#!/bin/sh
# 检测 NPM 管理端口是否监听
if netstat -nlt | grep -q ':81 '; then
  exit 0
else
  exit 1
fi

赋予权限: chmod +x /opt/ha-lb/keepalived/check_npm.sh


4. Keepalived 配置 (节点差异化)

请分别修改 /opt/ha-lb/keepalived/keepalived.conf

节点 1 (Master) 配置

代码段

global_defs {
    router_id NODE_01
    script_user root
    enable_script_security
}

vrrp_script check_npm {
    script "/usr/local/bin/check_npm.sh"
    interval 3
    weight -30
}

vrrp_instance VI_1 {
    state MASTER                # <--- 差异点
    interface ens2              # <--- 请修改为你的真实网卡名
    virtual_router_id 66
    priority 100                # <--- 差异点
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass MySecretPwd
    }
    virtual_ipaddress {
        192.168.6.222/24
    }
    track_script {
        check_npm
    }
    # 成为 Master 时触发同步
    notify_master "/opt/ha-lb/auto_sync.sh"
}

节点 2 & 3 (Backup) 配置

  • 节点 2: router_id NODE_02, state BACKUP, priority 90

  • 节点 3: router_id NODE_03, state BACKUP, priority 80

  • 注意: interface 需填写各机器实际网卡名。notify_master 配置保持一致。


5. 自动同步脚本 (所有节点相同)

文件路径:/opt/ha-lb/auto_sync.sh

#!/bin/bash
# ================= 配置区域 =================
VIP="192.168.6.222"
ALL_NODES=("ning-ha-01.lan" "ning-ha-02.lan" "ning-ha-03.lan")
SRC_DATA="/opt/ha-lb/npm/data/"
SRC_SSL="/opt/ha-lb/npm/letsencrypt/"
CURRENT_HOSTNAME=$(hostname)
# ===========================================

echo "[$(date)] 开始同步检查 ($CURRENT_HOSTNAME)..."

# 1. 只有持有 VIP 的 Master 才执行同步
if ip addr show | grep -q "$VIP"; then
    echo "我是 Master,准备同步配置..."
else
    echo "我是 Backup,跳过同步。"
    exit 0
fi

# 2. 遍历同步到其他节点
for NODE in "${ALL_NODES[@]}"; do
    if [ "$NODE" == "$CURRENT_HOSTNAME" ]; then continue; fi
    
    if ping -c 1 -W 1 "$NODE" &> /dev/null; then
        echo "同步到 -> $NODE"
        # 同步数据库和证书
        rsync -avz --delete "$SRC_DATA" "root@$NODE:$SRC_DATA" > /dev/null
        rsync -avz --delete "$SRC_SSL" "root@$NODE:$SRC_SSL" > /dev/null
        # 重启远程容器加载配置
        ssh "root@$NODE" "cd /opt/ha-lb && docker compose restart npm" 2>/dev/null
    fi
done
echo "同步完成。"

赋予权限: chmod +x /opt/ha-lb/auto_sync.sh


6. 启动与验证

6.1 启动服务

在三台机器上依次执行:

cd /opt/ha-lb
# 强制构建本地镜像并启动
docker compose up -d --build --force-recreate

6.2 验证 VIP

在 Master 节点执行 ip addr,应看到 192.168.6.222。

访问浏览器 http://192.168.6.222:81,登录 NPM (admin@example.com / changeme)。

6.3 验证同步机制

  1. 设置定时任务 (保险起见):

    在三台机器执行 crontab -e,添加:

    */30 * * * * /opt/ha-lb/auto_sync.sh >> /var/log/ha-sync.log 2>&1
    
  2. 测试同步

    • 在 VIP 的 Web 界面添加一个 Proxy Host。

    • 手动在 Master 执行 /opt/ha-lb/auto_sync.sh (或等待定时任务)。

    • 登录 Backup 节点的 IP :81,查看该 Proxy Host 是否自动出现。


7. 运维常用命令

查看 Keepalived 日志 (排查脑裂/切换):

docker logs -f keepalived

手动触发全量同步:

登录当前持有 VIP 的机器:

/opt/ha-lb/auto_sync.sh

更新 Nginx Proxy Manager 版本:

docker compose pull npm
docker compose up -d

评论