架构组件: Nginx Proxy Manager (Web UI/LB) + Keepalived (VIP HA)
核心特性: 界面化管理、自动故障切换、配置自动同步
1. 环境拓扑
部署目录:所有节点统一为
/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 验证同步机制
设置定时任务 (保险起见):
在三台机器执行 crontab -e,添加:
*/30 * * * * /opt/ha-lb/auto_sync.sh >> /var/log/ha-sync.log 2>&1测试同步:
在 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