Clustering

备注

This feature is currently a technical preview with the following temporary limitation:

  • Active/passive setup to support two-node clusters, either by utilizing etcd Learner or Mirror, is not yet available. Use a Witness node instead.

  • 该功能尚未在足够数量的生产环境中得到验证,可能存在漏洞。

NetHSM 4.0 以后的版本支持集群,可在多个 NetHSM 之间直接同步数据。这支持高频率的密钥生成,实现了高可用性和负载平衡。NetHSM 集群基于`etcd<https://etcd.io>`__,它使用`Raft 共识算法<https://raft.github.io/>`__,以实现强一致性。这可以确保所有 NetHSM 中的数据(如密钥)在任何时候都是正确的。

在建立 NetHSM 集群之前,请先熟悉这项技术及其限制条件,以避免意外中断和数据丢失。除本文档外,您可能还需要参考`etcd 的文档<https://etcd.io/docs/latest/learning/>`__。

Operational Redundancy

我们将 "节点 "称为预计成为群集一部分的 NetHSM。一个由 ``N``**节点组成的群集将继续运行,只要至少有** ``(N/2)+1``**节点是健康和可连接的。** 健康、可连接节点的最小数量称为**法定人数** 。

在低于此阈值的集群中(例如由于网络问题),无法选出领导者,且每个节点上的``etcd``本地实例将无法执行读写操作。这意味着会出现以下情况。

一个节点宕机,但仍能达到法定人数

在 3 节点集群中,如果一个节点出现故障(崩溃或因网络状况无法访问),其他两个节点将继续工作并为请求提供服务。

If the failed node is still healthy (e.g. it was just a network problem), it will be in the Failed state while isolated, refusing normal operations (not even read-only).

However if the node recovers, it will cleanly resynchronize with the rest of the cluster and exit the Failed state, resuming normal operation without losing data.

如果它无法恢复,就必须将其从集群中移除` <clustering.html#removing-a-node-cleanly>` __,并要么进行`恢复<clustering.html#recovering-a-failed-node>`__ 以访问其数据(但它将不再是集群的一部分),要么恢复出厂设置并从头开始重新加入集群。

发生网络分区,但仍能达到法定人数

这只是前一种情况的概括。在一个 5 节点集群中,3 个节点位于一个物理位置 A,2 个节点位于另一个物理位置 B:

  • 位置 A 中的 3 个节点符合法定人数(本例中为 3),因此它们继续运行。

  • The 2 nodes in location B are not meeting the quorum (still 3), so they will enter the Failed state and stop operating (even read-only).

  • 如果网络问题得到解决,这 2 个节点将与其他 3 个节点顺利连接。

换句话说,在最坏情况下的网络分区(在节点数量为奇数的集群中),集群中较大的那半部分将保持正常运行,而较小的那半部分则无法运行,直到分区问题得到解决为止。

法定人数永久丧失

A failure causing all subsets of the cluster to lose quorum will render the cluster completely inoperable (all remaining nodes will be in the Failed state), unless the failure is resolved. In this case, manual recovery must be performed.

例如,在一个 2 节点集群(法定人数为 2)中,如果单个节点发生故障,就会出现这种情况。在这种情况下,事后无法将故障节点从群集中清除,因为剩余的健康节点已经无法运行,因为它已经失去了法定人数。

因此,建议集群中的节点数始终为奇数,并经常备份。

To be clear, temporarily losing quorum (for example, if you are restarting all nodes of a cluster together, or a temporary network failure isolates nodes) is not a problem: once enough nodes are reconnected (without having to manually re-join) to reach quorum, the cluster will resume its normal operation. Only permanent failures such as network partitions, network misconfigurations, authentication issues or hardware failures, will require manual action.

更多信息,请参阅`etcd 的常见问题<https://etcd.io/docs/v3.6/faq/#why-an-odd-number-of-cluster-members>`__。

2 节点集群

目前还不支持双节点主动/被动集群,将在未来版本中添加。我们建议引入第 3 个节点,即第 3 个 NetHSM 或可在任何主机上运行的 etcd "见证"。请参见下一节 "见证"。

见证人

The nature of clustering with etcd makes it more reliable the more nodes there are in the cluster. As explained in the Operational Redundancy section, clusters should ideally have at least 3 nodes to have room to fail, since a 2-node cluster will entirely fail if only one fails.

