考虑跨 3 个可用区的 Statefulset(Cassandra 使用官方 K8S 示例):
- cassandra-0 -> 区域 a
- cassandra-1 -> 区域 b
- cassandra-2 -> 区域 c
每个 Cassandra pod 都使用一个 EBS 卷。所以自动地有一个亲和力。例如,cassandra-0 无法移动到“zone-b”,因为它的卷位于“zone-a”中。都好。
如果某些 Kubernetes 节点/worker 发生故障,它们将被替换。pod 将在新节点上重新启动并重新附加其 EBS 卷。看起来什么都没发生。
现在,如果整个 AZ “zone-a”出现故障并且在一段时间内不可用(这意味着 cassandra-0 由于与 EBS 在同一区域中的相关性而无法再启动)。你剩下:
- cassandra-1 -> 区域 b
- cassandra-2 -> 区域 c
只要“zone-a”不可用,Kubernetes 就永远无法启动 cassandra-0。这一切都很好,因为 cassandra-1 和 cassandra-2 可以处理请求。
现在,如果最重要的是,另一个 K8S 节点出现故障,或者您已经设置了基础架构的自动扩展,那么您最终可能需要移动到另一个 K8S 节点的 cassandra-1 或 cassandra-2。这不应该是一个问题。
但是根据我的测试,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?