Kubernetes etcd集群

2023-12-15 36

Etcd是分布式且可靠的键值存储,用于保存分布式系统中的关键数据。在Kubernetes生态系统中,Etcd担任着重要的角色,它不仅作为服务发现的后端,还负责储存集群的状态及其配置信息。为了确保数据的可靠性和高可用性,Etcd通常被部署为一个集群,多个节点之间的通信是通过Raft算法来处理的。

如果 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保针对这些数据有一份备份计划。

一、准备

必须拥有一个 Kubernetes 的集群,同时必须配置 kubectl 命令行工具与集群通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。 如果还没有集群,可以通过 Minikube 构建一个自己的集群,或者可以使用下面的 Kubernetes 练习环境之一:

  • Killercoda
  • 玩转 Kubernetes

要获知版本信息,请输入 kubectl version.

需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与集群通信。 建议在至少有两个不充当控制平面的节点上运行此任务。如果还没有集群, 可以使用 minikube 创建一个。

二、先决条件

1、运行的 etcd 集群个数成员为奇数。

2、etcd 是一个 leader-based 分布式系统。确保主节点定期向所有从节点发送心跳,以保持集群稳定。

3、确保不发生资源不足。

集群的性能和稳定性对网络和磁盘 I/O 非常敏感。任何资源匮乏都会导致心跳超时, 从而导致集群的不稳定。不稳定的情况表明没有选出任何主节点。 在这种情况下,集群不能对其当前状态进行任何更改,这意味着不能调度新的 Pod。

4、保持 etcd 集群的稳定对 Kubernetes 集群的稳定性至关重要。 因此,请在专用机器或隔离环境上运行 etcd 集群, 以满足所需资源需求。

5、在生产环境中运行的 etcd 最低推荐版本为 3.4.22+ 和 3.5.6+。

三、资源需求

使用有限的资源运行 etcd 只适合测试目的。为了在生产中部署,需要先进的硬件配置。

四、启动etcd集群

1、单节点 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。

2、多节点 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 地址。

3、使用负载均衡器的多节点 etcd 集群

要运行负载均衡的 etcd 集群:

  • 建立一个 etcd 集群;
  • 在 etcd 集群前面配置负载均衡器。例如,让负载均衡器的地址为 $LB;
  • 使用参数 –etcd-servers=$LB:2379 启动 Kubernetes API 服务器。

五、加固etcd集群

对 etcd 的访问相当于集群中的 root 权限,因此理想情况下只有 API 服务器才能访问它。 考虑到数据的敏感性,建议只向需要访问 etcd 集群的节点授予权限。

想要确保 etcd 的安全,可以设置防火墙规则或使用 etcd 提供的安全特性,这些安全特性依赖于 x509 公钥基础设施(PKI)。 首先,通过生成密钥和证书对来建立安全的通信通道。 例如,使用密钥对 peer.key 和 peer.cert 来保护 etcd 成员之间的通信, 而 client.key 和 client.cert 用于保护 etcd 与其客户端之间的通信。

1、安全通信

若要使用安全对等通信对 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

2、限制etcd集群的访问

配置安全通信后,限制只有 Kubernetes API 服务器可以访问 etcd 集群。使用 TLS 身份验证来完成此任务。

例如,考虑由 CA etcd.ca 信任的密钥对 k8sclient.key 和 k8sclient.cert。 当 etcd 配置为 –client-cert-auth 和 TLS 时,它使用系统 CA 或由 –trusted-ca-file 参数传入的 CA 验证来自客户端的证书。指定参数 –client-cert-auth=true 和 –trusted-ca-file=etcd.ca 将限制对具有证书 k8sclient.cert 的客户端的访问。

一旦正确配置了 etcd,只有具有有效证书的客户端才能访问它。要让 Kubernetes API 服务器访问, 可以使用参数 –etcd-certfile=k8sclient.cert、–etcd-keyfile=k8sclient.key 和 –etcd-cafile=ca.cert 配置。

3、替换失败的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 的成员 ID:

etcdctl --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 服务器;
  • 停止故障节点上的 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 服务器。 这通常可以通过配置负载均衡器来完成。

