{pve} 集群管理器 pvecm 是一个创建物理服务器组的工具。这样的一组被称为*集群*。我们使用 http://www.corosync.org [Corosync 集群引擎] 来实现可靠的组通信。集群中节点的数量没有明确的限制。实际上,实际可能的节点数可能会受到主机和网络性能的限制。目前(2021年),有报告称(使用高端企业级硬件的)集群在生产中有超过50个节点。

pvecm` 可用于创建新集群、将节点加入到集群、离开集群、获取状态信息以及执行各种其他与集群相关的任务。Proxmox 集群文件系统pmxcfs)用于透明地将集群配置分发到所有集群节点。

将节点分组到集群中具有以下优势:

  • 集中式的,基于网络的管理

  • 多主集群:每个节点都可以执行所有管理任务

  • 使用`pmxcfs`,一种基于数据库的文件系统,用于存储配置文件,并使用`corosync`在所有节点上实时复制。

  • 虚拟机和容器在物理主机之间的轻松迁移

  • 快速部署

  • 集群范围内的服务,如防火墙和高可用性

要求

  • 所有节点必须能够通过UDP端口5405-5412相互连接。 为了让corosync工作。

  • 日期和时间必须同步。

  • 需要在节点之间建立TCP端口22上的SSH隧道。

  • 如果你对高可用性感兴趣,你需要至少有三个节点来确保可靠的法定人数。所有节点应该有相同的版本。

  • 我们建议为集群流量使用专用的网络接口卡,特别是如果您使用共享存储的话。

  • 添加节点需要集群节点的根密码。

  • 虚拟机的在线迁移只有在节点拥有来自同一供应商的CPU时才得到支持。虽然在其他情况下可能也能工作,但这永远无法保证。

Note
无法将{pve} 3.x版本及更早版本的节点与{pve} 4.X版本的集群节点混合使用。
Note
虽然可以混合使用{pve} 4.4和{pve} 5.0节点,但这样做并不支持作为生产环境配置,只应该在从一个主版本升级到另一个主版本的整个集群升级期间临时进行。
Note
运行一个由 {pve} 6.x 和早期版本组成的集群是不可能的。集群协议(corosync)在 {pve} 6.x 和早期版本之间发生了根本性变化。{pve} 5.4 的 corosync 3 包仅用于升级程序升级到 {pve} 6.0。

准备节点

首先,在所有节点上安装 {pve}。确保每个节点都用最终的主机名和IP配置进行安装。在创建集群之后,不可以更改主机名和IP。

虽然通常会在 /etc/hosts 文件中列出所有节点名及其 IP 地址(或通过其他方式使它们的名称可以解析),但这并不是集群工作所必需的。然而,这样做可能会有用,因为你可以通过 SSH 从一个节点连接到另一个节点,使用更容易记住的节点名(另见 链接地址类型)。请注意,我们总是推荐在集群配置中通过 IP 地址引用节点。

创建一个集群

你可以通过控制台创建集群(通过`ssh`登录),或者使用{pve}网络界面(数据中心 → 集群)通过API进行。

Note
为你的集群使用一个独一无二的名字。这个名字之后不能更改。集群名称遵循与节点名称相同的规则。

通过Web界面创建

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

截至 {pve} 6.2 版本,集群中可以添加多达 8 个备用链接。要添加冗余链接,请点击“添加”按钮,然后从相应字段中选择链接编号和 IP 地址。在 {pve} 6.2 版本之前,要添加第二个作为备用的链接,您可以选中“高级”复选框并选择一个额外的网络接口(链接 1,另见 Corosync 冗余)。

Note
确保为集群通信选择的网络不用于任何高流量目的,如网络存储或实时迁移。虽然集群网络本身产生的数据量不大,但它对延迟非常敏感。查看完整的 集群网络要求

通过命令行创建

通过`ssh`登录到第一个{pve}节点并运行以下命令:

hp1# pvecm create CLUSTERNAME

要检查新集群的状态,请使用:

hp1# pvecm status

同一网络中的多个集群

在同一个物理或逻辑网络中可以创建多个集群。在这种情况下,每个集群必须有一个唯一的名字,以避免集群通信栈中可能出现的冲突。此外,这有助于避免人为混淆,使集群清晰可区分。

尽管corosync集群对带宽的需求相对较低,但数据包的延迟和每秒数据包数(PPS)是限制因素。同一网络中的不同集群可能会相互竞争这些资源,因此对于较大的集群使用独立的物理网络基础设施仍然是有意义的。

向集群添加节点

Caution
加入集群时,/etc/pve 中的所有现有配置都会被覆盖。特别地,加入节点不能持有任何客户机,否则可能会引起客户机ID冲突,节点还将继承集群的存储配置。如果要把已有客户机的节点加入集群,可以使用 vzdump 命令为每个客户机创建备份,然后在加入后恢复到不同的ID作为一种解决办法。如果节点的存储布局有所不同,你将需要重新添加节点的存储,并调整每个存储的节点限制,以反映存储实际可用于哪些节点。

通过图形用户界面将节点加入集群

登录到现有集群节点上的Web界面。在数据中心 → 集群下,点击顶部的*加入信息*按钮。然后,点击*复制信息*按钮。或者,也可以手动从’信息’字段中复制字符串。

接下来,登录到您想要添加的节点上的网络界面。在Datacenter → Cluster下,点击*Join Cluster*。用您之前复制的’Join Information’文本填写’Information’字段。加入集群所需的大多数设置将会自动填充。出于安全原因,集群密码需要手动输入。

Note
要手动输入所有必需的数据,可以取消勾选“辅助加入”复选框。

点击 加入 按钮后,群集加入过程将立即开始。节点加入群集后,其当前节点证书将被群集证书权威机构(CA)签名的证书所替代。这意味着当前会话在几秒钟后将停止工作。之后,您可能需要强制重新加载网页界面,并使用群集凭据重新登录。

现在你的节点应该在 Datacenter → Cluster 下可见。

通过命令行将节点加入集群

通过`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
~~~~~~~~~~~~~~~~~~
日期:             2021年9月14日 星期二 11:06:47
Quorum 提供者:   corosync_votequorum
节点数量:         4
节点 ID:         0x00000001
环 ID:           1.1a8
是否形成仲裁:    是