不过,该功能的设计使您不需要为集群添加完整、真实的 NetHSM 设备,就能达到稳定的节点数。相反,您可以自行部署并添加一个 "见证 "节点。这种节点只是``etcd`` 的一个实例,运行在您选择的机器上(或容器中),并连接到群集。群集中的真实设备会将其视为一个正常节点,并接收来自设备的所有数据和更新(当然,您无法对其执行任何 HSM 操作 - 它只能存储数据)。

Security Considerations

见证节点(或任何有访问权限的人)可直接访问群集中所有节点的存储后台(例如,您可以使用``etcdctl get "/" "0"`` 转储所有条目和相应值)。

不过,除了配置版本(/config/version,应始终为 "1")外,严格来说,所有值都经过加密(节点特定值使用设备密钥,其他值使用域密钥),以确保敏感数据的机密性。

但请注意,恶意节点可以

  • Write garbage as the value for any entry in the store, which will cause nodes to fail decrypting it (which may lead to crashes for some system entries).

  • List entry names such as users, namespaces and keys, which you may consider sensitive.

节点之间共享的内容

拥有 NetHSM 集群意味着它们之间共享大部分数据。对一个节点上的键、用户或命名空间的任何添加、修改或删除,最终都会反映到其他所有节点上。一般来说,任何修改状态的操作都会修改每个节点的状态。这包括备份**还原** 操作,该操作与正常操作一样。

下面几节将详细介绍哪些数据是完全本地的,哪些数据存储在共享的``etcd`` 存储器中,但仍是特定于节点的,以及哪些数据是跨节点完全共享的。

未存储在 etcd 中

每个节点的**设备密钥** 只存储在本地,不会在节点间共享。

存储在 etcd 中,但特定于节点

以下数据存储在``etcd`` 中,每个节点的作用域不同。因此,每个节点都可以访问** ,但在各节点之间,并不统一 (每个节点可以有不同的数据值)。

Configuration:

  • TLS certificates

  • Clock configuration

  • Network configuration

  • Logging configuration

  • Unattended boot configuration

  • Unlock salt (so each node has its own unlock passphrase)

  • Locked domain key

请注意,虽然每个节点都有自己版本的锁定域密钥(因为每个节点都用自己的设备密钥或解锁口令锁定域密钥),但底层域密钥是**跨节点共享的** (用于访问它们共享的 HSM 数据,如密钥)。

存储在 etcd 中并共享

以下所有数据都存储在全局范围内的``etcd`` 中,因此在集群的所有节点上都是统一的:

HSM 数据:

  • Keys

  • 用户

  • 命名空间

Configuration:

  • Config/domain store version

  • Cluster CA (used to authenticate nodes across cluster)

  • Backup passphrase and backup salt

Note that for now the config/domain store version can only be version 1 (if your software version supports clustering, then that is what you have). Refer to the Software Updates in Clusters section for more details on the safety of installing software updates within a cluster.

Creating a Cluster

任何集群最初都是从一个节点开始的。新节点会一个接一个地加入集群。

Preparing Nodes

节点之间的网络通信使用 TLS 证书进行加密和验证。

预计将成为同一群集一部分的所有节点必须首先安装一个共同的证书颁发机构 (CA),以便验证其他节点是否合法。

在下文中,我们假定所有节点都是全新配置和运行的。

Networking

Nodes must first be reconfigured with their expected final network configuration as described in the section Network.

创建和安装 CA

用户应根据自己的操作限制,通过自己的方式创建 CA,确保它至少允许使用``keyCertSign`` 密钥。

例如,可使用``openssl`` 创建最小 CA:

$ openssl genrsa -out CA.key 2048 # create a key
$ openssl req -x509 -new -nodes -key CA.key -sha256 -days 1825 -out CA.pem -addext keyUsage=critical,keyCertSign

现在必须在每个节点上安装该 CA。

要实现这一点,首先需要按照“`TLS Certificate”一节中的说明,从节点生成一个证书签名请求(CSR):<administration.html#tls-certificate>`__。对于*nitropy* ,可通过以下命令完成:nitropy nethsm --host $NETHSM_HOST csr --api。

备注