六、备份etcd集群

所有 Kubernetes 对象都存储在 etcd 上。 定期备份 etcd 集群数据对于在灾难场景(例如丢失所有控制平面节点)下恢复 Kubernetes 集群非常重要。 快照文件包含所有 Kubernetes 状态和关键信息。为了保证敏感的 Kubernetes 数据的安全,可以对快照文件进行加密。

备份 etcd 集群可以通过两种方式完成:etcd 内置快照和卷快照。

1、内置快照

etcd 支持内置快照。快照可以从使用 etcdctl snapshot save 命令的活动成员中获取, 也可以通过从 etcd 数据目录 复制 member/snap/db 文件,该 etcd 数据目录目前没有被 etcd 进程使用。获取快照不会影响成员的性能。

下面是一个示例,用于获取 $ENDPOINT 所提供的键空间的快照到文件 snapshot.db:

ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db

验证快照:

ETCDCTL_API=3 etcdctl –write-out=table snapshot status snapshot.db

+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 |       10 |          7 | 2.1 MB     |
+----------+----------+------------+------------+

2、卷快照

如果 etcd 运行在支持备份的存储卷(如 Amazon Elastic Block 存储)上,则可以通过获取存储卷的快照来备份 etcd 数据。

3、使用 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>

可以从 etcd Pod 的描述中获得 trusted-ca-file、cert-file 和 key-file。

七、为etcd集群扩容

通过交换性能,对 etcd 集群扩容可以提高可用性。缩放不会提高集群性能和能力。 一般情况下不要扩大或缩小 etcd 集群的集合。不要为 etcd 集群配置任何自动缩放组。 强烈建议始终在任何官方支持的规模上运行生产 Kubernetes 集群时使用静态的五成员 etcd 集群。合理的扩展是在需要更高可靠性的情况下,将三成员集群升级为五成员集群。

八、恢复etcd集群

etcd 支持从 major.minor 或其他不同 patch 版本的 etcd 进程中获取的快照进行恢复。 还原操作用于恢复失败的集群的数据。

在启动还原操作之前,必须有一个快照文件。它可以是来自以前备份操作的快照文件, 也可以是来自剩余数据目录的快照文件。 例如:

ETCDCTL_API=3 etcdctl --endpoints 10.2.0.9:2379 snapshot restore snapshot.db

恢复时使用 etcdctl 选项的另一个示例:

ETCDCTL_API=3 etcdctl snapshot restore --data-dir <data-dir-location> snapshot.db

其中 <data-dir-location> 是将在恢复过程中创建的目录。

另一个例子是先导出 ETCDCTL_API 环境变量:

export ETCDCTL_API=3
etcdctl snapshot restore --data-dir <data-dir-location> snapshot.db

如果还原的集群的访问 URL 与前一个集群不同,则必须相应地重新配置 Kubernetes API 服务器。 在本例中,使用参数 –etcd-servers=$NEW_ETCD_CLUSTER 而不是参数 –etcd-servers=$OLD_ETCD_CLUSTER 重新启动 Kubernetes API 服务器。用相应的 IP 地址替换 $NEW_ETCD_CLUSTER 和 $OLD_ETCD_CLUSTER。 如果在 etcd 集群前面使用负载均衡,则可能需要更新负载均衡器。

如果大多数 etcd 成员永久失败,则认为 etcd 集群失败。在这种情况下,Kubernetes 不能对其当前状态进行任何更改。 虽然已调度的 Pod 可能继续运行,但新的 Pod 无法调度。在这种情况下, 恢复 etcd 集群并可能需要重新配置 Kubernetes API 服务器以修复问题。

如果集群中正在运行任何 API 服务器,则不应尝试还原 etcd 的实例。相反,请按照以下步骤还原 etcd:

  • 停止所有 API 服务实例;
  • 在所有 etcd 实例中恢复状态;
  • 重启所有 API 服务实例。

建议重启所有组件(例如 kube-scheduler、kube-controller-manager、kubelet), 以确保它们不会依赖一些过时的数据。请注意,实际中还原会花费一些时间。 在还原过程中,关键组件将丢失领导锁并自行重启。

  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。