投票法定人数信息
~~~~~~~~~~~~~~~~~~~~~~
预期投票数:4
最高预期:4
总投票数:4
法定人数:3
标志:达到法定人数

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

成员资料
~~~~~~~~~~~~~~~~~~~~~~
    节点编号      投票数 名称
         1          1 hp1
         2          1 hp2 (本地)
         3          1 hp3
         4          1 hp4

添加具有独立集群网络的节点

当在拥有分离的集群网络中添加一个节点时,你需要使用’link0’参数来设置该网络上的节点地址:

# pvecm add IP-ADDRESS-CLUSTER --link0 LOCAL-IP-ADDRESS-LINK0

如果您想要使用Kronosnet传输层的内置冗余功能,也应该使用’link1’参数。

使用GUI,您可以在*Cluster Join*对话框中的相应’Link X’字段中选择正确的接口。

移除一个集群节点

Caution
在进行操作前仔细阅读流程,因为它可能并非你所想或所需。

将所有虚拟机从节点移走。确保您已经复制了任何想保留的本地数据或备份。此外,确保移除任何计划中的复制作业到要移除的节点。

Caution
在删除节点之前未能移除指向该节点的复制任务将导致复制任务无法移除。特别注意,如果复制的虚拟机被迁移,复制会自动切换方向,因此通过将复制的虚拟机从预定删除的节点迁移出去,复制任务将自动设置到那个节点。

在下面的例子中,我们将从集群中移除节点 hp4。

登录到一个*不同的*集群节点(不是hp4),并执行`pvecm nodes`命令来识别要移除的节点ID:

hp1# pvecm nodes

