繁体   English   中英

Kube.netes Stateful set、AZ 和 Volume 声明:AZ 失败时会发生什么

[英]Kubernetes Stateful set, AZ and Volume claims: what happens when an AZ fails

考虑跨 3 个可用区的 Statefulset(Cassandra 使用官方 K8S 示例):

  • cassandra-0 -> 区域 a
  • cassandra-1 -> b 区
  • cassandra-2 -> 区域 c

每个 Cassandra pod 使用一个 EBS 卷。 所以会自动产生亲和力。 例如,cassandra-0 不能移动到“zone-b”,因为它的卷在“zone-a”中。 都好。

如果一些 Kube.netes 节点/workers 发生故障,它们将被替换。 Pod 将在新节点上重新启动并重新连接到它们的 EBS 卷。 看起来什么都没发生过。

现在,如果整个 AZ“zone-a”出现故障并且在一段时间内不可用(意味着 cassandra-0 由于对同一区域中的 EBS 的亲和力而无法再启动)。 你还剩下:

  • cassandra-1 -> b 区
  • cassandra-2 -> 区域 c

只要“zone-a”不可用,Kube.netes 就永远无法启动 cassandra-0。 这一切都很好,因为 cassandra-1 和 cassandra-2 可以处理请求。

现在,如果最重要的是,另一个 K8S 节点出现故障,或者您已经设置了基础设施的自动缩放,您最终可能需要 cassandra-1 或 cassandra-2 才能移动到另一个 K8S 节点。 这应该不是问题。

但是根据我的测试,K8S 不会这样做,因为 pod cassandra-0 处于离线状态。 它永远不会自我修复 cassandra-1 或 cassandra-2(或任何 cassandra-X),因为它希望 cassandra-0 先回来。 而 cassandra-0 无法启动,因为它的卷位于一个已关闭且未恢复的区域中。

因此,如果您跨区域使用 Statefulset + VolumeClaim +并且您遇到整个 AZ 故障并且您在另一个 AZ 中遇到 EC2 故障或者您的基础设施具有自动扩展

=> 那么您将丢失所有 Cassandra 吊舱。 直到 zone-a 重新上线

这似乎是一个危险的情况。 有没有办法让有状态集不关心顺序并仍然自我修复或在 cassandra-3、4、5、X 上启动更多 pod?

从Kubernetes 1.7开始,您可以告诉Kubernetes使用podManagementPolicy选项( 文档 )放松StatefulSet排序保证。 通过将该选项设置为Parallel Kubernetes将不再保证在启动或停止pod并且并行启动pod时的任何顺序。 这可能会对您的服务发现产生影响,但应该解决您正在讨论的问题。

两种选择:

选项1: 使用podManagementPolicy并将其设置为Parallel。 pod-1和pod-2将崩溃几次,直到种子节点(pod-0)可用。 第一次创建statefulset时会发生这种情况。 另请注意,Cassandra文档过去建议不要并行创建多个节点,但似乎最近的更新使这不正确。 可以同时向群集添加多个节点

发现问题:如果使用2个种子节点,您将获得裂脑情景。 将同时创建每个种子节点,并创建2个单独的逻辑Cassandra集群

选项1b: 使用podManagementPolicy并将其设置为Parallel并使用ContainerInit。 与选项1相同,但使用initContainer https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ init容器是一个短期容器,用于在启动实际容器之前检查种子节点是否可用。 如果我们很高兴pod会崩溃直到种子节点再次可用,那么这不是必需的。问题是Init Container将始终运行,这不是必需的。 我们希望确保Cassandra集群在第一次创建时形成良好。 之后无所谓

选项2: 创建3个不同的状态填充

每个AZ / Rack有1个状态。 每个statefulset都有约束,因此它只能在特定AZ中的节点上运行。 我还有3个存储类(再次约束到特定区域),以确保statefulset不在错误的区域中提供EBS(statefulset还没有动态处理它)在每个statefulset中我都有一个Cassandra种子节点(定义为环境变量CASSANDRA_SEEDS,它在运行时填充SEED_PROVIDER)。 这使3个种子充足。 由于复制因子= 3,我的设置可以在完整的区域中断后继续存在

提示:

  • 种子节点列表包含用逗号分隔的所有3个节点:“cassandra-a-0.cassandra.MYNAMESPACE.svc.cluster.local,cassandra-b-0.cassandra.MYNAMESPACE.svc.cluster.local,cassandra-c- 0.cassandra.MYNAMESPACE.svc.cluster.local”
  • 等到第一个种子(cassandra-a-0)准备就绪,然后再创建其他2个状态集。 否则你会得到一个裂脑。 这只是创建群集时的问题。 之后,您可以松散一个或两个种子节点而不会产生影响,因为第三个节点知道所有其他节点。

我认为,如果您可以控制每个 pod 的部署(cassandra-0、cassandra-1、cassandra-2 具有三个不同的 yaml 部署文件),则可以将 podAffinity 设置为每个 pod 的特定区域。

一旦区域上的节点发生故障并且必须重新安排在该服务器内运行的 pod,亲和力将强制 Kube.netes 将 pod 部署在同一区域的不同节点上,如果同一区域上没有节点可用, Kube.netes 应该无限期地关闭那个 pod。

例如,您可以创建一个具有三个不同 managedNodeGroup 的 Kube.netes 集群,每个区域一个(标签“zone”:每个组的“a”、“b”、“c”),每个组至少有两个节点,并使用 podAffinity。

注意:不要为节点使用 x1.32xlarge 机器:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM