当前位置:  首页>> 技术小册>> Kubernetes中文教程(五)

先决条件

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

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

  • 确保不发生资源不足。

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

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

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

资源需求

使用有限的资源运行 etcd 只适合测试目的。为了在生产中部署,需要先进的硬件配置。
在生产中部署 etcd 之前,请查看[所需资源参考文档]。

启动 etcd 集群

本节介绍如何启动单节点和多节点 etcd 集群。

单节点 etcd 集群

只为测试目的使用单节点 etcd 集群。

  1. 运行以下命令:

    1. etcd --listen-client-urls=http://$PRIVATE_IP:2379 \
    2. --advertise-client-urls=http://$PRIVATE_IP:2379
  2. 使用参数 --etcd-servers=$PRIVATE_IP:2379 启动 Kubernetes API 服务器。

    确保将 PRIVATE_IP 设置为 etcd 客户端 IP。

多节点 etcd 集群

出于耐用性和高可用性考量,在生产环境中应以多节点集群的方式运行 etcd,并且定期备份。
建议在生产环境中使用五个成员的集群。
有关该内容的更多信息,请参阅[常见问题文档]。

可以通过静态成员信息或动态发现的方式配置 etcd 集群。
有关集群的详细信息,请参阅
[etcd 集群文档]。

例如,考虑运行以下客户端 URL 的五个成员的 etcd 集群:http://$IP1:2379
http://$IP2:2379http://$IP3:2379http://$IP4:2379http://$IP5:2379
要启动 Kubernetes API 服务器:

  1. 运行以下命令:

    1. 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
  2. 使用参数 --etcd-servers=$IP1:2379,$IP2:2379,$IP3:2379,$IP4:2379,$IP5:2379
    启动 Kubernetes API 服务器。

    确保将 IP<n> 变量设置为客户端 IP 地址。

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

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

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

加固 etcd 集群

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

想要确保 etcd 的安全,可以设置防火墙规则或使用 etcd 提供的安全特性,这些安全特性依赖于 x509 公钥基础设施(PKI)。
首先,通过生成密钥和证书对来建立安全的通信通道。
例如,使用密钥对 peer.keypeer.cert 来保护 etcd 成员之间的通信,
client.keyclient.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 模式。
使用安全通信的客户端命令的示例:

  1. ETCDCTL_API=3 etcdctl --endpoints 10.2.0.9:2379 \
  2. --cert=/etc/kubernetes/pki/etcd/server.crt \
  3. --key=/etc/kubernetes/pki/etcd/server.key \
  4. --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  5. member list

限制 etcd 集群的访问

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

例如,考虑由 CA etcd.ca 信任的密钥对 k8sclient.keyk8sclient.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 配置。

Kubernetes 目前不支持 etcd 身份验证。
想要了解更多信息,请参阅相关的问题[支持 etcd v2 的基本认证]。

替换失败的 etcd 成员

etcd 集群通过容忍少数成员故障实现高可用性。
但是,要改善集群的整体健康状况,请立即替换失败的成员。当多个成员失败时,逐个替换它们。
替换失败成员需要两个步骤:删除失败成员和添加新成员。

虽然 etcd 在内部保留唯一的成员 ID,但建议为每个成员使用唯一的名称,以避免人为错误。
例如,考虑一个三成员的 etcd 集群。假定 URL 分别为:member1=http://10.0.0.1member2=http://10.0.0.2
member3=http://10.0.0.3。当 member1 失败时,将其替换为 member4=http://10.0.0.4

  1. 获取失败的 member1 的成员 ID:

    1. etcdctl --endpoints=http://10.0.0.2,http://10.0.0.3 member list

