5.集群管理器 Cluster Manager
Proxmox VE 集群管理器 pvecm 是用于创建一组物理服务器的工具 , 这样的一组称为 集群(cluster)。我们使用 Corosync Cluster Engine 实现可靠的组通信。集群的节点数在理论上没有明确上限 , 实际可能数取决于主机与网络性能。目前(2021)有使用高端企业硬件的集群在生产环境稳定运行 50+ 节点的报告。
pvecm 可用于创建新集群、将节点加入集群、离开集群、获取状态信息以及执行各种集群相关任务。 Proxmox 集群文件系统(pmxcfs) 用于将集群配置透明分发到所有节点。
把节点组成集群有以下优势:
- 集中式、基于 Web 的管理
- 多主(multi-master)集群 :每个节点都可执行所有管理任务
- 使用
pmxcfs(数据库驱动的文件系统)存储配置文件 , 并通过corosync实时在所有节点上复制 - 物理主机之间轻松迁移虚拟机与容器
- 快速部署
- 集群范围的服务 , 如防火墙与 HA
5.1.要求 Requirements
- 所有节点之间必须能通过 UDP 端口 5405–5412 互通 , corosync 方可工作。
- 日期与时间必须同步。
- 节点之间需 TCP 22 端口的 SSH 通道。
- 若关心高可用 , 至少需要 3 个节点才能保证可靠的 quorum。所有节点版本应一致。
对较小的 2 节点集群 , 可使用 QDevice 提供第 3 票(见 §5.10)。
- 我们 推荐为集群流量使用专用物理 NIC。
Proxmox VE 集群通信使用 Corosync 协议 , 对低且稳定的延迟敏感 , 但带宽要求不高 , 大多数情况下一块专用 1 Gbit NIC 就足够。这有助于避免其他服务占用全部可用带宽 , 进而增加 Corosync 包的延迟。
- 为集群流量额外配置链路 , 可在专网故障时提供冗余。
Corosync 最多支持 8 条链路。
要实现可靠的 Corosync 冗余 , 必须至少有一条链路位于 不同的物理网络。这能在专网中断时让集群通信继续存活。
仅用一条 bond 链路承担 Corosync 在某些故障场景下会出问题 , 详见 §5.7.2「Corosync Over Bonds」。
- 添加节点时需要集群节点的 root 密码。
- 虚拟机在线迁移只在 CPU 来自同一厂商 时得到支持;其他情况也可能工作 , 但没有保证。
5.2.准备节点 Preparing Nodes
首先 , 在所有节点上安装 Proxmox VE。确保每个节点安装时使用 最终的主机名与 IP 配置。集群创建之后无法更改主机名与 IP。
虽然把所有节点名与其 IP 写入 /etc/hosts(或通过其他方式让节点名可解析)是常见做法 , 但这对集群工作并非必需。如果配置了主机名解析 , 您可以使用更好记的节点名通过 SSH 互连(另见「链路地址类型」)。请注意 , 我们始终推荐在集群配置中通过 IP 地址引用节点。
5.3.创建集群 Create a Cluster
您可以通过控制台(SSH 登录后), 或通过 Proxmox VE Web 界面(Datacenter → Cluster)经由 API 创建集群。
请为您的集群 使用唯一名称。集群名之后不可更改 , 并遵循与节点名相同的规则。
5.3.1.通过 Web GUI 创建 Create via Web GUI
在 Datacenter → Cluster 下 , 点击 Create Cluster。输入集群名称 , 并从下拉列表中选择一个网络连接作为主集群网络(Link 0)。默认值为该节点主机名解析得到的 IP。
自 Proxmox VE 6.2 起 , 可为集群添加最多 8 条后备链路。要添加冗余链路 , 点击 Add 按钮 , 并从相应字段选择链路编号与 IP 地址。 6.2 之前的版本需勾选 Advanced 并选择额外网卡(Link 1, 另见 §5.8「Corosync 冗余」)。
确保用于集群通信的网络 不用于 高流量用途(例如网络存储或在线迁移)。集群网络本身数据量很小 , 但对延迟极敏感。请参阅完整的「集群网络要求」。
5.3.2.通过命令行创建 Create via the Command Line
经 SSH 登录到第一台 Proxmox VE 节点 , 运行:
hp1# pvecm create CLUSTERNAME
检查新集群的状态:
hp1# pvecm status
5.3.3.同一网络中的多个集群 Multiple Clusters in the Same Network
可以在同一物理或逻辑网络中创建多个集群。此时每个集群必须使用 唯一名称 以避免集群通信栈的冲突 , 同时便于区分。
尽管 corosync 集群的带宽需求相对较低 , 但包延迟与每秒包数(PPS)是限制因素。同网段内的不同集群可能在这些资源上互相竞争 , 因此对规模较大的集群 , 使用独立的物理网络仍然合理。
5.4.向集群添加节点 Adding Nodes to the Cluster
加入集群时 , /etc/pve 下所有现有配置都会被覆盖。尤其 , 加入的节点 不能 持有任何客户机 , 否则客户机 ID 可能冲突;该节点将继承集群的存储配置。若需把带有现成客户机的节点加入 , 可先用 vzdump 备份每个客户机 , 加入后以不同 ID 恢复。若节点存储布局不同 , 还需重新添加该节点的存储 , 并调整每个存储的 node restriction。
5.4.1.通过 GUI 加入集群 Join Node to Cluster via GUI
登录到已有集群节点的 Web 界面。在 Datacenter → Cluster 顶部点击 Join Information, 再点 Copy Information, 或手动从 Information 字段复制字符串。
接着 , 登录到要加入的节点 Web 界面 , 在 Datacenter → Cluster 点 Join Cluster。把之前复制的 Join Information 粘贴到 Information 字段 , 大多数加入集群所需设置会自动填好。出于安全考虑 , 集群密码需要手动输入。
如需手动填写全部所需数据 , 可取消勾选 Assisted Join。
点击 Join 后 , 加入过程立即开始。加入完成后 , 节点当前证书会被换为集群 CA 签发的证书 , 当前会话几秒后会失效 , 届时需强制刷新页面并以集群凭据重新登录。此时您的节点应可在 Datacenter → Cluster 下看到。
5.4.2.通过命令行加入集群 Join Node to Cluster via Command Line
经 SSH 登录到待加入节点:
# pvecm add IP-ADDRESS-CLUSTER
IP-ADDRESS-CLUSTER 应为已有集群节点的 IP 或主机名。 推荐使用 IP(见「链路地址类型」)。检查集群状态:
# pvecm status
添加 4 节点后的集群状态示例:
# pvecm status
Cluster information
~~~~~~~~~~~~~~~~~~~
Name: prod-central
Config Version: 3
Transport: knet
Secure auth: on
Quorum information
~~~~~~~~~~~~~~~~~~
Date: Tue Sep 14 11:06:47 2021
Quorum provider: corosync_votequorum
Nodes: 4
Node ID: 0x00000001
Ring ID: 1.1a8
Quorate: Yes
Votequorum information
~~~~~~~~~~~~~~~~~~~~~~
Expected votes: 4
Highest expected: 4
Total votes: 4
Quorum: 3
Flags: Quorate
Membership information
~~~~~~~~~~~~~~~~~~~~~~
Nodeid Votes Name
0x00000001 1 192.168.15.91
0x00000002 1 192.168.15.92 (local)
0x00000003 1 192.168.15.93
0x00000004 1 192.168.15.94
只要列出所有节点:
# pvecm nodes
# pvecm nodes
Membership information
~~~~~~~~~~~~~~~~~~~~~~
Nodeid Votes Name
1 1 hp1
2 1 hp2 (local)
3 1 hp3
4 1 hp4
5.4.3.在独立集群网络上加入节点 Adding Nodes with Separated Cluster Network
向有独立集群网络的集群中添加节点时 , 需要用 link0 参数指定节点在该网络上的地址:
# pvecm add IP-ADDRESS-CLUSTER --link0 LOCAL-IP-ADDRESS-LINK0
若想使用 Kronosnet 传输层的内建冗余 , 还可加 --link1。在 GUI 中则可在 Cluster Join 对话框的相应 Link X 字段选择正确的接口。
5.5.移除集群节点 Remove a Cluster Node
在继续之前请 仔细阅读此过程, 它可能并不是您想要或需要的。
把节点上的所有虚拟机迁走 , 并确保已备份所有要保留的本地数据 / 备份。此外 , 请 移除指向待删除节点的所有计划复制作业。
未先移除复制作业就删除节点 , 会导致复制作业无法再删除。注意 :复制方向在被复制的 VM 迁移时会自动切换 , 因此把已配置复制的 VM 从将被删除的节点迁走 , 反而会把复制作业指向该节点。
若待删除节点上已配置 Ceph:
- 确保仍有足够数量的 Proxmox VE 节点带有处于 up 与 in 状态的 OSD。
默认 Ceph 池的 size / min_size = 3/2, 在 CRUSH 对象均衡器中以整节点作为故障域。因此若运行 OSD 的节点少于 size(3), 数据冗余将降级;若少于 min_size, 池 I/O 会被阻塞 , 受影响客户机可能崩溃。
- 确保仍有足够的 monitor、 manager, 若使用 CephFS 还需足够的 metadata 服务器。
- 为了维持数据冗余 , 每销毁一个 OSD(尤其是节点上最后一个)都会触发数据再平衡 , 务必确保剩余节点 OSD 有足够空闲空间。
- 要从待删除节点卸除 Ceph , 先逐个销毁其 OSD。
- 等 Ceph 状态恢复
HEALTH_OK后 , 再销毁其 metadata server(GUI 中 Ceph → CephFS, 或 CLI):
# pveceph mds destroy NAME
- 销毁其 monitor。
- 销毁其 manager。
- 最后从 CRUSH 层级中移除已空的 bucket(即待删节点):
# ceph osd crush remove NAME
以下示例演示如何从集群移除节点 hp4:
登录到 其他 集群节点(不要是 hp4), 运行 pvecm nodes 找到待移除节点的 ID:
hp1# pvecm nodes
Membership information
~~~~~~~~~~~~~~~~~~~~~~
Nodeid Votes Name
1 1 hp1 (local)
2 1 hp2
3 1 hp3
4 1 hp4
此时必须 关闭 hp4, 并确保其不会以当前配置在(集群)网络中再次上电。
如上所述 , 在移除之前必须关闭节点, 且保证其不会以当前配置在原集群网络上再次上电。否则集群可能损坏且难以恢复。
关闭 hp4 后 , 即可安全地从集群中移除:
hp1# pvecm delnode hp4 Killing node 4
此时可能出现 Could not kill node (error = CS_ERR_NOT_EXIST)。这并非真正删除失败 , 而是 corosync 尝试 「杀死」 一个已离线节点时的错误 , 可忽略。
再用 pvecm nodes 或 pvecm status 检查节点列表 , 应类似:
hp1# pvecm status
...
Votequorum information
~~~~~~~~~~~~~~~~~~~~~~
Expected votes: 3
Highest expected: 3
Total votes: 3
Quorum: 2
Flags: Quorate
Membership information
~~~~~~~~~~~~~~~~~~~~~~
Nodeid Votes Name
0x00000001 1 192.168.15.90 (local)
0x00000002 1 192.168.15.91
0x00000003 1 192.168.15.92
若出于任何原因 , 您想让该服务器再次加入同一个集群 , 必须:
- 在其上 全新安装 Proxmox VE;
- 按上一节所述加入集群。
已移除节点的配置文件仍保留在 /etc/pve/nodes/hp4, 如需可从中取回所需配置 , 之后再删除该目录。
移除后 , 节点的 SSH 指纹仍残留在其他节点的 known_hosts 中。若以相同 IP 或主机名重新加入时出现 SSH 错误 , 在重新加入后的节点上运行一次 pvecm updatecerts 即可更新全集群指纹。
5.5.1.不重装即分离节点 Separate a Node Without Reinstalling
这不是推荐方式 , 请谨慎操作。如不确定 , 请使用前一种方法。
您也可以不重装就把节点从集群中分离。但移除后该节点仍会拥有共享存储的访问权限 , 必须先处理这一问题。 Proxmox VE 集群不能与另一集群共享完全相同的存储 , 因为存储锁无法跨集群边界工作 , 还可能导致 VMID 冲突。
建议创建仅待分离节点能访问的新存储 , 例如 NFS 上的新 export 或新的 Ceph 池。关键是 完全相同的存储不能被多个集群访问。设置好新存储后 , 把该节点上的所有数据与 VM 迁移到新存储。然后才可把节点从集群分离。
务必彻底分离所有共享资源 , 否则会产生冲突与问题。
先停止该节点上的 corosync 与 pve-cluster 服务:
systemctl stop pve-cluster systemctl stop corosync
以本地模式重新启动集群文件系统:
pmxcfs -l
删除 corosync 配置文件:
rm /etc/pve/corosync.conf rm -r /etc/corosync/*
再次以普通服务启动文件系统:
killall pmxcfs systemctl start pve-cluster
此时节点已从集群分离。可在任意剩余的集群节点上删除它:
pvecm delnode oldnode
若命令因剩余节点失去 quorum 而失败 , 可将期望票数临时设为 1 作为变通:
pvecm expected 1
然后重复 pvecm delnode。
接着回到被分离的节点 , 清除其上所有剩余集群文件 , 以便该节点可无障碍地加入其他集群:
rm /var/lib/corosync/*
由于其他节点的配置文件还在集群文件系统中 , 您可能也想清除它们。在 确认节点名正确 后 , 递归删除 /etc/pve/nodes/NODENAME 即可。
该节点的 SSH 密钥仍留在 authorized_keys 中 , 节点彼此仍可用公钥登录。应从 /etc/pve/priv/authorized_keys 删除相应密钥。
5.6.仲裁(Quorum) Quorum
Proxmox VE 使用 基于仲裁(quorum) 的技术来在所有集群节点间保持一致状态。
Quorum 是分布式系统中为允许执行某项操作 , 一次分布式事务必须获得的最少票数。
网络分区时 , 状态变更要求 多数节点在线。一旦失去 quorum, 集群会切换到只读模式。
Proxmox VE 默认为每个节点分配 1 票。
5.7.集群网络 Cluster Network
集群网络是集群的核心。所有经过它传送的消息都必须以正确顺序可靠地送达所有节点。在 Proxmox VE 中该部分由 corosync 实现 —— 一个高性能、低开销、面向高可用性的开发工具集 , 它也支撑着我们去中心化的配置文件系统(pmxcfs)。
5.7.1.网络要求 Network Requirements
Proxmox VE 集群栈要求各节点之间有延迟 低于 5 毫秒(LAN 性能) 的可靠网络。节点数较少时 , 更高延迟的网络或许也能工作 , 但没有保证;超过 3 节点且延迟在 10 ms 左右以上时尤其不可靠。
该网络不应被其他成员大量占用 —— corosync 带宽需求低 , 但对延迟抖动敏感;理想情况下 corosync 应运行在物理上独立的网络上。尤其不要把 corosync 与存储共用一个网络(除非作为冗余配置中的低优先级后备)。
搭建集群前 , 最好检查网络是否胜任。可用 ping 验证节点间在集群网络上的互通。若启用了 Proxmox VE 防火墙 , corosync 所需的 ACCEPT 规则会自动生成 , 无需手工配置。
Corosync 在 3.0 版本(Proxmox VE 6.0 引入)之前使用多播 , 现代版本依赖 Kronosnet 进行集群通信 , 目前只支持普通 UDP 单播。
仍可在 corosync.conf 中把 transport 设为 udp 或 udpu 以启用多播或传统单播 , 但这会 禁用 全部加密与冗余支持 , 不推荐。
5.7.2.在 Bond 上运行 Corosync Corosync Over Bonds
建议 :至少为主 Corosync 链路使用一块专用物理 NIC(见 §5.1「要求」), bond 可作为额外链路以增强冗余。用 bond 承载 Corosync 流量时 , 须注意以下事项:
- bond 模式
active-backup在某些故障场景下可能不提供预期的冗余 , 详见下文。 - 建议不要 对 Corosync 使用
balance-rr、balance-xor、balance-tlb、balance-alb等 bond 模式。它们在部分故障场景下已知有问题 , 详见下文。 - IEEE 802.3ad(LACP) :若用 LACP bond 承载 corosync , 强烈建议在 Proxmox VE 节点与交换机上都把
bond-lacp-rate设为fast!默认slow在某些故障场景已知有问题。
背景 :考虑这样一种故障场景:绑定中的一个接口失效但其链路状态仍然 UP 且已停止发送包 , 同时没有其他 Corosync 链路可用。部分 bond 模式可能造成 非对称连通性 , 导致集群节点只能与不同子集的节点通信。受影响的多为负载均衡型 bond 模式 , 它们仍会把一部分包发到已故障的接口。这种情况下 Corosync 难以形成稳定 quorum;若 HA 启用 , 即便 bond 正常的节点也可能自我 fence。最坏情况 , 整个集群会自我 fence。
active-backup 在上述场景中 不会 造成非对称连通 , 但发生接口故障的 bond 可能不会切换到后备链路 , 节点可能失联并在 HA 启用时自我 fence。
balance-rr、 balance-xor、 balance-tlb、 balance-alb 在上述故障下会造成非对称连通 , 启用 HA 时可能触发意外 fence。
IEEE 802.3ad(LACP)在上述故障下可能造成非对称连通 , 但可通过 「连续 3 个 LACPDU 未收到」 机制恢复。然而默认 LACPDU 每 30 秒发一次 , 切换耗时约 90 秒 , 而带 HA 资源的节点在失去稳定 quorum 约 1 分钟后就会 fence 自己。因此若用 LACP bond 承载 corosync , 请在节点与交换机上都设 bond-lacp-rate fast —— 这会请求对端每秒发送一次 LACPDU, 双向都设置后上述场景的切换时间可降至 3 秒 , 避免 fence。
5.7.3.独立集群网络 Separate Cluster Network
不加任何参数创建集群时 , corosync 集群网络通常与 Web 界面及 VM 网络共享;视配置不同 , 存储流量也可能走同一网络。 推荐独立出来 , 因为 corosync 是对时间敏感的实时应用。
搭建新网络 :首先配置一块新网卡 , 应在物理独立的网络上。确保网络满足「集群网络要求」(§5.7.1)。
在创建集群时分离 :使用 pvecm create 的 linkX 参数。假设已在静态地址 10.10.10.1/25 配好一块额外 NIC 并希望集群通信走该接口:
pvecm create test --link0 10.10.10.1
检查是否工作正常:
systemctl status corosync
之后按「带独立集群网络加入节点」的说明添加其他节点。
在集群创建后分离 :若已建集群 , 想把通信换到另一网络而不重建 , 也可以。此过程中集群可能出现短暂 quorum 丢失 , 因为节点需重启 corosync 并逐一在新网络上加回。
请先阅读如何编辑 corosync.conf(§5.11.1) , 然后打开该文件 , 您应看到类似:
logging {
debug: off
to_syslog: yes
}
nodelist {
node {
name: due
nodeid: 2
quorum_votes: 1
ring0_addr: due
}
node {
name: tre
nodeid: 3
quorum_votes: 1
ring0_addr: tre
}
node {
name: uno
nodeid: 1
quorum_votes: 1
ring0_addr: uno
}
}
quorum {
provider: corosync_votequorum
}
totem {
cluster_name: testcluster
config_version: 3
ip_version: ipv4-6
secauth: on
version: 2
interface {
linknumber: 0
}
}
ringX_addr 实际上指 corosync 的 link 地址。 「ring」 是旧版 corosync 遗留的名字 , 为向后兼容保留。
首先 , 若节点条目里没有 name 属性则添加 , 其值必须与节点名一致。然后把所有节点的 ring0_addr 替换为新网络上的地址(可用 IP 或主机名;用主机名时要确保在所有节点都可解析 , 见「链路地址类型」)。
本例把集群通信切换到 10.10.10.0/25, 因此相应修改各节点 ring0_addr。
同一过程也可用于更换其他 ringX_addr。建议 一次只改一条链路地址, 出问题时更容易恢复。
递增 config_version 后 , 新配置文件应类似:
logging {
debug: off
to_syslog: yes
}
nodelist {
node {
name: due
nodeid: 2
quorum_votes: 1
ring0_addr: 10.10.10.2
}
node {
name: tre
nodeid: 3
quorum_votes: 1
ring0_addr: 10.10.10.3
}
node {
name: uno
nodeid: 1
quorum_votes: 1
ring0_addr: 10.10.10.1
}
}
quorum {
provider: corosync_votequorum
}
totem {
cluster_name: testcluster
config_version: 4
ip_version: ipv4-6
secauth: on
version: 2
interface {
linknumber: 0
}
}
最终检查无误后保存 , 并按「编辑 corosync.conf」一节所述生效。
更改会热应用 , 不一定需要重启 corosync。若您同时改了其他设置 , 或 corosync 报错 , 可选择重启。在单节点执行:
systemctl restart corosync
再检查:
systemctl status corosync
corosync 恢复工作后 , 在其他节点上也依次重启 , 它们将逐一以新网络加入集群。
5.7.4.Corosync 地址 Corosync Addresses
corosync link 地址(向后兼容地记为 ringX_addr)可以两种方式指定:
- IPv4/v6 地址 :直接使用 , 推荐。它们是静态的 , 通常不会被随意改动。
- 主机名 :通过
getaddrinfo解析 , 默认 IPv6 优先(见man gai.conf)。升级已有集群到 IPv6 时尤其要注意。
使用主机名需谨慎 , 因为它所解析到的地址可能在不修改 corosync 或运行节点的情况下被改变 —— 可能在无意中影响 corosync。
如倾向使用主机名 , 建议为 corosync 专用一个独立且静态的主机名 , 并确保集群中每个节点都能正确解析所有主机名。
自 Proxmox VE 5.1 起 , 虽然主机名仍受支持 , 但会在 录入时解析, 只有解析后的 IP 会写入配置。更早版本加入集群的节点在 corosync.conf 中可能仍使用未解析的主机名 —— 建议把它们替换为 IP 或独立主机名。
5.8.Corosync 冗余 Corosync Redundancy
Corosync 通过其内建的 Kronosnet 层默认支持冗余网络(旧的 udp/udpu 传输不支持)。启用方式 :在 pvecm 上用多个 --linkX 参数 , 或在 GUI 创建集群 / 加节点时填 Link 1, 或在 corosync.conf 中指定多个 ringX_addr。
要提供有效的故障转移 , 每条链路都应位于各自的物理网络上。
下述示例假定每个节点各有一个 10.10.10.0/25 与 10.20.20.0/25 静态地址。链路按优先级使用 , 可通过 corosync.conf 相应 interface 段中的 knet_link_priority 设置 , 或更推荐地 , 在 pvecm 创建集群时用 priority 参数:
# pvecm create CLUSTERNAME --link0 10.10.10.1,priority=15 --link1 10.20.20.1,priority=20
由于 link1 优先级更高 , 将优先被使用。若未手动配置优先级(或两条链路优先级相同), 则按编号从小到大使用。
即便所有链路都正常工作 , 也只有最高优先级的那条会承载 corosync 流量;不同优先级之间无法混用通信。由于低优先级链路只在所有更高优先级链路全部失败时才使用 , 因此把其他用途的网络(VM、存储等)配成低优先级链路是可行策略 —— 最坏情况下 , 有一条高延迟 / 拥塞的连接总比完全断开好。
5.8.1.为现有集群添加冗余链路 Adding Redundant Links To An Existing Cluster
要向运行中的配置加入新链路 , 先阅读 §5.11.1 如何编辑 corosync.conf。然后给 nodelist 段的每个节点加一条新 ringX_addr , 确保 X 对所有节点一致且该编号唯一;再在 totem 段加一个 interface , X 用上一步选的编号。
假设新链路编号为 1, 新配置文件可能形如:
logging {
debug: off
to_syslog: yes
}
nodelist {
node {
name: due
nodeid: 2
quorum_votes: 1
ring0_addr: 10.10.10.2
ring1_addr: 10.20.20.2
}
node {
name: tre
nodeid: 3
quorum_votes: 1
ring0_addr: 10.10.10.3
ring1_addr: 10.20.20.3
}
node {
name: uno
nodeid: 1
quorum_votes: 1
ring0_addr: 10.10.10.1
ring1_addr: 10.20.20.1
}
}
quorum {
provider: corosync_votequorum
}
totem {
cluster_name: testcluster
config_version: 4
ip_version: ipv4-6
secauth: on
version: 2
interface {
linknumber: 0
}
interface {
linknumber: 1
}
}
按编辑 corosync.conf 的最后步骤应用 , 不需要重启 corosync。查看 corosync 是否已加载新链路:
journalctl -b -u corosync
建议临时断开某节点的旧链路来测试 , 观察其状态是否保持 online:
pvecm status
若集群仍健康 , 说明新链路正在工作。
5.9.SSH 在 Proxmox VE 集群中的角色 Role of SSH in Proxmox VE Clusters
Proxmox VE 在多种特性中使用 SSH 通道:
- 代理控制台 / Shell 会话(节点与客户机):在节点 A 上访问节点 B 的 shell 时 , 会连到 A 上的终端代理 , 再经非交互 SSH 通道连到 B 的登录 shell。
- 安全模式下 VM 与 CT 的内存、本地存储迁移 :迁移期间源与目的节点之间会建立一条或多条 SSH 通道 , 用于交换迁移信息并传输内存与磁盘内容。
- 存储复制。
5.9.1.SSH 配置 SSH setup
Proxmox VE 系统对 SSH 的配置 / 设置做了如下更改:
- 为
root配置的 SSH 客户端偏好 AES 而非 ChaCha20; root的authorized_keys指向/etc/pve/priv/authorized_keys, 合并集群内所有已授权密钥;sshd允许root用密码登录。
较旧系统 /etc/ssh/ssh_known_hosts 可能是指向 /etc/pve/priv/known_hosts 的软链接(含所有节点 host key 合并版本)。现已改为 pve-cluster 中显式的 host key pinning, 仍在位的软链接可通过 pvecm updatecerts --unmerge-known-hosts 取消。
5.9.2..bashrc 自动执行的陷阱 Pitfalls due to automatic execution of .bashrc and siblings
若您有自定义的 .bashrc 或在登录 shell 启动时被自动执行的同类文件 , SSH 在会话建立后会自动运行它们。由于上述多数场景以 root 权限执行 , 可能产生意外副作用。
为避免此类问题 , 建议在 /root/.bashrc 开头加入检查 , 仅在 交互式会话 中才执行后续命令:
# 非交互式时尽早退出 , 避免副作用! case $- in *i*) ;; *) return;; esac
5.10.Corosync 外部投票支持(QDevice) Corosync External Vote Support
本节介绍如何在 Proxmox VE 集群中部署外部投票者。配置后 , 集群可承受更多节点故障而不违反集群通信的安全属性。
需要两种服务:
- 在每个 Proxmox VE 节点上运行的 QDevice 守护进程;
- 在独立服务器上运行的 外部投票守护进程。
这样即便是较小的部署(例如 2+1 节点)也能达到更高的可用性。
5.10.1.QDevice 技术概览 QDevice Technical Overview
Corosync Quorum Device(QDevice)是在每个集群节点上运行的守护进程。它根据外部第三方仲裁者的决定 , 向集群 quorum 子系统提供一定数量的票数。它的主要用途是让集群能承受 超出标准 quorum 规则 的节点故障。外部设备能看到所有节点 , 因此会只把票投给那一组 , 且仅当该组在获得第三方票后真的能(再次)形成 quorum 时才投。
目前仅支持 QDevice Net 作为第三方仲裁者。这是一个只要能通过网络到达分区成员 , 就向该分区提供一票的守护进程;同一时刻只会给集群的一个分区投票。它被设计为支持多个集群 , 几乎零配置、无状态 —— 新集群会动态处理 , 外部主机上不需要配置文件。
外部主机仅要求能访问集群网络并提供 corosync-qnetd 包。我们为 Debian 系主机提供包 , 其他 Linux 发行版通常也有。
与 corosync 本身不同 , QDevice 通过 TCP/IP 连接到集群。守护进程也可运行在集群 LAN 之外 , 不受 corosync 的低延迟限制约束。
5.10.2.支持的部署 Supported Setups
我们对 偶数节点 的集群支持 QDevice, 并推荐在想要更高可用性的 2 节点集群中使用。对 奇数节点 的集群 , 目前不鼓励使用 QDevice。原因是 QDevice 为不同类型集群提供的票数不同 :偶数集群额外一票 , 仅提升可用性(QDevice 自身故障时集群退回到无 QDevice 状态)。
而奇数集群时 , QDevice 提供 (N-1) 票(N 为节点数)。这避免了 single-extra-vote 时的 split-brain , 允许除一个节点外其他所有节点(以及 QDevice)都故障。但这有两个缺点:
- 若 QNet 守护进程本身失败 , 任何其他节点再失败都会导致集群立即失去 quorum。例如 15 节点集群 , 原本可容忍 7 个节点失败;启用 QDevice 后 , 若 QDevice 自己故障 , 一个 节点失败都不允许 —— 此时 QDevice 近乎成为单点故障。
- 「可容忍除 1 节点外全部失败」听起来诱人 , 但实际可能导致 HA 服务大量恢复到单一剩余节点上 , 造成过载;另外 Ceph 在只剩
((N-1)/2)或更少节点时会停止提供服务。
若您理解上述缺陷与含义 , 可自行决定是否在奇数集群中使用。
5.10.3.QDevice-Net 配置 QDevice-Net Setup
我们建议任何向 corosync-qdevice 提供票数的守护进程都以非特权用户运行。 Proxmox VE 与 Debian 提供了已配置好的包。守护进程与集群之间的流量 必须加密 以确保 QDevice 集成的安全。
先在外部服务器上安装 corosync-qnetd:
external# apt install corosync-qnetd
再在所有集群节点上安装 corosync-qdevice:
pve# apt install corosync-qdevice
完成后确保所有集群节点在线 , 接着在其中一个 Proxmox VE 节点上运行:
pve# pvecm qdevice setup <QDEVICE-IP>
集群的 SSH 密钥将自动复制到 QDevice。
请先为外部服务器的 root 配置基于密钥的登录 , 或在配置阶段临时允许 root 密码登录。如在此阶段遇到 Host key verification failed., 可运行 pvecm updatecerts 修复。
所有步骤完成后会看到 「Done」。可用以下命令验证:
pve# pvecm status
...
Votequorum information
~~~~~~~~~~~~~~~~~~~~~~
Expected votes: 3
Highest expected: 3
Total votes: 3
Quorum: 2
Flags: Quorate Qdevice
Membership information
~~~~~~~~~~~~~~~~~~~~~~
Nodeid Votes Qdevice Name
0x00000001 1 A,V,NMW 192.168.22.180 (local)
0x00000002 1 A,V,NMW 192.168.22.181
0x00000000 1 Qdevice
QDevice 状态标志 通常有三列:
A/NA:Alive 或 Not Alive, 指示与外部corosync-qnetd的通信是否正常。V/NV:QDevice 是否为该节点投票。在节点间 corosync 连接中断 , 但两者都仍可与外部 qnetd 通信的 split-brain 场景下 , 只有一个节点会获得投票。MW/NMW:Master wins(MW)或否(NMW)。默认NMW(见votequorum_qdevice_master_wins(3))。NR:QDevice 未注册。
若 QDevice 列为 Not Alive(NA), 请确认外部服务器的 5403 端口(qnetd 默认端口)可通过 TCP/IP 到达!
5.10.4.常见问题 Frequently Asked Questions
Tie Breaking :若出现平局 —— 两个大小相同的集群分区彼此不可见但都能看到 QDevice —— QDevice 会随机选择其中之一并为其投票。
可能的负面影响 :偶数节点集群使用 QDevice 没有负面影响;若其失效 , 等同于无 QDevice。
QDevice 部署后添加 / 删除节点 :若要在已配置 QDevice 的集群中增减节点 , 需先移除 QDevice, 再正常增删 , 最后当集群再度为偶数节点时重新配置 QDevice。
移除 QDevice :若是通过官方 pvecm 工具添加的 , 可用:
pve# pvecm qdevice remove
5.11.Corosync 配置 Corosync Configuration
/etc/pve/corosync.conf 在 Proxmox VE 集群中扮演关键角色 —— 它控制集群成员与网络。更多信息参阅手册页:
man corosync.conf
对节点成员操作应始终使用 Proxmox VE 提供的 pvecm;其他更改可能需手动编辑该文件。以下是若干最佳实践。
5.11.1.编辑 corosync.conf Edit corosync.conf
编辑 corosync.conf 并不总是直截了当。每个集群节点上其实有两份 :一份在 /etc/pve/corosync.conf, 另一份在 /etc/corosync/corosync.conf。编辑集群文件系统中的那份会把变更传播到本地那份 , 但反之不行。
文件一有改动配置就会自动更新 , 这意味着 corosync 能整合的变更会立刻生效。因此为避免编辑中途保存触发意外生效 , 应 先复制再在副本上编辑:
cp /etc/pve/corosync.conf /etc/pve/corosync.conf.new
再用喜欢的编辑器(nano、 vim.tiny 等 Proxmox VE 节点预装编辑器)打开副本。
配置变更后请 始终递增 config_version , 否则可能出现问题。
修改完成后 , 再做一份当前可用配置的副本作为备份(当新配置应用失败时用):
cp /etc/pve/corosync.conf /etc/pve/corosync.conf.bak
再用新配置覆盖旧配置:
mv /etc/pve/corosync.conf.new /etc/pve/corosync.conf
用以下命令检查是否自动应用成功:
systemctl status corosync journalctl -b -u corosync
若未能自动应用 , 可重启 corosync:
systemctl restart corosync
出错时参考下一节排错。
5.11.2.排错 Troubleshooting
问题 :quorum.expected_votes must be configured
若 corosync 启动失败且系统日志中出现如下信息:
[...]
corosync[1647]: [QUORUM] Quorum provider: corosync_votequorum failed to initialize.
corosync[1647]: [SERV ] Service engine 'corosync_quorum' failed to load for reason
'configuration error: nodelist or quorum.expected_votes must be configured!'
[...]
说明配置中某个 ringX_addr 的主机名无法解析。
无 Quorum 时写配置 :若需在失去 quorum 的节点修改 /etc/pve/corosync.conf 且您确实知道在做什么:
pvecm expected 1
这会把期望票数设为 1, 让集群暂时进入 quorate 状态 , 方便您修复或回滚配置。若 corosync 根本无法启动 , 这还不够 —— 此时最好直接编辑本地副本 /etc/corosync/corosync.conf, 确保所有节点上该配置内容一致以避免 split-brain。
5.11.3.Corosync 配置术语表 Corosync Configuration Glossary
ringX_addr- 命名节点间 Kronosnet 连接的不同 link 地址。
5.12.集群冷启动 Cluster Cold Start
显然 , 所有节点离线时集群不可能有 quorum。断电后常见此状态。
为避免此情况(尤其要使用 HA 时), 始终建议配备不间断电源(UPS, 即「后备电池」)。
节点启动时会启动 pve-guests 服务并等待 quorum;一旦到达 quorum, 就启动所有设置了 onboot 标志的客户机。
上电或断电恢复时 , 各节点的引导速度可能不同。请记住 :直到 quorum 达成之前 , 客户机启动都会被延迟。
5.13.客户机 VMID 自动选择 Guest VMID Auto-Selection
创建新客户机时 , Web 界面会要求后端分配空闲 VMID。默认搜索范围为 100 到 1000000(低于 schema 允许的最大 VMID)。
有时管理员希望把新分配的 VMID 限定在单独范围 , 例如将临时 VM 与手动选择 VMID 的 VM 区分;或希望得到固定长度的 VMID —— 把下限设为 100000 就有更多空间。
可在 /etc/pve/datacenter.cfg 中设置下界、上界或两者(也可在 Web 的 Datacenter → Options 编辑)。
该范围仅用于 next-id API 调用 , 不是硬性限制。
5.14.客户机迁移 Guest Migration
把虚拟客户机迁到其他节点是集群的一项重要特性。迁移行为可通过 datacenter.cfg 控制 , 也可以在 API 或命令行中对具体迁移指定参数。
客户机是 在线还是离线, 是否持有本地资源(如本地磁盘), 会带来不同行为。虚拟机迁移详情见「QEMU/KVM 迁移」章节;容器迁移详情见「容器迁移」章节。
5.14.1.迁移类型 Migration Type
migration type 决定迁移数据走加密(secure)还是未加密(insecure)通道。若设为 insecure , 客户机的 RAM 内容也会以未加密方式传输 , 可能泄露客户机内部的敏感数据(例如密码或加密密钥)。
因此 , 若您对所用网络没有完全控制、无法保证无人窃听 , 强烈推荐使用 secure 通道。
存储迁移不受此设置影响 , 当前始终使用安全通道传输存储内容。
加密消耗相当算力 , 因此该设置常被改为 insecure 以获得更好性能。现代系统因硬件 AES 影响较小。性能影响在快速网络(10 Gbps 及以上)时最明显。
5.14.2.迁移网络 Migration Network
默认情况下 , Proxmox VE 将迁移流量发送到集群通信所用的网络。这并不理想 :既可能打扰敏感的集群流量 , 也可能该网络在节点上并非带宽最佳。
设置 migration network 参数可让所有迁移流量走专用网络;除内存外 , 对离线迁移的存储流量也生效。
迁移网络以 CIDR 记法 指定 , 好处是无需为每个节点设单独的 IP —— Proxmox VE 会根据指定的 CIDR 在目标节点上确定实际地址。要启用此特性 , 所指网络应使每个节点恰好有一个 IP 在其中。
示例 :假设有 3 节点 3 独立网络 —— 一个公网通信、一个集群通信、一个非常快速的网络 , 我们希望把最后者专用于迁移。网络配置可能如下:
iface eno1 inet manual
# public network
auto vmbr0
iface vmbr0 inet static
address 192.X.Y.57/24
gateway 192.X.Y.1
bridge-ports eno1
bridge-stp off
bridge-fd 0
# cluster network
auto eno2
iface eno2 inet static
address 10.1.1.1/24
# fast network
auto eno3
iface eno3 inet static
address 10.1.2.1/24
我们把 10.1.2.0/24 用作迁移网络。对单次迁移 , 在命令行使用 migration_network:
# qm migrate 106 tre --online --migration_network 10.1.2.0/24
若要把它设为集群所有迁移的默认网络 , 编辑 /etc/pve/datacenter.cfg 的 migration 属性:
# 使用专用迁移网络 migration: secure,network=10.1.2.0/24
在 /etc/pve/datacenter.cfg 中设置迁移网络时 , 迁移类型也必须设置。