Chapter 05 · Cluster Manager

第 5 章 集群管理器

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。所有节点版本应一致。
NOTE

对较小的 2 节点集群 , 可使用 QDevice 提供第 3 票(见 §5.10)。

  • 我们 推荐为集群流量使用专用物理 NIC
NOTE

Proxmox VE 集群通信使用 Corosync 协议 , 对低且稳定的延迟敏感 , 但带宽要求不高 , 大多数情况下一块专用 1 Gbit NIC 就足够。这有助于避免其他服务占用全部可用带宽 , 进而增加 Corosync 包的延迟。

  • 为集群流量额外配置链路 , 可在专网故障时提供冗余。
NOTE

Corosync 最多支持 8 条链路。

NOTE

要实现可靠的 Corosync 冗余 , 必须至少有一条链路位于 不同的物理网络。这能在专网中断时让集群通信继续存活。

NOTE

仅用一条 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 创建集群。

NOTE

请为您的集群 使用唯一名称。集群名之后不可更改 , 并遵循与节点名相同的规则。

5.3.1.通过 Web GUI 创建 Create via Web GUI

GUI 创建集群

Datacenter → Cluster 下 , 点击 Create Cluster。输入集群名称 , 并从下拉列表中选择一个网络连接作为主集群网络(Link 0)。默认值为该节点主机名解析得到的 IP。

自 Proxmox VE 6.2 起 , 可为集群添加最多 8 条后备链路。要添加冗余链路 , 点击 Add 按钮 , 并从相应字段选择链路编号与 IP 地址。 6.2 之前的版本需勾选 Advanced 并选择额外网卡(Link 1, 另见 §5.8「Corosync 冗余」)。

NOTE

确保用于集群通信的网络 不用于 高流量用途(例如网络存储或在线迁移)。集群网络本身数据量很小 , 但对延迟极敏感。请参阅完整的「集群网络要求」。

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

WARN

加入集群时 , /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 → ClusterJoin Cluster。把之前复制的 Join Information 粘贴到 Information 字段 , 大多数加入集群所需设置会自动填好。出于安全考虑 , 集群密码需要手动输入。

NOTE

如需手动填写全部所需数据 , 可取消勾选 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

WARN

在继续之前请 仔细阅读此过程, 它可能并不是您想要或需要的。

把节点上的所有虚拟机迁走 , 并确保已备份所有要保留的本地数据 / 备份。此外 , 请 移除指向待删除节点的所有计划复制作业

WARN

未先移除复制作业就删除节点 , 会导致复制作业无法再删除。注意 :复制方向在被复制的 VM 迁移时会自动切换 , 因此把已配置复制的 VM 从将被删除的节点迁走 , 反而会把复制作业指向该节点。

若待删除节点上已配置 Ceph

  • 确保仍有足够数量的 Proxmox VE 节点带有处于 upin 状态的 OSD。
NOTE

默认 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, 并确保其不会以当前配置在(集群)网络中再次上电。

WARN

如上所述 , 在移除之前必须关闭节点, 且保证其不会以当前配置在原集群网络上再次上电。否则集群可能损坏且难以恢复。

关闭 hp4 后 , 即可安全地从集群中移除:

hp1# pvecm delnode hp4
 Killing node 4
NOTE

此时可能出现 Could not kill node (error = CS_ERR_NOT_EXIST)。这并非真正删除失败 , 而是 corosync 尝试 「杀死」 一个已离线节点时的错误 , 可忽略。

再用 pvecm nodespvecm 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

若出于任何原因 , 您想让该服务器再次加入同一个集群 , 必须:

  1. 在其上 全新安装 Proxmox VE;
  2. 按上一节所述加入集群。

已移除节点的配置文件仍保留在 /etc/pve/nodes/hp4, 如需可从中取回所需配置 , 之后再删除该目录。

NOTE

移除后 , 节点的 SSH 指纹仍残留在其他节点的 known_hosts 中。若以相同 IP 或主机名重新加入时出现 SSH 错误 , 在重新加入后的节点上运行一次 pvecm updatecerts 即可更新全集群指纹。

5.5.1.不重装即分离节点 Separate a Node Without Reinstalling

WARN

这不是推荐方式 , 请谨慎操作。如不确定 , 请使用前一种方法。

您也可以不重装就把节点从集群中分离。但移除后该节点仍会拥有共享存储的访问权限 , 必须先处理这一问题。 Proxmox VE 集群不能与另一集群共享完全相同的存储 , 因为存储锁无法跨集群边界工作 , 还可能导致 VMID 冲突。

建议创建仅待分离节点能访问的新存储 , 例如 NFS 上的新 export 或新的 Ceph 池。关键是 完全相同的存储不能被多个集群访问。设置好新存储后 , 把该节点上的所有数据与 VM 迁移到新存储。然后才可把节点从集群分离。

WARN

