记ProxmoxVE集群脑裂处置过程

1,485 阅读6分钟

2024-01-05更新记录

其实理解了投票机制后就很容易解决这个问题了,正常使用的 PVE 集群,突然脑裂了,解决方法其实很简单,之前写的帖子因为没理解透投票机制,导致走了很多弯路。

修复方法:

1.批量关闭所有节点的 corosync 服务

systemctl stop corosync

2. 逐台节点启动 corosysnc 服务

systemctl start corosync

首先大致介绍下背景,发生事故的 ProxmoxVE 集群是部署在比较恶劣的服务器和网络上,用于提供开发、测试环境的虚拟化能力,至于为什么不用商业产品 Vsphere 、Zstack 或者 OpenStack 等大型开源虚拟化产品,总结一句话就是:没钱、没人、没本领,那为什么会选择 Proxmox,最重要的原因并不是因为他是免费开源的,而是可以轻松的部署一套分布式存储集群,并且提供了非常完善的 API 能力,可以在之后的 IaC 基础设施即代码的能力建设上提供强有力的环境。
集群分别部署在两种类型的硬件上,一种是退役的华为 E9000 一体机、一种是退役的 DELL 机架式服务器,考虑到分布式存储 Ceph 的稳定性要求,华为一体机中的存储型刀片用于提供存储和计算,其他型号刀片服务器及机架式服务器仅提供计算能力,存储则使用 Ceph RBD,可以实现虚拟机的快速迁移。
接下来就是事故描述了,Day 0 这个集群有部分宿主机自动重启,未引起重视,因为平时偶尔也会有几台宿主机会自动重启,重启好了,集群也有恢复正常了。到了下午快下班的时候,又有几台宿主机自动重启,这次重启后发现集群状态不正常,集群创建机(创建这个集群的宿主机,属于存储计算一体的节点)网络不通,ping 网络也不通,重启网络服务 systemctl restart networking依然不通,于是决定重启操作系统,然而一直无响应,于是登录带外管理强制下电重启,等了很久(以往没有这种情况)后终于重启成功,此时集群恢复正常(伪),下班时间也到了,就回家了。
晚上10点左右,接同事通知,有更多的虚拟机宕机,且无法登录 Proxmox 的管理界面,提示密码错误。通过 SSH 登录后查看日志,发现日志报错内容是集群未就绪,瞬间意识到不对了,于是开始了一系列的救火操作。
首先回想到白天在第一次发生重启事件时,天真的以为更新下操作系统、集群软件组件也许就好了,然后正是这个手贱的操作导致集群脑裂:这个集群的虚拟网络用的是openvswitch,在很久之前的一次故障中,就发现了更新这个服务后,必须手动重启服务,否则会发生莫名其妙的网络不通问题。那么下面就是批量重启所有节点的这个服务,但是并没有什么卵用:

## OVS更新后必须手动重启服务
systemctl restart openvswitch-switch.service && systemctl restart networking

重启网络后所有节点网络都是正常的,但是集群依然是脑裂状态:\

查看 corosync 集群当前节点连接状态

### 查看当前节点连接状态
### 现场未保留,这是正常集群的状态,异常状态的时候会有随机的节点显示 disconnect
proxmox-cluster02-ceph01:~# corosync-cfgtool -s
Local node ID 16, transport knet
LINK ID 0 udp
        addr    = 172.20.3.171
        status:
                nodeid:          1:     connected
                nodeid:          2:     connected
                nodeid:          3:     connected
                nodeid:          4:     connected
                nodeid:          5:     connected
                nodeid:          6:     connected
                nodeid:          7:     connected
                nodeid:          8:     connected
                nodeid:          9:     connected
                nodeid:         10:     connected
                nodeid:         11:     connected
                nodeid:         12:     connected
                nodeid:         13:     connected
                nodeid:         14:     connected
                nodeid:         15:     connected
                nodeid:         16:     localhost

查看 corosync 当前已连接的节点和链路

## 查看当前已连接的节点和链路
## 现场未保留,这是正常集群的状态,异常状态的时候有两个现象:
## 1. 列出的节点数会缺少很多
## 2. enabled 后面没有 connected 标识,为空
proxmox-cluster02-ceph01:~# corosync-cfgtool -n
Local node ID 16, transport knet
nodeid: 1 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.179) enabled connected mtu: 1397

nodeid: 2 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.178) enabled connected mtu: 1397

nodeid: 3 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.177) enabled connected mtu: 1397

nodeid: 4 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.9) enabled connected mtu: 1397

nodeid: 5 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.17) enabled connected mtu: 1397

nodeid: 6 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.10) enabled connected mtu: 1397

nodeid: 7 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.30) enabled connected mtu: 1397

nodeid: 8 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.18) enabled connected mtu: 1397

nodeid: 9 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.19) enabled connected mtu: 1397

nodeid: 10 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.16) enabled connected mtu: 1397

nodeid: 11 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.175) enabled connected mtu: 1397

nodeid: 12 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.176) enabled connected mtu: 1397

nodeid: 13 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.174) enabled connected mtu: 1397

nodeid: 14 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.173) enabled connected mtu: 1397

nodeid: 15 reachable
   LINK: 0 udp (172.20.3.171->172.20.3.172) enabled connected mtu: 1397

corosync 集群选举状态

proxmox-cluster02-ceph01:~# corosync-quorumtool -s
Quorum information
------------------
Date:             Fri Sep 16 22:43:05 2022
Quorum provider:  corosync_votequorum
Nodes:            16
Node ID:          16
Ring ID:          1.88
Quorate:          no

Votequorum information
----------------------
Expected votes:   16
Highest expected: 16
Total votes:      1
Quorum:           9 Activity blocked  
Flags:             

Membership information
----------------------
    Nodeid      Votes Name
        16          1 proxmox-cluster02-ceph01 (local)

从上面的集群选举状态中的字段可以看出此时集群已经脑裂,Total votes 总票数只有 1 ,也就是只有自己参与了投票,Quorum: 9 Activity blocked 这个具体含义不清除,官方论坛有些关于这个问题的讨论,结论就是脑裂了,集群挂了。
那么是怎么尝试修复的呢?\

统一更新集群版本、祭出重启大法,没卵用

pveupdate && pveupgrade -y && \
  systemctl restart openvswitch-switch.service && \
  systemctl restart networking &&\
  systemctl reboot

此时时间已经走到 Day 1 凌晨 3 点,先恢复最重要的业务:LDAP:

节点脱离集群网络

systemctl stop pve-cluster && \
	systemctl stop corosync && \
	pmxcfs -l && \
	rm -f /etc/pve/corosync.conf && \
	rm -rf /etc/corosync/* && \
	killall pmxcfs && \
	systemctl start pve-cluster && \
	rm -rf /etc/corosync/*

脱离集群后,就可以启动虚拟机了。
早上上班后接着开始修复集群,方案决定采用重建 corosync 集群的方式,重建过程中发现集群创建机继续使用原来的节点的话,在把别的节点加入的时候,集群创建机必然会自动重启一下,刚加入的节点也会随机重启,重启原因目前还是未找到
最后换了一个节点用于集群创建机,并将其他节点加入,过程中有一个节点自动重启,全部加入集群后,整个集群恢复正常。

重新加入集群

pvecm add 172.20.3.179 --force
## --force 参数表示强行加入集群,如节点自身已经有虚拟机,就需要加这个参数,但是需要注意本机的虚拟机 ID 不能与集群其他成员的虚拟机 ID 重复。