显示以下信息:

  1. 8211f1d0f64f3269, started, member1, http://10.0.0.1:2380, http://10.0.0.1:2379
  2. 91bc3c398fb3c146, started, member2, http://10.0.0.2:2380, http://10.0.0.2:2379
  3. fd422379fda50e48, started, member3, http://10.0.0.3:2380, http://10.0.0.3:2379
  1. 执行以下操作之一:

    1. 如果每个 Kubernetes API 服务器都配置为与所有 etcd 成员通信,
      请从 --etcd-servers 标志中移除删除失败的成员,然后重新启动每个 Kubernetes API 服务器。
    2. 如果每个 Kubernetes API 服务器都与单个 etcd 成员通信,
      则停止与失败的 etcd 通信的 Kubernetes API 服务器。
  1. 停止故障节点上的 etcd 服务器。除了 Kubernetes API 服务器之外的其他客户端可能会造成流向 etcd 的流量,
    可以停止所有流量以防止写入数据目录。
  1. 移除失败的成员:

    1. etcdctl member remove 8211f1d0f64f3269

显示以下信息:

  1. Removed member 8211f1d0f64f3269 from cluster
  1. 增加新成员:

    1. etcdctl member add member4 --peer-urls=http://10.0.0.4:2380

显示以下信息:

  1. Member 2be1eb8f84b7f63e added to cluster ef37ad9dc622a7c4
  1. 在 IP 为 10.0.0.4 的机器上启动新增加的成员:

    1. export ETCD_NAME="member4"
    2. 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"
    3. export ETCD_INITIAL_CLUSTER_STATE=existing
    4. etcd [flags]
  1. 执行以下操作之一:

    1. 如果每个 Kubernetes API 服务器都配置为与所有 etcd 成员通信,
      则将新增的成员添加到 --etcd-servers 标志,然后重新启动每个 Kubernetes API 服务器。
    2. 如果每个 Kubernetes API 服务器都与单个 etcd 成员通信,请启动在第 2 步中停止的 Kubernetes API 服务器。
      然后配置 Kubernetes API 服务器客户端以再次将请求路由到已停止的 Kubernetes API 服务器。
      这通常可以通过配置负载均衡器来完成。

有关集群重新配置的详细信息,请参阅
[etcd 重构文档]。

备份 etcd 集群

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

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

内置快照

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

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

  1. ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb

验证快照:

  1. ETCDCTL_API=3 etcdctl --write-out=table snapshot status snapshotdb
  1. +----------+----------+------------+------------+
  2. | HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
  3. +----------+----------+------------+------------+
  4. | fe01cf57 | 10 | 7 | 2.1 MB |
  5. +----------+----------+------------+------------+

卷快照

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

使用 etcdctl 选项的快照

我们还可以使用 etcdctl 提供的各种选项来制作快照。例如:

  1. ETCDCTL_API=3 etcdctl -h

列出 etcdctl 可用的各种选项。例如,你可以通过指定端点、证书等来制作快照,如下所示:

  1. ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  2. --cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \
  3. snapshot save <backup-file-location>

可以从 etcd Pod 的描述中获得 trusted-ca-filecert-filekey-file

为 etcd 集群扩容

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

合理的扩展是在需要更高可靠性的情况下,将三成员集群升级为五成员集群。
请参阅 [etcd 重构文档]
以了解如何将成员添加到现有集群中的信息。

恢复 etcd 集群

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

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

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

恢复时也可以指定操作选项,例如:

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

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

  1. export ETCDCTL_API=3
  2. etcdctl snapshot restore --data-dir <data-dir-location> snapshotdb

有关从快照文件还原集群的详细信息和示例,请参阅
[etcd 灾难恢复文档]。

如果还原的集群的访问 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-schedulerkube-controller-managerkubelet),
以确保它们不会依赖一些过时的数据。请注意,实际中还原会花费一些时间。
在还原过程中,关键组件将丢失领导锁并自行重启。

升级 etcd 集群

有关 etcd 升级的更多详细信息,请参阅 [etcd 升级]文档。

在开始升级之前,请先备份你的 etcd 集群。


该分类下的相关小册推荐: