Kubernetes 运行 etcd 集群
etcd 是一个一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后备存储。
如果你的 Kubernetes 集群使用 etcd 作为其后备存储,请确保你制定了数据备份计划。
你可以在官方文档中找到有关 etcd 的深入信息。
开始之前
在你按照此页面中的步骤部署、管理、备份或还原 etcd 之前,你需要了解操作 etcd 集群的典型期望。有关更多上下文,请参阅 etcd 文档。
关键细节包括
建议在生产环境中运行的 etcd 最低版本为
3.4.22+
和3.5.6+
。etcd 是一个基于领导者的分布式系统。确保领导者定期按时向所有跟随者发送心跳,以保持集群稳定。
你应该以奇数个成员的集群形式运行 etcd。
目标是确保不会发生资源匮乏。
集群的性能和稳定性对网络和磁盘 I/O 很敏感。任何资源匮乏都可能导致心跳超时,从而导致集群不稳定。不稳定的 etcd 表明没有选出领导者。在这种情况下,集群无法对其当前状态进行任何更改,这意味着无法调度新的 Pod。
etcd 的资源需求
在资源有限的情况下操作 etcd 仅适用于测试目的。对于在生产环境中部署,需要高级硬件配置。在生产环境中部署 etcd 之前,请参阅资源需求参考。
保持 etcd 集群稳定对于 Kubernetes 集群的稳定性至关重要。因此,为了保证资源需求,请在专用机器或隔离环境中运行 etcd 集群。
工具
根据你正在处理的特定结果,你将需要 etcdctl
工具或 etcdutl
工具(你可能需要两者)。
了解 etcdctl 和 etcdutl
etcdctl
和 etcdutl
是用于与 etcd 集群交互的命令行工具,但它们服务于不同的目的
etcdctl
:这是通过网络与 etcd 交互的主要命令行客户端。它用于日常操作,例如管理键和值、管理集群、检查运行状况等。etcdutl
:这是一个管理实用程序,旨在直接操作 etcd 数据文件,包括在 etcd 版本之间迁移数据、碎片整理数据库、还原快照和验证数据一致性。对于网络操作,应使用etcdctl
。
有关 etcdutl
的更多信息,你可以参考etcd 恢复文档。
启动 etcd 集群
本节介绍启动单节点和多节点 etcd 集群。
本指南假设已安装 etcd
。
单节点 etcd 集群
仅出于测试目的使用单节点 etcd 集群。
运行以下命令
etcd --listen-client-urls=http://$PRIVATE_IP:2379 \ --advertise-client-urls=http://$PRIVATE_IP:2379
使用标志
--etcd-servers=$PRIVATE_IP:2379
启动 Kubernetes API 服务器。确保
PRIVATE_IP
设置为你的 etcd 客户端 IP。
多节点 etcd 集群
为了获得持久性和高可用性,请在生产环境中以多节点集群的形式运行 etcd 并定期备份。建议在生产环境中使用五成员集群。有关更多信息,请参阅FAQ 文档。
由于你正在使用 Kubernetes,因此可以选择在 一个或多个 Pod 内作为容器运行 etcd。 kubeadm
工具默认设置 etcd 静态 Pod,或者你可以部署一个单独的集群,并指示 kubeadm 将该 etcd 集群用作控制平面的后备存储。
你可以通过静态成员信息或动态发现来配置 etcd 集群。有关集群的更多信息,请参阅etcd 集群文档。
例如,考虑一个具有以下客户端 URL 运行的五成员 etcd 集群:http://$IP1:2379
、http://$IP2:2379
、http://$IP3:2379
、http://$IP4:2379
和 http://$IP5:2379
。要启动 Kubernetes API 服务器
运行以下命令
etcd --listen-client-urls=http://$IP1:2379,http://$IP2:2379,http://$IP3:2379,http://$IP4:2379,http://$IP5:2379 --advertise-client-urls=http://$IP1:2379,http://$IP2:2379,http://$IP3:2379,http://$IP4:2379,http://$IP5:2379
使用标志
--etcd-servers=$IP1:2379,$IP2:2379,$IP3:2379,$IP4:2379,$IP5:2379
启动 Kubernetes API 服务器。确保将
IP<n>
变量设置为你的客户端 IP 地址。
带负载均衡器的多节点 etcd 集群
要运行负载均衡的 etcd 集群
- 设置一个 etcd 集群。
- 在 etcd 集群前面配置一个负载均衡器。例如,让负载均衡器的地址为
$LB
。 - 使用标志
--etcd-servers=$LB:2379
启动 Kubernetes API 服务器。
保护 etcd 集群
对 etcd 的访问等同于集群中的根权限,因此理想情况下,只有 API 服务器应该有权访问它。考虑到数据的敏感性,建议仅向需要访问 etcd 集群的节点授予权限。
要保护 etcd,请设置防火墙规则或使用 etcd 提供的安全功能。etcd 安全功能依赖于 x509 公钥基础设施 (PKI)。首先,通过生成密钥和证书对来建立安全通信通道。例如,使用密钥对 peer.key
和 peer.cert
来保护 etcd 成员之间的通信,并使用 client.key
和 client.cert
来保护 etcd 与其客户端之间的通信。请参阅 etcd 项目提供的示例脚本,以生成用于客户端身份验证的密钥对和 CA 文件。
保护通信
要配置具有安全对等通信的 etcd,请指定标志 --peer-key-file=peer.key
和 --peer-cert-file=peer.cert
,并使用 HTTPS 作为 URL 架构。
同样,要配置具有安全客户端通信的 etcd,请指定标志 --key-file=k8sclient.key
和 --cert-file=k8sclient.cert
,并使用 HTTPS 作为 URL 架构。以下是使用安全通信的客户端命令示例
ETCDCTL_API=3 etcdctl --endpoints 10.2.0.9:2379 \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
member list
限制对 etcd 集群的访问
配置安全通信后,使用 TLS 身份验证将 etcd 集群的访问权限限制为仅限 Kubernetes API 服务器。
例如,考虑由 CA etcd.ca
信任的密钥对 k8sclient.key
和 k8sclient.cert
。当 etcd 配置了 --client-cert-auth
以及 TLS 时,它会使用系统 CA 或由 --trusted-
一旦 etcd 配置正确,只有拥有有效证书的客户端才能访问它。要使 Kubernetes API 服务器能够访问,请使用 --etcd-certfile=k8sclient.cert
、--etcd-keyfile=k8sclient.key
和 --etcd-cafile=ca.cert
标志配置它们。
注意
Kubernetes 不计划使用 etcd 身份验证。替换失败的 etcd 成员
etcd 集群通过容忍少量的成员故障来实现高可用性。但是,为了提高集群的整体健康状况,请立即替换失败的成员。当多个成员发生故障时,请逐个替换它们。替换失败的成员包括两个步骤:删除失败的成员和添加新成员。
尽管 etcd 在内部保留唯一的成员 ID,但建议为每个成员使用唯一的名称以避免人为错误。例如,考虑一个由三个成员组成的 etcd 集群。假设 URL 为:member1=http://10.0.0.1
、member2=http://10.0.0.2
和 member3=http://10.0.0.3
。当 member1
失败时,将其替换为 member4=http://10.0.0.4
。
获取失败的
member1
的成员 IDetcdctl --endpoints=http://10.0.0.2,http://10.0.0.3 member list
将显示以下消息
8211f1d0f64f3269, started, member1, http://10.0.0.1:2380, http://10.0.0.1:2379 91bc3c398fb3c146, started, member2, http://10.0.0.2:2380, http://10.0.0.2:2379 fd422379fda50e48, started, member3, http://10.0.0.3:2380, http://10.0.0.3:2379
执行以下任一操作
- 如果每个 Kubernetes API 服务器都被配置为与所有 etcd 成员通信,则从
--etcd-servers
标志中删除失败的成员,然后重新启动每个 Kubernetes API 服务器。 - 如果每个 Kubernetes API 服务器都与单个 etcd 成员通信,则停止与失败的 etcd 通信的 Kubernetes API 服务器。
- 如果每个 Kubernetes API 服务器都被配置为与所有 etcd 成员通信,则从
停止故障节点上的 etcd 服务器。除了 Kubernetes API 服务器之外,可能还有其他客户端导致 etcd 的流量,因此需要停止所有流量以防止写入数据目录。
删除失败的成员
etcdctl member remove 8211f1d0f64f3269
将显示以下消息
Removed member 8211f1d0f64f3269 from cluster
添加新成员
etcdctl member add member4 --peer-urls=http://10.0.0.4:2380
将显示以下消息
Member 2be1eb8f84b7f63e added to cluster ef37ad9dc622a7c4
在 IP 为
10.0.0.4
的机器上启动新添加的成员export ETCD_NAME="member4" export ETCD_INITIAL_CLUSTER="member2=http://10.0.0.2:2380,member3=http://10.0.0.3:2380,member4=http://10.0.0.4:2380" export ETCD_INITIAL_CLUSTER_STATE=existing etcd [flags]
执行以下任一操作
- 如果每个 Kubernetes API 服务器都被配置为与所有 etcd 成员通信,则将新添加的成员添加到
--etcd-servers
标志中,然后重新启动每个 Kubernetes API 服务器。 - 如果每个 Kubernetes API 服务器都与单个 etcd 成员通信,则启动在步骤 2 中停止的 Kubernetes API 服务器。然后配置 Kubernetes API 服务器客户端,再次将请求路由到已停止的 Kubernetes API 服务器。这通常可以通过配置负载均衡器来完成。
- 如果每个 Kubernetes API 服务器都被配置为与所有 etcd 成员通信,则将新添加的成员添加到
有关集群重新配置的更多信息,请参阅 etcd 重新配置文档。
备份 etcd 集群
所有 Kubernetes 对象都存储在 etcd 中。定期备份 etcd 集群数据对于在灾难场景(例如丢失所有控制平面节点)下恢复 Kubernetes 集群非常重要。快照文件包含所有 Kubernetes 状态和关键信息。为了保证敏感 Kubernetes 数据的安全,请对快照文件进行加密。
备份 etcd 集群可以通过两种方式完成:etcd 内置快照和卷快照。
内置快照
etcd 支持内置快照。可以使用 etcdctl snapshot save
命令从活动成员创建快照,或者通过从当前未被 etcd 进程使用的 etcd 数据目录 中复制 member/snap/db
文件来创建快照。创建快照不会影响成员的性能。
以下是一个示例,用于将 $ENDPOINT
服务的键空间快照创建到文件 snapshot.db
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db
验证快照
以下示例描述了使用 etcdutl
工具验证快照
etcdutl --write-out=table snapshot status snapshot.db
这应该生成一个类似于下面提供的示例的输出
+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 | 10 | 7 | 2.1 MB |
+----------+----------+------------+------------+
以下示例描述了使用 etcdctl
工具验证快照
export ETCDCTL_API=3
etcdctl --write-out=table snapshot status snapshot.db
这应该生成一个类似于下面提供的示例的输出
Deprecated: Use `etcdutl snapshot status` instead.
+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 | 10 | 7 | 2.1 MB |
+----------+----------+------------+------------+
卷快照
如果 etcd 运行在支持备份的存储卷上,例如 Amazon Elastic Block Store,则可以通过创建存储卷的快照来备份 etcd 数据。
使用 etcdctl 选项进行快照
我们还可以使用 etcdctl 提供的各种选项创建快照。例如
ETCDCTL_API=3 etcdctl -h
将列出 etcdctl 中提供的各种选项。例如,您可以像下面这样指定端点、证书和密钥来创建快照
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \
snapshot save <backup-file-location>
其中 trusted-ca-file
、cert-file
和 key-file
可以从 etcd Pod 的描述中获得。
横向扩展 etcd 集群
横向扩展 etcd 集群通过牺牲性能来提高可用性。扩展不会提高集群性能或容量。一般规则是不横向扩展或缩减 etcd 集群。不要为 etcd 集群配置任何自动扩展组。强烈建议在任何官方支持的规模下,始终为生产 Kubernetes 集群运行静态的五成员 etcd 集群。
当需要更高的可靠性时,合理的扩展是将由三个成员组成的集群升级为由五个成员组成的集群。有关如何向现有集群添加成员的信息,请参阅 etcd 重新配置文档。
恢复 etcd 集群
注意
如果您的集群中运行着任何 API 服务器,则不应尝试恢复 etcd 实例。相反,请按照以下步骤恢复 etcd
- 停止所有 API 服务器实例
- 恢复所有 etcd 实例中的状态
- 重新启动所有 API 服务器实例
Kubernetes 项目还建议重新启动 Kubernetes 组件(kube-scheduler
、kube-controller-manager
、kubelet
),以确保它们不依赖于某些过时的数据。在实践中,恢复需要一些时间。在恢复期间,关键组件将失去领导者锁并自行重新启动。
etcd 支持从来自 major.minor 版本的 etcd 进程拍摄的快照进行恢复。还支持从不同补丁版本的 etcd 恢复版本。恢复操作用于恢复失败集群的数据。
在开始恢复操作之前,必须存在快照文件。它可以是来自先前备份操作的快照文件,也可以是来自剩余的 数据目录 的快照文件。
使用 etcdutl
恢复集群时,请使用 --data-dir
选项指定要将集群恢复到哪个文件夹
etcdutl --data-dir <data-dir-location> snapshot restore snapshot.db
其中 <data-dir-location>
是将在恢复过程中创建的目录。
以下示例描述了使用 etcdctl
工具进行恢复操作
export ETCDCTL_API=3
etcdctl --data-dir <data-dir-location> snapshot restore snapshot.db
如果 <data-dir-location>
与之前的文件夹相同,请在恢复集群之前将其删除并停止 etcd 进程。否则,请更改 etcd 配置并在恢复后重新启动 etcd 进程,以使其使用新的数据目录:首先将 /etc/kubernetes/manifests/etcd.yaml
的 volumes.hostPath.path
中 name: etcd-data
的值更改为 <data-dir-location>
,然后执行 kubectl -n kube-system delete pod <name-of-etcd-pod>
或 systemctl restart kubelet.service
(或两者)。
有关从快照文件恢复集群的更多信息和示例,请参阅 etcd 灾难恢复文档。
如果恢复后的集群的访问 URL 与之前的集群发生了更改,则必须相应地重新配置 Kubernetes API 服务器。在这种情况下,请使用 --etcd-servers=$NEW_ETCD_CLUSTER
标志而不是 --etcd-servers=$OLD_ETCD_CLUSTER
标志重新启动 Kubernetes API 服务器。将 $NEW_ETCD_CLUSTER
和 $OLD_ETCD_CLUSTER
替换为各自的 IP 地址。如果在 etcd 集群前面使用了负载均衡器,则可能需要更新负载均衡器。
如果大多数 etcd 成员永久失败,则认为 etcd 集群已失败。在这种情况下,Kubernetes 无法对其当前状态进行任何更改。尽管计划的 Pod 可能会继续运行,但无法计划新的 Pod。在这种情况下,请恢复 etcd 集群并可能重新配置 Kubernetes API 服务器以解决此问题。
升级 etcd 集群
注意
在开始升级之前,请首先备份您的 etcd 集群。有关 etcd 升级的详细信息,请参阅 etcd 升级文档。
维护 etcd 集群
有关 etcd 维护的更多详细信息,请参阅 etcd 维护文档。
集群碎片整理
碎片整理是一项开销很大的操作,因此应尽可能少地执行。另一方面,还需要确保任何 etcd 成员都不会超出存储配额。Kubernetes 项目建议在执行碎片整理时,使用诸如 etcd-defrag 之类的工具。
您还可以将碎片整理工具作为 Kubernetes CronJob 运行,以确保定期进行碎片整理。有关详细信息,请参阅 etcd-defrag-cronjob.yaml
。
此页面上的项目引用了提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目的作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅 CNCF 网站指南。
在提出添加额外第三方链接的更改之前,应阅读内容指南。