本文档适配Halo网站直接粘贴发布,全程无复杂格式,所有命令可直接复制执行,核心实现:PVE1(主)+ PVE2(备)+ ARM内网仲裁机,基于DRBD实时同步+Keepalived自动切换,彻底杜绝脑裂,实现0数据丢失、无人干预故障切换,家用AIO天花板级稳定方案。
一、环境信息(必替换为自身实际信息)
请先确认自身设备信息,后续所有配置均基于此修改,避免出错:
PVE1(主节点,x86架构):主机名 pve1 | IP 192.168.1.10 | 虚拟机ID 100(需主备的虚拟机)
PVE2(备节点,x86架构):主机名 pve2 | IP 192.168.1.11
ARM仲裁机(内网,Armbian虚拟机):IP 192.168.1.12(需部署在ARM PVE的虚拟机中)
DRBD配置:资源名 vm | 设备 /dev/drbd0(两台PVE已提前配置完成,状态正常)
虚拟VIP(对外统一访问IP):192.168.1.100/24(无需提前配置,Keepalived自动管理)
DRBD专用磁盘:两台PVE各有1块相同大小的闲置磁盘(如 /dev/sdb,未分区、未挂载,用于DRBD同步)
二、DRBD基础配置(两台PVE均需执行,核心同步配置)
DRBD是实现虚拟机磁盘实时同步的核心,需先完成两台PVE的DRBD配置,再进行后续Keepalived和仲裁机配置,步骤如下(两台PVE操作一致,仅主节点需额外执行初始化):
2.1 安装DRBD相关软件
执行命令,安装DRBD内核模块和管理工具:
apt update && apt install -y drbd-dkms drbd-utils
2.2 加载DRBD内核模块
执行命令,加载模块并确认加载成功:
modprobe drbd
lsmod | grep drbd
若输出包含“drbd”相关内容,说明模块加载成功。
2.3 创建DRBD配置文件
执行命令,创建并编辑DRBD资源配置文件(资源名设为vm,与后续脚本保持一致):
nano /etc/drbd.d/vm.res
粘贴以下内容(替换主机名、IP、磁盘路径为自身实际信息,两台PVE配置完全一致):
resource vm {
on pve1 { # PVE1主机名,需与自身主机名一致
device /dev/drbd0; # DRBD虚拟设备,固定不变
disk /dev/sdb; # 自身DRBD专用闲置磁盘,替换为实际路径
address 192.168.1.10:7789; # PVE1 IP + DRBD端口(7789可自定义,两台一致即可)
meta-disk internal; # 元数据存储在磁盘内部,无需额外配置
}
on pve2 { # PVE2主机名,需与自身主机名一致
device /dev/drbd0;
disk /dev/sdb; # 与PVE1磁盘大小一致,路径可不同但建议统一
address 192.168.1.11:7789; # PVE2 IP + 相同DRBD端口
meta-disk internal;
}
net {
protocol C; # 强同步模式,确保写入主节点后立即同步到备节点,0数据丢失
max-buffers 8192; # 优化同步性能,无需修改
}
disk {
no-disk-barrier;
no-disk-flush; # 优化磁盘写入性能,无需修改
}
}
编辑完成后,按 Ctrl+O 保存,Ctrl+X 退出。
2.4 启动DRBD资源(两台PVE均执行)
执行命令,启动DRBD资源并确认启动状态:
drbdadm up vm
2.5 初始化DRBD主节点(仅在PVE1执行)
仅主节点(PVE1)执行以下命令,初始化DRBD并设置为主节点,备节点(PVE2)无需执行:
drbdadm create-md vm # 初始化元数据
drbdadm primary --force vm # 强制设置PVE1为DRBD主节点
2.6 查看DRBD同步状态(两台PVE均可执行)
执行命令,实时查看DRBD同步进度:
watch cat /proc/drbd
等待同步完成,当显示“cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate”时,说明DRBD主备同步正常(PVE1为主,PVE2为备),按 Ctrl+C 退出查看。
2.7 补充说明
1. 若DRBD专用磁盘已分区,需先执行 fdisk /dev/sdb 删除分区(谨慎操作,避免误删数据);
2. 同步速度取决于内网带宽,千兆内网同步较快,首次同步时间根据磁盘大小而定;
3. DRBD配置完成后,后续虚拟机磁盘需挂载 /dev/drbd0,才能实现实时同步。
三、前置条件(必须满足,否则无法正常运行)
DRBD已配置完成,两台PVE执行 cat /proc/drbd ,显示状态为 Primary/Secondary UpToDate/UpToDate(主备节点DRBD同步正常)。
三台设备(PVE1、PVE2、ARM仲裁机)内网互通,可互相ping通、SSH连接(无防火墙拦截)。
PVE1已创建目标虚拟机(ID 100),并将虚拟机磁盘挂载到DRBD设备 /dev/drbd0;PVE2暂不创建同名虚拟机。
防火墙放通:VRRP协议(协议号112)、DRBD端口(7789)、ICMP协议(ping)。
四、ARM仲裁机配置(最简操作,仅需2步)
ARM仲裁机无需部署复杂服务,仅需允许被ping通,作为第三方裁判即可,操作均在Armbian虚拟机中执行:
4.1 安装ping工具(确保可被检测)
执行命令:
apt update && apt install -y iputils-ping
4.2 验证连通性
在PVE1、PVE2分别执行 ping 192.168.1.12 -c 3 ,能正常收到回复即完成(若不通,检查防火墙或网络配置)。
五、两台PVE节点通用配置(均需执行)
以下操作同时在PVE1和PVE2上执行,确保环境一致:
5.1 安装依赖软件
执行命令,安装Keepalived(自动切换核心)和ping工具(检测仲裁机):
apt update && apt install -y keepalived iputils-ping
5.2 确认DRBD状态
执行命令,确保DRBD处于正常同步状态:
cat /proc/drbd
确认显示 cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate(PVE1为主,PVE2为备)。
六、PVE1(主节点)详细配置
6.1 编辑Keepalived主配置文件
执行命令,创建并编辑配置文件:
nano /etc/keepalived/keepalived.conf
粘贴以下内容(替换IP为自身实际信息,其他无需修改):
global_defs {
router_id PVE1
}
vrrp_instance VI_1 {
state MASTER
interface vmbr0 # 自身网卡名,默认vmbr0,无需修改
virtual_router_id 66 # 主备节点需一致,任意1-255之间的数字
priority 150 # 主节点优先级,需高于备节点(备节点设为100)
advert_int 1 # 检测间隔,1秒一次,无需修改
# 认证配置,主备节点需完全一致
authentication {
auth_type PASS
auth_pass 12345678 # 自定义密码,建议修改,主备一致即可
}
# 虚拟VIP,对外统一访问IP,替换为自身规划的VIP
virtual_ipaddress {
192.168.1.100/24
}
# 第三方仲裁检测:必须能ping通ARM仲裁机,否则自动降级
track_script {
check_arbitrator
}
# 状态切换执行的脚本(自动切DRBD主备、启停虚拟机)
notify_master "/etc/keepalived/role-master.sh"
notify_backup "/etc/keepalived/role-backup.sh"
notify_fault "/etc/keepalived/role-fault.sh"
}
# 仲裁机检测脚本:ping ARM仲裁机IP,2秒检测一次
vrrp_script check_arbitrator {
script "ping -c 2 -W 1 192.168.1.12 >/dev/null 2>&1"
interval 2
weight -20
fall 2
rise 2
}
编辑完成后,按 Ctrl+O 保存,Ctrl+X 退出。
6.2 创建状态切换脚本(3个)
脚本作用:自动切换DRBD主备状态、启停虚拟机,无需人工干预,依次创建3个脚本并添加执行权限。
1. 主节点升主脚本(成为主节点时执行)
执行命令:nano /etc/keepalived/role-master.sh
粘贴内容(替换虚拟机ID为自身实际ID):
#!/bin/bash
drbdadm primary vm # 切换DRBD为主节点
qm start 100 # 启动虚拟机(替换为自身虚拟机ID)
2. 主节点降备脚本(变为备节点时执行)
执行命令:nano /etc/keepalived/role-backup.sh
粘贴内容(替换虚拟机ID为自身实际ID):
#!/bin/bash
qm stop 100 # 关闭虚拟机
drbdadm secondary vm # 切换DRBD为备节点
3. 故障降级脚本(节点故障时执行)
执行命令:nano /etc/keepalived/role-fault.sh
粘贴内容(替换虚拟机ID为自身实际ID):
#!/bin/bash
qm stop 100 # 强制关闭虚拟机
drbdadm secondary vm # 强制切换DRBD为备节点
6.3 给脚本添加执行权限
执行命令,一次性给3个脚本添加权限:
chmod +x /etc/keepalived/role-*.sh
七、PVE2(备节点)详细配置
备节点配置与主节点基本一致,仅需修改优先级和升主脚本(添加--force参数),其余配置保持一致。
7.1 编辑Keepalived备配置文件
执行命令:nano /etc/keepalived/keepalived.conf
粘贴以下内容(替换IP为自身实际信息,重点修改priority和state):
global_defs {
router_id PVE2
}
vrrp_instance VI_1 {
state BACKUP # 备节点设为BACKUP,主节点为MASTER
interface vmbr0
virtual_router_id 66 # 与主节点一致
priority 100 # 优先级低于主节点(主节点150)
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678 # 与主节点完全一致
}
virtual_ipaddress {
192.168.1.100/24 # 与主节点VIP一致
}
track_script {
check_arbitrator # 同样检测ARM仲裁机
}
notify_master "/etc/keepalived/role-master.sh"
notify_backup "/etc/keepalived/role-backup.sh"
notify_fault "/etc/keepalived/role-fault.sh"
}
vrrp_script check_arbitrator {
script "ping -c 2 -W 1 192.168.1.12 >/dev/null 2>&1"
interval 2
weight -20
fall 2
rise 2
}
保存退出(Ctrl+O → Ctrl+X)。
7.2 创建状态切换脚本(3个,仅升主脚本有差异)
同样创建3个脚本,仅升主脚本添加--force参数(强制切换DRBD主节点),其余两个与主节点一致。
1. 备节点升主脚本(重点修改)
执行命令:nano /etc/keepalived/role-master.sh
粘贴内容(替换虚拟机ID):
#!/bin/bash
drbdadm primary --force vm # 备节点升主,需加--force强制切换
qm start 100 # 启动虚拟机
2. 备节点降备脚本(与主节点完全一致)
执行命令:nano /etc/keepalived/role-backup.sh
粘贴内容:
#!/bin/bash
qm stop 100
drbdadm secondary vm
3. 故障降级脚本(与主节点完全一致)
执行命令:nano /etc/keepalived/role-fault.sh
粘贴内容:
#!/bin/bash
qm stop 100
drbdadm secondary vm
7.3 给脚本添加执行权限
执行命令,与主节点一致:
chmod +x /etc/keepalived/role-*.sh
八、启动服务并验证状态(两台PVE均执行)
8.1 启动Keepalived服务并设置开机自启
执行命令:
systemctl enable keepalived && systemctl restart keepalived
8.2 验证3个关键状态(确保配置成功)
1. 验证Keepalived状态(无报错即正常)
执行命令:systemctl status keepalived
显示 active (running) 即为正常。
2. 验证VIP位置(正常情况下,VIP应在PVE1)
执行命令:ip a
查看vmbr0网卡,是否有 192.168.1.100/24 的IP(主节点有,备节点无)。
3. 验证DRBD状态(依然保持主备同步)
执行命令:cat /proc/drbd
确认状态为 Primary/Secondary UpToDate/UpToDate。
九、核心逻辑(为什么能彻底杜绝脑裂?)
通过ARM内网仲裁机作为第三方裁判,制定严格的主备切换规则,从根源避免双主(脑裂):
任何节点(PVE1或PVE2)ping不通ARM仲裁机 → 立即自动降级为故障状态,关闭虚拟机、释放DRBD主节点,不再参与主备竞争。
备节点(PVE2)想要升为主节点,必须同时满足两个条件:① 主节点(PVE1)失联;② 自身能正常ping通ARM仲裁机。
网络分裂/抖动时:只有能连通仲裁机的节点,才能成为主节点;另一节点自动降级,不会出现双主,彻底杜绝脑裂。
内网仲裁机不受外网影响,即使家里宽带断网,主备切换依然正常,服务不受影响(这是公网VPS仲裁无法比的)。
十、故障切换测试(必做,验证稳定性)
配置完成后,必须进行测试,确保故障时能自动切换,步骤如下:
测试1:主节点(PVE1)关机
操作:关闭PVE1电源,在PVE2执行 journalctl -u keepalived -f ,观察日志。
预期效果:PVE2检测到PVE1失联,且自身能ping通仲裁机 → 自动升为主节点 → 自动执行drbdadm primary --force vm → 自动启动虚拟机 → VIP漂移到PVE2。
测试2:主节点(PVE1)恢复
操作:启动PVE1,观察两台PVE的状态。
预期效果:PVE1启动后,因优先级更高(150),自动升为主节点 → PVE2自动降为备节点 → VIP漂移回PVE1 → 虚拟机在PVE1启动,PVE2虚拟机关闭。
测试3:仲裁机失联
操作:关闭ARM仲裁机虚拟机,观察两台PVE状态。
预期效果:两台PVE均ping不通仲裁机 → 均降级为故障状态 → 虚拟机关闭、VIP消失;重启仲裁机后,自动恢复主备状态。
十一、常见问题及解决方案(避坑必备)
11.1 Keepalived启动失败,日志提示“interface vmbr0 does not exist”
原因:网卡名不是vmbr0(默认是vmbr0,若修改过需对应调整)。
解决:执行 ip a 查看自身网卡名,替换配置文件中 interface 后的内容。
11.2 DRBD状态异常,显示“Outdated”
原因:主备同步中断,或切换时未正确执行脚本。
解决:在备节点(PVE2)执行:
drbdadm disconnect vm
drbdadm secondary vm
在主节点(PVE1)执行:
drbdadm connect vm
等待同步完成(cat /proc/drbd 查看Sync'ed: 100%)。
11.3 故障时未自动切换,日志提示“ping failed”
原因:仲裁机无法ping通,或防火墙拦截ICMP协议。
解决:检查ARM仲裁机是否开机、网络是否正常;在两台PVE关闭防火墙,或放通ICMP协议。
11.4 出现脑裂(极端情况,概率极低)
现象:两台PVE均显示为DRBD Primary,数据不一致。
解决:二选一(丢弃一边数据,确保数据一致):
方案1:以PVE1为准,丢弃PVE2数据(在PVE2执行):
drbdadm disconnect vm
drbdadm secondary vm
drbdadm -- --overwrite-data-of-peer primary vm
方案2:以PVE2为准,丢弃PVE1数据(在PVE1执行):
drbdadm disconnect vm
drbdadm secondary vm
drbdadm -- --overwrite-data-of-peer primary vm
11.5 DRBD初始化失败,提示“no such device or address”
原因:磁盘路径错误,或DRBD资源名与配置文件不一致。
解决:执行 lsblk 查看磁盘实际路径,修改DRBD配置文件中的disk参数;确保资源名(vm)与所有命令中的资源名一致。
十二、最终架构总结
本方案是家用AIO最稳的主备高可用方案,完美利用现有ARM设备,实现:
数据安全:DRBD protocol C强同步,0数据丢失;
自动切换:主节点宕机,备节点无人干预自动接管;
无脑裂:ARM内网仲裁机作为第三方裁判,彻底杜绝双主;
高可用:不受外网影响,内网故障切换稳定可靠;
易维护:所有配置可直接复制,后续无需复杂操作。
将本文档复制到Halo网站编辑器,替换自身IP、虚拟机ID等信息后,即可直接发布,作为后续维护参考。