会员信息
~~~~~~~~~~~~~~~~~~~~~~
    节点ID      投票数 名称
         1          1 hp1 (本地)
         2          1 hp2
         3          1 hp3
         4          1 hp4

在这一点上,您必须关闭hp4并确保它不会再次以其当前配置(在网络中)开机。

Important
如上所述,关键是在移除节点*之前*必须先将其断电,并确保它在当前配置下不会再次在现有集群网络中上电。如果你按现状启动节点,集群可能会损坏,而且可能很难恢复到正常工作状态。

在关闭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

您需要提供要翻译的内容,才能进行翻译。

投票法定人数信息
~~~~~~~~~~~~~~~~~~~~~~
预期票数:       3
最高预期票数:   3
总票数:         3
法定人数:       2
标志:           达到法定人数

Membership information
~~~~~~~~~~~~~~~~~~~~~~
    Nodeid      Votes Name
0x00000001          1 192.168.15.90 (local)
0x00000002          1 192.168.15.91
0x00000003          1 192.168.15.92

如果出于任何原因,你希望这个服务器再次加入同一个集群,你必须:

  • 在上面进行{pve}的全新安装,

  • 然后按照前一节中的解释进行连接。

已删除节点的配置文件仍将保留在'/etc/pve/nodes/hp4’中。恢复任何您仍需要的配置,并在之后删除该目录。

Note
删除节点后,其SSH指纹仍将存在于其他节点的’known_hosts’中。如果在使用相同的IP或主机名重新加入节点后收到SSH错误,请在重新添加的节点上运行一次`pvecm updatecerts`来更新其在集群范围内的指纹。

不重新安装即可分离节点

Caution
这不是推荐的方法,请谨慎进行。如果您不确定,使用前面的方法。

您也可以在不从头开始重新安装的情况下,将一个节点从群集中分离出来。但是,在将节点从群集中移除后,它仍将访问任何共享存储。在开始从群集中移除节点之前,必须解决这个问题。一个{pve}群集不能与另一个群集共享完全相同的存储,因为存储锁定无法跨群集边界工作。此外,这还可能导致VMID冲突。

建议您创建一个新的存储空间,只有您希望隔离的节点能够访问。这可以是NFS上的一个新导出,或者一个新的Ceph池等等。重要的是确保完全相同的存储不会被多个集群访问。设置好这个存储后,将所有数据和虚拟机从节点移动到这个新存储中。然后,您就可以准备将该节点从集群中分离出来了。

Warning
确保所有共享资源都被清晰地分隔!否则你将会遇到冲突和问题。

首先,在节点上停止 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

如果命令因剩余节点中的法定人数丢失而失败,您可以将预期的投票数设置为1作为一种解决方法:

预期为1

然后重复执行 pvecm delnode 命令。

现在切换回到分离的节点,并删除其上的所有剩余集群文件。这确保了该节点可以再次无问题地添加到另一个集群中。

