在多区域中运行

此页面描述了跨多个区域运行 Kubernetes 的方法。

背景

Kubernetes 的设计使其可以在多个故障区域(通常这些区域位于一个名为区域的逻辑分组中)中运行单个 Kubernetes 集群。主要的云提供商将区域定义为一组故障区域(也称为可用区),这些区域提供一组一致的功能:在一个区域内,每个区域提供相同的 API 和服务。

典型的云架构旨在尽量减少一个区域中的故障也会影响另一个区域中的服务的可能性。

控制平面行为

所有控制平面组件都支持作为可互换资源的池运行,每个组件进行复制。

部署集群控制平面时,请将控制平面组件的副本放置在多个故障区域中。如果可用性是一个重要的考虑因素,请选择至少三个故障区域,并将每个单独的控制平面组件(API 服务器、调度器、etcd、集群控制器管理器)复制到至少三个故障区域。如果运行云控制器管理器,那么也应该将它复制到所有选定的故障区域。

节点行为

Kubernetes 会自动将工作负载资源(例如DeploymentStatefulSet)的 Pod 分散到集群中的不同节点。这种分散有助于减少故障的影响。

当节点启动时,每个节点上的 kubelet 会自动将标签添加到 Kubernetes API 中代表该特定 kubelet 的 Node 对象。这些标签可以包括区域信息

如果你的集群跨越多个区域或地区,你可以将节点标签与Pod 拓扑分布约束结合使用,以控制 Pod 在故障域(区域、地区,甚至特定节点)之间如何在你的集群中分布。这些提示使调度器能够放置 Pod 以获得更好的预期可用性,从而降低相关故障影响整个工作负载的风险。

例如,你可以设置一个约束,以确保 StatefulSet 的 3 个副本彼此都运行在不同的区域中(只要可行)。你可以声明式地定义此约束,而无需显式定义每个工作负载使用的可用区。

跨区域分布节点

Kubernetes 核心不会为你创建节点; 你需要自己创建节点,或使用诸如 Cluster API 之类的工具来代表你管理节点。

使用诸如 Cluster API 之类的工具,你可以定义一组机器作为集群的工作节点跨多个故障域运行,并定义在整个区域服务中断的情况下自动修复集群的规则。

Pod 的手动区域分配

你可以将节点选择器约束应用于你创建的 Pod,以及应用于诸如 Deployment、StatefulSet 或 Job 之类的工作负载资源中的 Pod 模板。

区域的存储访问

创建持久卷时,Kubernetes 会自动将区域标签添加到链接到特定区域的任何 PersistentVolume。然后,调度器通过其 NoVolumeZoneConflict 谓词来确保声明给定 PersistentVolume 的 Pod 仅放置在该卷所在的同一区域中。

请注意,添加区域标签的方法可能取决于你的云提供商和你正在使用的存储配置器。始终参考特定环境的文档以确保配置正确。

你可以为 PersistentVolumeClaims 指定一个StorageClass,该 StorageClass 指定该类中的存储可能使用的故障域(区域)。要了解如何配置能够感知故障域或区域的 StorageClass,请参阅允许的拓扑

网络

Kubernetes 本身不包含区域感知的网络。你可以使用网络插件来配置集群网络,并且该网络解决方案可能具有特定于区域的元素。例如,如果你的云提供商支持具有 type=LoadBalancer 的服务,则负载均衡器可能只会将流量发送到与处理给定连接的负载均衡器元素在同一区域中运行的 Pod。有关详细信息,请查看云提供商的文档。

对于自定义或本地部署,也适用类似的考虑因素。服务Ingress 的行为(包括对不同故障区域的处理)的确取决于集群的设置方式。

故障恢复

设置集群时,你可能还需要考虑如果一个区域中的所有故障区域同时脱机,你的设置是否以及如何恢复服务。例如,你是否依赖于至少有一个节点能够在一个区域中运行 Pod?
确保任何集群关键修复工作都不依赖于集群中至少有一个健康的节点。例如:如果所有节点都不健康,你可能需要使用特殊的容忍度来运行修复 Job,以便修复能够完成,并使至少一个节点恢复服务。

Kubernetes 没有针对此挑战的答案;但是,这是需要考虑的事情。

下一步

要了解调度器如何在集群中放置 Pod,并遵守配置的约束,请访问调度和驱逐