To properly authenticate nodes, the clustering backend (etcd) expects that each node has a certificate with a properly filled Subject Alt Names (SAN) field. Nodes are expected to be reached only via their IP and need to have a proper IP SAN in their certificate. IP SANs can be requested for the CSR by prefixing "IP:" to the names, as in openssl:

"subjectAltNames": [ "normalname.org", "IP:192.168.1.1" ]

在*nitropy* 中,请使用``--san`` 选项,例如:--san "IP:192.168.1.1"。

如果您想使用公共证书颁发机构(CA)对证书进行签名,您的节点必须使用公共 IP 地址。这是因为一项安全要求规定,公共证书颁发机构不得签发在 IP SAN 中包含私有 IP 地址的证书。

有了获得的 CSR(我们称之为``nethsm.csr``),我们就可以为其生成证书,准备安装。例如``openssl``:

$ openssl x509 -req -days 1825 -in nethsm.csr -CA CA.pem -copy_extensions copy \
    -CAkey CA.key -out new_cert.pem -set_serial 01 -sha256

然后按照`TLS证书部分<administration.html#tls-certificate>`__(使用*nitropy*:nitropy nethsm --host $NETHSM_HOST set-certificate --api new_cert.pem)中的说明,安装获取的``new_cert.pem``。

Finally, the CA (CA.pem) can now be installed. This is only possible once the installed TLS certificate is signed by it. Otherwise, the operation will be rejected.

论点

争论

描述

FILENAME

The path of the CA file

例子

$ nitropy nethsm --host $NETHSM_HOST set-cluster-ca-certificate CA.pem

可以通过 ` `nitropy nethsm --host $NETHSM_HOST get-cluster-ca-certificate 查询已安装的集群 CA。

备注

每个节点都必须重复这一过程。

时钟同步

请确保每个节点都已配置了准确的系统时间,最好使用 NTP/NTS 而不是手动设置时间。这可以通过`Time<administration.html#time>`__ 和`NTS/NTP<administration.html#ntp-nts>`__ 配置来实现。

Adding a New Node

Adding a node to a cluster is done in three steps:

  1. Register the addition to the cluster (through any one of its members)

  2. Tell the new node to join

  3. 一旦该节点赶上进度,就将其从“学习者”晋升为“正式成员”

Configure a Backup Passphrase

First make sure a backup passphrase is configured on the node that will be used to register a new joiner as described in the section Backup.

注册新节点

准备好要加入的节点的 IP 地址。该节点的完整*URL* (在``etcd`` 术语中也称为*peer URL* )将是``https://<IP_of_node>:2380``(例如``https://192.168.1.1:2380``)。的端口必须是 2380,因此要确保节点之间的防火墙允许该端口的 TCP 流量。

You can double-check the URL is correct by listing the cluster members on the node that is expected to join. This should list just one member: itself.

例子

$ nitropy nethsm --host $NETHSM_HOST list-cluster-members