rm /var/lib/corosync/*

由于其他节点的配置文件仍然存在于集群文件系统中,您可能也想清理这些文件。在完全确定您有正确的节点名称后,您可以简单地从'/etc/pve/nodes/NODENAME’递归删除整个目录。

Caution
节点的SSH密钥将保留在’authorized_key’文件中。这意味着节点仍然可以通过公钥认证相互连接。您应该通过从'/etc/pve/priv/authorized_keys’文件中删除相应的密钥来解决这个问题。

法定人数

{pve}使用基于法定人数的技术来在所有集群节点间提供一致的状态。

法定人数是分布式事务在分布式系统中执行操作前必须获得的最小投票数。

— 来自维基百科
法定人数(分布式计算)

在网络分区的情况下,状态变更要求大多数节点在线。如果集群失去法定人数,它会切换到只读模式。

Note
默认情况下,{pve}为每个节点分配一个单独的投票。

集群网络

群集网络是群集的核心。通过它发送的所有消息都必须按照各自的顺序可靠地传递给所有节点。在 {pve} 中,这部分工作由 corosync 完成,它是一个高性能、低开销、高可用性开发工具包的实现。它服务于我们的分散式配置文件系统(pmxcfs)。

网络要求

{pve} 集群栈需要所有节点之间具有低于5毫秒(局域网性能)的可靠网络延迟才能稳定运行。虽然在节点数量较少的设置中,高延迟的网络 可能 工作,但这并不保证,而且当节点超过三个并且延迟大约超过10毫秒时,正常工作的可能性就变得相当小了。

网络不应被其他成员过度使用,因为尽管corosync不需要大量带宽,但它对延迟波动很敏感;理想情况下,corosync应该运行在自己的物理隔离网络上。特别是不要将corosync和存储使用相同的网络(除非在冗余配置中作为潜在的低优先级备份)。

在设置集群之前,最好先检查网络是否适合此目的。为了确保节点能够在集群网络上相互连接,您可以使用`ping`工具测试它们之间的连通性。

如果{pve}防火墙已启用,将自动生成corosync的ACCEPT规则 - 不需要手动操作。

Note
Corosync在3.0版本之前使用了多播(在{pve} 6.0中引入)。现代版本依赖于https://kronosnet.org/[Kronosnet]来进行集群通信,目前,它只支持常规的UDP单播。
Caution
您仍然可以通过将传输设置为`udp`或`udpu`在您的corosync.conf中启用组播或旧版单播,但请记住,这将禁用所有加密和冗余支持。因此,不推荐这样做。

分离集群网络

当不使用任何参数创建集群时,corosync集群网络通常与Web界面和虚拟机的网络共享。根据您的设置,甚至存储流量也可能通过同一网络发送。建议更改此设置,因为corosync是一个时间敏感的实时应用程序。

设置一个新网络

首先,你需要设置一个新的网络接口。它应该位于一个物理分离的网络上。确保你的网络满足集群网络要求。

创建时分离

通过 pvecm create 命令的 linkX 参数可以实现,该命令用于创建一个新的集群。

如果你已经设置了一个额外的NIC,其静态地址为10.10.10.1/25,并且想要通过这个接口发送和接收所有群集通信,你需要执行:

pvecm create test --link0 10.10.10.1

要检查一切是否正常运行,请执行:

systemctl status corosync

随后,按照上述描述进行,以添加具有分离的群集网络的节点

在群集创建后分离

如果你已经创建了一个集群而想将其通讯切换到另一个网络,而不是重建整个集群,你可以这样做。这一改变可能会导致集群在短时间内失去法定人数,因为节点必须重新启动corosync并且在新网络上逐个启动。

首先检查如何编辑corosync.conf文件的xref:pvecm_edit_corosync_conf链接。然后,打开它,你应该会看到一个类似于以下内容的文件:

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 链接地址。名称“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开始再次工作,请也在所有其他节点上重启它。然后,它们将一个接一个地通过新网络加入集群成员。

Corosync 地址

一个corosync链接地址(为了向后兼容,在`corosync.conf`中被标记为’ringX_addr')可以通过两种方式指定:

  • IPv4/v6 地址可以被直接使用。它们被推荐使用,因为它们是静态的,通常不会轻易改变。

  • 主机名将通过使用`getaddrinfo`来解析,这意味着默认情况下,如果IPv6地址可用,将首先使用IPv6地址(也可以参见`man gai.conf`)。特别是在将现有集群升级到IPv6时,请牢记这一点。

Caution
主机名应该谨慎使用,因为它们解析的地址可以在不接触corosync或其运行的节点的情况下进行更改 - 这可能导致一个地址在没有考虑到corosync的影响就被更改的情况。

如果偏好使用主机名,建议为corosync指定一个单独的、静态的主机名。同时,确保集群中的每个节点都能正确解析所有主机名。

自{pve} 5.1版本起,尽管得到支持,但主机名将在输入时被解析。配置中只保存解析后的IP地址。

加入集群的节点如果是在早期版本上运行,很可能在`corosync.conf`文件中仍使用它们未解析的主机名。正如上面提到的,用IP地址或一个单独的主机名来替换它们可能是一个好主意。

Corosync 冗余

Corosync默认通过其集成的Kronosnet层支持冗余网络功能(在传统的udp/udpu传输上不支持)。可以通过指定多于一个的链接地址来启用,可以通过`pvecm`的'--linkX’参数,在GUI中作为Link 1(在创建集群或添加新节点时)或者在`corosync.conf`中指定多于一个的’ringX_addr’来实现。

Note
为了提供有效的故障转移,每个链接应该使用自己的物理网络连接。

链接的使用根据优先级设置。您可以通过在`corosync.conf`的相应接口部分设置`knet_link_priority`来配置此优先级,或者,更推荐的是,在使用`pvecm`创建集群时使用`priority`参数。

 # pvecm create CLUSTERNAME --link0 10.10.10.1,priority=15 --link1 10.20.20.1,priority=20

这将导致先使用’link1',因为它有更高的优先级。

如果没有手动配置优先级(或两个链接具有相同的优先级),链接将按照它们的编号顺序使用,编号较小的具有更高的优先级。

即使所有链接都在工作,只有优先级最高的链接会看到corosync流量。链接优先级不能混合,这意味着不同优先级的链接将无法相互通信。

由于低优先级的链接在所有高优先级链接失败之前不会看到流量,因此将用于其他任务(虚拟机、存储等)的网络指定为低优先级链接成为一种有用的策略。如果情况变得极其糟糕,一个延迟更高或更拥堵的连接可能比根本没有连接要好。

向现有集群添加冗余链接

要想在运行配置中添加新链接,首先检查如何编辑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是否已加载新链接:

journalctl -b -u corosync

暂时断开某个节点上的旧链接,并确保其在断开连接时状态仍保持在线,这样测试新链接可能是个好主意:

pvecm状态

如果你看到一个健康的集群状态,这意味着你的新链接正在被使用。

SSH在{pve}集群中的作用

{pve}利用SSH隧道来实现各种功能。

  • 代理控制台/Shell会话(节点和访客)

    当在连接到节点A时使用节点B的shell,它会连接到节点A上的一个终端代理,该代理通过一个非交互式SSH隧道依次连接到节点B上的登录shell。

  • 在“安全”模式下的虚拟机和容器技术内存及本地存储迁移。

    在迁移过程中,将建立一个或多个SSH隧道,用于源节点和目标节点之间的迁移信息交换以及内存和磁盘内容的传输。

  • 存储复制

Important
由于自动执行 .bashrc 及其兄弟文件导致的陷阱

如果您有一个自定义的`.bashrc`文件,或者类似的文件被配置的shell在登录时执行,`ssh`会在会话成功建立后自动运行它。这可能导致一些意外行为,因为那些命令可能会在上述任何操作中以root权限执行。这可能导致潜在的问题副作用!

为了避免此类复杂情况,建议在 /root/.bashrc 中添加一个检查,以确保会话是交互式的,并且只有在这种情况下才运行 .bashrc 命令。

你可以在你的 .bashrc 文件开头加入这段代码:

# Early exit if not running interactively to avoid side-effects!
case $- in
    *i*) ;;
      *) return;;
esac

Corosync 外部投票支持

这一部分描述了如何在{pve}集群中部署一个外部投票器的方式。配置后,集群可以在不违反集群通信的安全属性的情况下,承受更多的节点故障。

为了使这个工作,涉及到两项服务:

  • 在每个{pve}节点上运行的一个QDevice守护进程

  • 一个在独立服务器上运行的外部投票守护进程

因此,即使在较小的设置中(例如2+1节点),您也可以实现更高的可用性。

QDevice技术概述

Corosync Quorum Device(QDevice)是一个在每个集群节点上运行的守护进程。它根据外部运行的第三方仲裁者的决定,向集群的法定人数(quorum)子系统提供配置数量的投票权。它的主要用途是允许集群承受比标准法定人数规则允许的更多节点故障。这可以安全地完成,因为外部设备能够看到所有节点,因此只选择一组节点来给予其投票权。只有在这组节点在接收到第三方投票后可以再次达到法定人数(quorum)的情况下,才会这样做。

目前,只有“QDevice Net”作为第三方仲裁者得到支持。这是一个守护程序,如果它能够通过网络连接到分区成员,就会为集群分区提供一个投票。在任何时间,它只会给集群的一个分区投票。它旨在支持多个集群,几乎不需要配置和状态。新集群被动态处理,运行QDevice的主机上不需要配置文件。

外部主机唯一的要求是它需要访问群集的网络,并且需要有corosync-qnetd包可用。我们为基于Debian的主机提供了一个包,其他Linux发行版也应该通过各自的包管理器提供一个包。

Note
与corosync本身不同,一个QDevice通过TCP/IP连接到集群。该守护进程也可以运行在集群的局域网之外,并且不受corosync的低延迟需求的限制。

支持的设置

我们支持在具有偶数数量的节点的集群中使用QDevices,并推荐2节点集群使用它,如果它们需要提供更高的可用性。对于节点数为奇数的集群,我们目前不鼓励使用QDevices。这样做的原因在于QDevice为每种类型的集群提供的投票差异。拥有偶数节点的集群会获得额外的一票,这仅仅增加了可用性,因为如果QDevice自身出现故障,你将处于和没有QDevice完全相同的位置。

在另一方面,对于奇数个集群大小,QDevice提供 (N-1) 票数 —— 其中 N 对应于集群节点计数。这种替代行为是有道理的;如果它只有一个额外的投票,集群可能会陷入脑裂情况。这个算法允许所有节点但一个(自然还有QDevice本身)失败。然而,这样做有两个缺点:

  • 如果QNet守护进程本身失败了,那么其他任何节点都不能失败,否则集群将立即失去法定人数。例如,在一个有15个节点的集群中,在集群变得无法形成法定人数之前,可以有7个节点失败。但是,如果这里配置了QDevice并且它本身失败了,那么15个节点中的任何一个节点都不能失败。在这种情况下,QDevice几乎就像一个单点故障。

  • 事实上,除了一个节点加上QDevice之外,所有节点都可能失败这一点乍听起来很有希望,但这可能导致大量HA服务恢复,这可能会使剩余的唯一节点过载。此外,如果只剩下‘((N-1)/2)’个或更少的节点在线,Ceph服务器将停止提供服务。

如果你理解了这项技术在奇数节点集群配置中使用的缺点和影响,你可以自己决定是否要使用这项技术。

QDevice-Net 设置

我们推荐以非特权用户身份运行提供投票给corosync-qdevice的任何守护进程。{pve}和Debian提供了一个已经配置为这样做的包。守护进程与集群之间的流量必须加密,以确保Q设备在{pve}中的安全可靠集成。

首先,在你的外部服务器上安装 corosync-qnetd

external# apt install corosync-qnetd

以及所有集群节点上的 corosync-qdevice

pve# apt install corosync-qdevice

完成此操作后,请确保集群中的所有节点都在线。

您现在可以通过在其中一个 {pve} 节点上运行以下命令来设置您的 QDevice:

pve# pvecm qdevice setup <QDEVICE-IP>

集群中的SSH密钥将自动复制到QDevice。

Note
确保为外部服务器上的root用户设置基于密钥的访问权限,或者在设置阶段暂时允许使用密码登录root。如果在此阶段收到如’Host key verification failed.'的错误,运行`pvecm updatecerts`可能会解决这个问题。

在所有步骤都成功完成之后,你会看到“完成(Done)”字样。你可以用以下方法验证QDevice是否已经设置:

pve# pvecm status

您需要提供要翻译的内容,才能进行翻译。

投票仲裁信息
~~~~~~~~~~~~~~~~~~~~~
预期投票数:3
最高预期:3
总投票数:3
法定人数:2
标志:已达法定人数 Q设备

会员信息
~~~~~~~~~~~~~~~~~~~~~~
    节点ID      票数    Q设备 名称
    0x00000001      1    A,V,NMW 192.168.22.180 (本地)
    0x00000002      1    A,V,NMW 192.168.22.181
    0x00000000      1            Q设备

QDevice状态标志

如上所示,QDevice的状态输出通常包含三列:

  • A` / NA: 存活或非存活。指示与外部的通讯是否存活。 corosync-qnetd` 守护进程正在运行。

  • V` / NV: 如果QDevice将为节点投票。在脑裂情况下 在此情况下,节点之间的corosync连接已断开,但它们仍然可以与外部的`corosync-qnetd`守护进程通信,只有一个节点会获得投票权。

  • MW` / NMW:主控胜利(MV)或不胜利(NMW)。默认为`NMW`,请参见 脚注:[votequorum_qdevice_master_wins 手册页面 https://manpages.debian.org/bookworm/libvotequorum-dev/votequorum_qdevice_master_wins.3.en.html]。

  • NR`: QDevice未注册。

Note
如果您的QDevice显示为`Not Alive`(上述输出中为`NA`),请确保您的外部服务器的端口`5403`(qnetd服务器的默认端口)可以通过TCP/IP访问!

常见问题解答

平局打破

在出现并列的情况下,如果两个相同大小的集群分区互相看不见,但能够看到QDevice,那么QDevice将随机选择其中一个分区,并给予它一票。

可能的负面影响

对于节点数为偶数的集群,在使用QDevice时没有负面影响。如果它无法工作,那就等同于根本没有使用QDevice。

在QDevice设置后添加/删除节点

如果您想要在配置了QDevice的群集中添加一个新节点或删除一个现有节点,您需要先移除QDevice。之后,您可以正常添加或移除节点。一旦您再次拥有一个节点数量为偶数的群集,您可以按照之前描述的方式再次设置QDevice。

移除Q设备

如果你使用官方的 pvecm 工具添加了 QDevice,你可以通过运行以下命令来移除它:

pve# pvecm qdevice remove

Corosync配置

/etc/pve/corosync.conf` 文件在 {pve} 集群中扮演着核心角色。它控制着集群成员和其网络。有关它的更多信息,请查阅 corosync.conf 手册页面:

man corosync.conf

对于节点成员身份管理,你应该始终使用{pve}提供的`pvecm`工具。对于其他更改,你可能需要手动编辑配置文件。以下是一些进行此操作的最佳实践提示。

编辑corosync.conf

编辑corosync.conf文件并不总是非常直观。每个集群节点上有两个,一个在 /etc/pve/corosync.conf,另一个在 /etc/corosync/corosync.conf。编辑我们集群文件系统中的那个会将改动传播到本地的那个,但反之则不行。

配置会在文件发生变化时自动更新。这意味着可以集成到正在运行的corosync中的更改将立即生效。因此,你应该总是先做一个副本然后编辑副本,以避免在编辑文件保存时触发无意的更改。

cp /etc/pve/corosync.conf /etc/pve/corosync.conf.new

然后,使用您最喜欢的编辑器打开配置文件,比如预装在每个{pve}节点上的`nano`或者`vim.tiny`。

Note
在配置更改后总是递增’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

出现错误时,请查看下方的故障排除部分。

故障排除

问题:quorum.expected_votes 必须被配置

当corosync开始出现故障并且你在系统日志中收到以下消息时:

[...]
corosync[1647]:  [QUORUM] Quorum provider: corosync_votequorum初始化失败。
corosync[1647]:  [SERV  ] 服务引擎'corosync_quorum'加载失败,原因是
    '配置错误:必须配置nodelist或quorum.expected_votes!'
[...]

这意味着在配置中为corosync的’ringX_addr’设置的主机名无法被解析。

当不构成法定人数时写入配置

如果您需要在没有法定人数的节点上更改'/etc/pve/corosync.conf',并且您了解自己在做什么,请使用:

预期为1

这将预期的投票计数设置为1并使集群达到法定人数。然后,您可以修正配置,或将其还原回上一个正常工作的备份。

如果corosync无法再次启动,这还不够。在这种情况下,最好编辑位于'/etc/corosync/corosync.conf’的corosync配置的本地副本,以便corosync能够再次启动。确保在所有节点上,这个配置具有相同的内容,以避免发生脑裂情况。

Corosync配置术语表

环X地址

这标记了节点之间Kronosnet连接的不同链接地址。

集群冷启动

很明显,当所有节点都离线时,集群是没有法定人数的。这在断电后是一个常见情况。

Note
使用不间断电源(简称 "UPS",也称为 "电池备用")始终是一个好主意,以避免这种状态,特别是如果你需要高可用性(HA)。

在节点启动时,`pve-guests`服务会启动并等待法定人数(quorum)。一旦达到法定人数(quorate),它会启动所有设置了`onboot`标志的客户机。

当您开启节点,或者在停电后电力恢复时,可能会有一些节点比其他节点启动得更快。请记住,在达到法定人数之前,客户机的启动将会延迟。

客户端虚拟机ID自动选择

当创建新的客户时,Web界面将自动请求后端提供一个空闲的VMID。默认搜索范围是`100`到`1000000`(低于架构强制执行的最大允许VMID)。

有时管理员希望在不同的范围内分配新的VMID,例如为了方便地将临时VM与手动选择VMID的VM分开。其他时候,他们只是希望提供一个稳定长度的VMID,将下界设置为例如`100000`,就为此提供了更多的空间。

为了适应这一用例,可以通过`datacenter.cfg`配置文件设置下限、上限或两者均有的边界,该配置文件可以在网页界面的’数据中心' → '选项’下编辑。

Note
范围只用于下一个id的API调用,所以它不是一个硬性限制。

客户迁移

在集群中,将虚拟宾客迁移到其他节点是一个有用的功能。有一些设置可以控制此类迁移的行为。这可以通过配置文件 datacenter.cfg 来完成,或者通过 API 或命令行参数针对特定迁移进行操作。

客人是在线还是离线,或者是否拥有本地资源(如本地磁盘)都会产生不同影响。

有关虚拟机迁移的详情,请参见QEMU/KVM 迁移章节

关于容器迁移的详细信息,请参见容器迁移章节

迁移类型

迁移类型定义了迁移数据是否应通过加密(安全)通道还是非加密(不安全)通道发送。将迁移类型设置为`不安全`意味着虚拟客户机的RAM内容也会未加密地传输,这可能导致来自客户机内部的关键数据(例如,密码或加密密钥)的信息泄露。

因此,如果您无法完全控制网络并且无法保证没有人在窃听,我们强烈建议使用安全通道。

Note
存储迁移不遵循此设置。目前,它总是通过安全通道发送存储内容。

加密需要大量的计算能力,因此这个设置经常被改为`insecure`以获取更好的性能。在现代系统中影响较低,因为它们在硬件中实现了AES加密。在快速网络中性能影响尤为明显,那里你可以传输10 Gbps或更高的速度。

移民网络

默认情况下,{pve} 使用用于集群通信的网络来发送迁移流量。这并不是最佳选择,因为敏感的集群流量可能会被干扰,而且这个网络可能不是节点上可用的最佳带宽。

设置迁移网络参数可以使用专用网络来处理所有的迁移流量。除了内存之外,这还影响离线迁移的存储流量。

迁移网络被设置为使用CIDR表示法的网络。这样做的好处是你不需要为每一个节点设置单独的IP地址。{pve}可以从CIDR形式指定的网络中确定目的节点上的真实地址。为了启用这一点,必须指定网络,以便每个节点在相应网络中恰好有一个IP地址。

例子

我们假设有一个由三个节点组成的设置,它们连接着三个独立的网络。一个用于与因特网的公共通讯,一个用于集群通讯,以及一个非常快速的网络,我们希望将其用作专用的迁移网络。

这样的设置的网络配置可能如下所示:

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`属性:

# 使用专用迁移网络
迁移:安全,网络=10.1.2.0/24
Note
当在 /etc/pve/datacenter.cfg 中设置迁移网络时,必须始终设置迁移类型。