Kubernetes Stateful set,AZ和Volume声明:当AZ失败时会发生什么

时间:2018-02-09 03:43:05

标签: amazon-web-services kubernetes kubernetes-statefulset

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

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

每个Cassandra pod使用EBS卷。所以自动有亲和力。例如,cassandra-0无法移动到“zone-b”,因为其卷位于“zone-a”中。一切都好。

如果某些Kubernetes节点/工作人员失败,他们将被替换。 pod将在新节点上重新启动并重新连接其EBS卷。看起来什么都没发生。

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

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

只要“zone-a”不可用,Kubernetes就永远无法启动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?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

两个选项:

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

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

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

选项2:创建3个不同的statefulets

每个AZ / Rack有1个状态。每个statefulset都有约束,因此它只能在特定AZ中的节点上运行。我还有3个存储类(再次约束到特定区域),以确保statefulset不在错误的区域中配置EBS(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”< / LI>
  • 等到第一个种子(cassandra-a-0)准备就绪,然后再创建其他2个状态集。否则你会得到一个裂脑。这只是创建群集时的问题。之后,您可以松散一个或两个种子节点而不会产生影响,因为第三个节点知道所有其他节点。