Then register that expected URL on any existing node of the cluster (if you don't have a cluster yet, do this on the NetHSM that will serve as the initial node of the cluster).

可选择的选项

选项

描述

--url TEXT

新节点的对等节点 URL(可设置多次)

论点

争论

描述

JOIN_DATA_PATH

写入合并数据的文件路径

例子

$ nitropy nethsm --host $NETHSM_HOST add-cluster-member --url https://192.168.1.1:2380 join-data.json

该命令会列出集群成员,并将新节点加入集群所需的数据(包括加入工具包)写入文件。请保留此文件,以便进行下一步操作。

备注

Notice in the list of members (learner: True in the nitropy output, "learner": true in the REST API response) that the new joiner is a "learner": it can now connect to the cluster and receive data from it, but cannot participate until it is promoted, which will be covered below.

虽然“学习节点”这一概念增加了一个额外步骤(晋升),但它能确保集群更安全地运行,因为新节点在晋升之前,其任何问题都不会导致整个集群不稳定。

请保留该连接数据文件以备下一步使用(如果您使用了 REST API,则保留响应)。

Joining the Cluster as a Learner

在预计要加入集群的节点上加入集群,使用上一步中的数据以及新加入节点注册时所用的备份密码。

必要的选项

选项

描述

--backup-passphrase TEXT

新加入节点注册所在节点的备份密码短语

论点

争论

描述

JOIN_DATA_PATH

上一步中连接数据文件的路径

例子

$ nitropy nethsm --host $NETHSM_HOST join-cluster --backup-passphrase $BACKUP_PASSPHRASE join-data.json

警告

The join call (nitropy nethsm join-cluster or POST /cluster/join) will hang until the new node is manually promoted (see below). This is normal. When the call returns successfully, it indicates that join and promotion have been successful. Don't cancel this join call.

Assuming both the cluster and the node can reach each other, this will enact the actual join, wiping the data on the new joiner to instead synchronize its state with that of the cluster. If this operation fails immediately (e.g. the cluster was not reachable or authentication failed), this node's state will not be wiped and the join will be reverted. However as soon as a first join is successful, this operation is final and can only be reverted by a factory reset.

在此阶段,新节点已作为*学习节点* 加入集群:它正在与集群同步,但尚未投入运行。另一方面,此阶段该节点出现的任何问题都不会对集群造成影响,因此此操作是安全的。

完成加入流程的最后一步是将新节点提升为正式成员。

Promoting the New Learner

根据网络和集群状况的不同,新成员可能需要一段时间才能跟上集群的进度。一旦完成同步,它就可以从学习者晋升为正式成员。

警告

Promoting a node increases the cluster's quorum threshold (refer to the API documentation and the Operational Redundancy section of this document). Ensure this new node has a stable connection to the cluster before promoting it.

您可以按照以下方式尝试提升该新成员的权限。通过列出集群成员,即可找到该成员的ID。

论点

争论

描述

MEMBER_ID

The ID of the learner to be promoted

例子

$ nitropy nethsm --host $NETHSM_HOST promote-cluster-member $MEMBER_ID

如果学习者尚未跟上进度,则该操作将失败(REST API 返回 HTTP 状态码 412),应稍后再尝试晋升。

If this promotion is successful, the node will now have fully joined the cluster and the earlier call to /cluster/join will have returned. The node ends up in a Locked state and has to be unlocked with the unlock passphrase of the node that was used for registration. Afterwards the unlock passphrase can be changed (unlock passphrases remain node-specific and are not shared across nodes).

Adding a Witness Node

Prepare a Witness

您需要一个``etcd`` v3.6 可用的环境,该环境的 IPv4 地址(至少)可以被群集的其他成员访问。需要允许往来于 2380 端口的 TCP 流量。

在``etcd`` 中创建一个存放数据的空目录,并写下其路径(我们将使用``/var/etcd/data``)。确保将启动进程的用户拥有读写该目录的权限。

Transfer to the machine the CA certificate that is being used to authenticate nodes in the cluster. You should have created one in the Creating and Installing a CA section. We'll store it in /var/etcd/CA.pem.

然后,您需要为见证者创建一个证书,并在 CA 上签名,这样它就可以与同行通信了。例如,可以通过``openssl`` 来完成:

# Create a key
$ openssl genrsa -out witness.key 2048
# Create a CSR with a SAN that corresponds to the witness's IP or hostname
$ openssl req -new -sha256 -key own.key -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=witness" \
    -addext "subjectAltName=IP:172.22.1.3" --out witness.csr
# Sign it
$ openssl x509 -req -days 1825 -in witness.csr -CA CA.pem -copy_extensions copy \
    -CAkey CA.key -out witness.pem -set_serial 01 -sha256

将生成的``witness.key`` 和``witness.pem`` 也存储在``/var/etcd`` 中。

Register Witness to Cluster

Follow the normal instructions from the Registering a New Node section to signal the existing cluster the addition of a new member with the given URL(s).

Keep the join data file written by nitropy nethsm add-cluster-member (or the response from the cluster, if you used the REST API): it contains the list of cluster members and a joiner kit (you won't need this part).

Configure etcd

与 NetHSM 自动为自己选择节点名称(使用设备 ID)不同,您必须为添加的每个见证者选择一个名称,,确保名称是唯一的 。在以下示例中,我们将使用 "witness1"。

有了 NetHSM 登记证人的回复,准备表格的变量:

export ETCD_NAME="witness1"
export ETCD_DATA_DIR="/var/etcd/data"
export ETCD_INITIAL_CLUSTER="peer1=url1,peer1=url2,peer2=url1,peer2=url2,..."
export ETCD_INITIAL_ADVERTISE_PEER_URLS="my_url1,my_url2,..."

Assuming the join data file written by nitropy (or the NetHSM REST API response) is stored in a response.json file, you can generate these last two variables automatically with the following jq expressions:

export ETCD_INITIAL_CLUSTER=$(jq --raw-output '[.members[] | ["\(if .name == "" then "witness1" else .name end)=\(.urls[])"]] | flatten | join(",")' < response.json)
export ETCD_INITIAL_ADVERTISE_PEER_URLS=$(jq --raw-output '.members[] | select(.name=="") | .urls | join(",")' < response.json)

For example with the example response provided in the Registering a New Node section, you will have:

ETCD_NAME="witness1"
ETCD_DATA_DIR="/var/etcd/data"
ETCD_INITIAL_CLUSTER="witness1=https://172.22.1.3:2380,9ZVNM2MNWP=https://172.22.1.2:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.22.1.3:2380"

最后,使用``docs/etcd_witness.conf.template`` 中提供的模板文件创建``etcd.conf.yml`` 文件:

$ envsubst < NETHSM_ROOT/docs/etcd_witness.conf.template > /var/etcd/witness.conf.yml
$ cat witness.conf.yml

这样你就能得到一个表格文件:

name: witness1
data-dir: /var/etcd/data
log-level: warn
log-format: console

listen-peer-urls: https://0.0.0.0:2380
listen-client-urls: http://localhost:2379

initial-advertise-peer-urls: https://172.22.1.3:2380
advertise-client-urls: http://localhost:2379
initial-cluster: witness1=https://172.22.1.3:2380,9ZVNM2MNWP=https://172.22.1.2:2380
initial-cluster-state: 'existing'

peer-transport-security:
  cert-file: witness.pem
  key-file: witness.key
  client-cert-auth: true
  trusted-ca-file: CA.pem
  skip-client-san-verification: true

Start etcd

以您喜欢的方式(手动、systemd 服务、容器等)启动``etcd``,将其指向上一步创建的配置文件:

$ cd /var/etcd
$ etcd --config-file witness.conf.yml

你应该能看到它启动,以学习者身份加入集群,并跟上数据进度。

Promote the Witness

最后,过一段时间后,请按照`网站中“晋升新学员”<clustering.html#promoting-the-new-learner>`__ 部分的常规说明,为该见证人办理晋升手续。如果操作失败,请稍后再试。

After a successful promotion, you should be able to check that it is healthy with the etcdctl client:

etcdctl get /config/version

该键应存在并包含 "1"。

Make sure this process keeps running, as it is now a proper member of your cluster. If you need to decommission it, first properly remove it from the cluster. If its reachable IP changes, update its URL from the cluster.

Operating a Cluster

备份和恢复

备份操作与不使用群集时相同,可从群集的任何节点请求。它将备份整个群集的数据,包括节点特定字段(不过,除非在未配置的节点上恢复备份,否则这些字段将被忽略)。

在一个群集上完成的备份可以在同一个群集上还原,即使此后添加或删除了一些节点。在运行中的群集上进行的此类还原不会影响配置值(只有键、用户和命名空间),就像其他任何部分还原一样。

在未配置的节点上恢复备份将恢复用于创建备份的节点的特定节点字段(如网络配置、证书等)。

在应用还原的节点将更改转发给其他节点时,还原大型备份可能会使群集在一段时间内不堪重负。

此操作仍与 NetHSM 以前版本的备份兼容。

备注

在节点 A 上还原在另一个节点 Z 上使用不同域密钥制作的备份,会像以前一样正确重写 A 的域密钥。但是,如果 A 与节点 B 在一个群集中,B 将无法运行,因为 Z 的域密钥无法在 B 上还原。

换句话说,只能在具有在同一群集中完成的备份的群集中执行还原操作(尽管此后节点可能已被移除或添加)。如果要在某个节点上还原外来备份,首先要安全地将其从群集中移除,然后进行出厂重置并还原备份。

干净利落地删除节点

只要集群的某些部分仍符合法定人数,其任何成员都可以用来将另一个节点从集群中删除,无论该节点是已经无法访问还是预计将无法访问。

You first have to know the ID of the node you want to remove, by listing all nodes and looking for the right one. Then it can be removed. If the node in question was still healthy, this will isolate it from the rest of the cluster and transition it to the Failed state.

论点

争论

描述

MEMBER_ID

The ID of the node to be removed

例子

$ nitropy nethsm --host $NETHSM_HOST remove-cluster-member $MEMBER_ID

备注

已经加入集群但尚未被提升为领导节点的节点,也可以通过这种方式安全地移除。

Recovering a Failed Node

报告“Failed”状态( )的节点将拒绝响应大多数常规操作。该节点仍可被关闭、重启、重置、进行故障诊断(, )或隔离(, )。

警告

Failed 状态以及``diagnose`` 和``force-new`` 操作仅适用于 5.0 及更高版本。在 4.0 版本中,失去定额的节点将停止响应*所有* 请求。该节点*必须* 进行出厂重置。

节点处于“失败” 状态的常见原因包括:

  • 一个持久的`丢失了多数票<clustering.html#the-quorum-is-durably-lost>`__。

  • 暂时失去法定人数(例如:在向集群添加第二个节点时,该节点尚未加入)。

  • etcd 目前正在重启(例如,由于证书已更改,或网络已重新配置)。

  • 该集群正承受着非常高的负载(例如,在恢复一个非常大的备份时)。

无论原因如何,NetHSM只有在尝试与数据库交互未果且持续时间不少于一分钟后,才会转入“失败”状态( )。此举旨在避免因极短暂的不稳定状态而导致的错误状态转换。

To help you understand which case your node is in, the diagnose function remains available and returns information about the current status of etcd and its database, including logs.

例子

$ nitropy nethsm --host $NETHSM_HOST get-cluster-diagnostics

备注

如果且当数据库再次可用时(例如,由于网络问题已解决,定额(quorum)得以恢复),NetHSM将自动从“失败” 状态恢复到之前的状态(或者,如果当时正在启动,则恢复正常的启动序列),无需任何手动操作。 在问题解决后,集群稳定下来、HSM检测到问题已解决并完成状态切换,最多需要一分钟时间。

如果您认定该故障是持久的(例如,丢失了法定人数且无法解决根本原因),您可以:

  • 将节点恢复出厂设置( ),这将清除所有数据,并恢复备份。

  • Isolate the node with nitropy nethsm force-new-cluster (REST API: POST /cluster/force-new), which will irreversibly forget all other cluster members, recover the etcd data present on disk and reboot. If the underlying failure was cluster-related, the node will follow the normal boot sequence and end up in either the Locked or Operational state depending on the unattended boot setting.

备注

If a node is isolated with force-new, it will desynchronized with the cluster: any new writes on it or the cluster cannot be reconciled. The node can still rejoin the cluster but will lose all its local modifications.

The force-new operation, which is only available in the Failed state, requires authentication as it is potentially destructive. However since HSM users and roles are not available in that state, the endpoint expects HTTPS clients to always authenticate with the unlock fake user, and the latest known unlock passphrase as the password. With nitropy, pass them as --username unlock --password $UNLOCK_PASSPHRASE:

$ nitropy nethsm --host $NETHSM_HOST --username unlock --password $UNLOCK_PASSPHRASE force-new-cluster

警告

从低于 5.0 的版本升级后,在 HSM 解锁或解锁密码短语至少更改一次之前,`` 中的 force-new` 端点将始终显示“未授权”。

Software Updates in Clusters

未来的更新将被标记为 "集群安全"(这应该是大多数)或 "集群不安全"。

群集安全更新可应用于群集中的节点,而无需先将它们从群集中移除。不过,与所有操作一样,应确保一次只在一个节点上进行,并且在群集中删除一个节点不会低于法定人数(例如,如果更新失败)。

群集不安全更新必须应用于隔离节点。您应该拆除群集(逐个删除节点),出厂重置除一个节点外的所有节点,将更新应用到每个节点,然后让所有重置节点加入剩余节点。

确保在进行此类操作前进行备份。

重新配置现有群集

Changing the Cluster CA

现有群集(有两个或两个以上节点)**,在运行过程中不能** 更改其群集 CA。如果需要更改此证书:选择一个节点,移除所有其他节点,更新 CA,然后让其他成员重新加入。

Changing the Network Configuration of Nodes

修改一个节点的网络配置(如更改其 IP)会自动将更新通知其他节点。但应确保每次只在单个节点上执行此类更新,而且在群集中失去该节点不会失去法定人数。