务必彻底分离所有共享资源 , 否则会产生冲突与问题。

先停止该节点上的 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 即可。

WARN

该节点的 SSH 密钥仍留在 authorized_keys 中 , 节点彼此仍可用公钥登录。应从 /etc/pve/priv/authorized_keys 删除相应密钥。

5.6.仲裁(Quorum) Quorum

Proxmox VE 使用 基于仲裁(quorum) 的技术来在所有集群节点间保持一致状态。

Quorum 是分布式系统中为允许执行某项操作 , 一次分布式事务必须获得的最少票数。

— Wikipedia «Quorum (distributed computing)»

网络分区时 , 状态变更要求 多数节点在线。一旦失去 quorum, 集群会切换到只读模式。

NOTE

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 规则会自动生成 , 无需手工配置。

NOTE

Corosync 在 3.0 版本(Proxmox VE 6.0 引入)之前使用多播 , 现代版本依赖 Kronosnet 进行集群通信 , 目前只支持普通 UDP 单播。

NOTE

仍可在 corosync.conf 中把 transport 设为 udpudpu 以启用多播或传统单播 , 但这会 禁用 全部加密与冗余支持 , 不推荐

5.7.2.在 Bond 上运行 Corosync Corosync Over Bonds

建议 :至少为主 Corosync 链路使用一块专用物理 NIC(见 §5.1「要求」), bond 可作为额外链路以增强冗余。用 bond 承载 Corosync 流量时 , 须注意以下事项:

  • bond 模式 active-backup 在某些故障场景下可能不提供预期的冗余 , 详见下文。
  • 建议不要 对 Corosync 使用 balance-rrbalance-xorbalance-tlbbalance-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-rrbalance-xorbalance-tlbbalance-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 createlinkX 参数。假设已在静态地址 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
  }
}
NOTE

ringX_addr 实际上指 corosync 的 link 地址。 「ring」 是旧版 corosync 遗留的名字 , 为向后兼容保留。

首先 , 若节点条目里没有 name 属性则添加 , 其值必须与节点名一致。然后把所有节点的 ring0_addr 替换为新网络上的地址(可用 IP 或主机名;用主机名时要确保在所有节点都可解析 , 见「链路地址类型」)。

本例把集群通信切换到 10.10.10.0/25, 因此相应修改各节点 ring0_addr

NOTE

同一过程也可用于更换其他 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 时尤其要注意。
WARN

使用主机名需谨慎 , 因为它所解析到的地址可能在不修改 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

NOTE

要提供有效的故障转移 , 每条链路都应位于各自的物理网络上

下述示例假定每个节点各有一个 10.10.10.0/2510.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.11.1 如何编辑 corosync.conf。然后给 nodelist 段的每个节点加一条新 ringX_addr , 确保 X 对所有节点一致且该编号唯一;再在 totem 段加一个 interfaceX 用上一步选的编号。

假设新链路编号为 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;
  • rootauthorized_keys 指向 /etc/pve/priv/authorized_keys, 合并集群内所有已授权密钥;
  • sshd 允许 root 用密码登录。
NOTE

较旧系统 /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 发行版通常也有。

NOTE

与 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。

NOTE

请先为外部服务器的 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 未注册。
NOTE

若 QDevice 列为 Not AliveNA), 请确认外部服务器的 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

再用喜欢的编辑器(nanovim.tiny 等 Proxmox VE 节点预装编辑器)打开副本。

IMP

配置变更后请 始终递增 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。断电后常见此状态。

NOTE

为避免此情况(尤其要使用 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 编辑)。

NOTE

该范围仅用于 next-id API 调用 , 不是硬性限制。

5.14.客户机迁移 Guest Migration

把虚拟客户机迁到其他节点是集群的一项重要特性。迁移行为可通过 datacenter.cfg 控制 , 也可以在 API 或命令行中对具体迁移指定参数。

客户机是 在线还是离线, 是否持有本地资源(如本地磁盘), 会带来不同行为。虚拟机迁移详情见「QEMU/KVM 迁移」章节;容器迁移详情见「容器迁移」章节。

5.14.1.迁移类型 Migration Type

migration type 决定迁移数据走加密(secure)还是未加密(insecure)通道。若设为 insecure , 客户机的 RAM 内容也会以未加密方式传输 , 可能泄露客户机内部的敏感数据(例如密码或加密密钥)。

因此 , 若您对所用网络没有完全控制、无法保证无人窃听 , 强烈推荐使用 secure 通道。

NOTE

存储迁移不受此设置影响 , 当前始终使用安全通道传输存储内容。

加密消耗相当算力 , 因此该设置常被改为 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.cfgmigration 属性:

# 使用专用迁移网络
migration: secure,network=10.1.2.0/24
NOTE

/etc/pve/datacenter.cfg 中设置迁移网络时 , 迁移类型也必须设置