Набор Kubernetes Stateful, утверждения AZ и Volume: что происходит, когда AZ выходит из строя

Рассмотрим Statefulset (Cassandra на официальном примере K8S) в трех зонах доступности:

  • cassandra-0 -> зона а
  • кассандра-1 -> зона б
  • кассандра-2 -> зона c

Каждый модуль Cassandra использует том EBS. Итак, родство возникает автоматически. Например, кассандра-0 не может переместиться в «зону-b», потому что ее объем находится в «зоне-а». Все хорошо.

Если некоторые ноды / рабочие Kubernetes выйдут из строя, они будут заменены. Поды снова запустятся на новом узле и снова подключат свой том EBS. Похоже, ничего не произошло.

Теперь, если вся "зона-а" AZ выходит из строя и какое-то время недоступна (это означает, что cassandra-0 больше не может запускаться из-за привязки к EBS в той же зоне). У вас осталось:

  • кассандра-1 -> зона б
  • кассандра-2 -> зона c

Kubernetes никогда не сможет запустить cassandra-0, пока «zone-a» недоступна. Это все хорошо, потому что cassandra-1 и cassandra-2 могут обслуживать запросы.

Теперь, если вдобавок к этому другой узел K8S выйдет из строя или у вас настроено автоматическое масштабирование инфраструктуры, вы можете получить cassandra-1 или cassandra-2, необходимые для перехода на другой узел K8S. Это не должно быть проблемой.

Однако из моего тестирования K8S не будет этого делать, потому что модуль cassandra-0 отключен. Он никогда не будет самостоятельно лечить кассандру-1 или кассандру-2 (или любую другую кассандру-X), потому что сначала он хочет вернуть кассандру-0. И cassandra-0 не может запуститься, потому что его громкость находится в зоне, которая не работает и не восстанавливается.

Итак, если вы используете Statefulset + VolumeClaim + для разных зон, И вы испытываете сбой всей зоны доступности, И вы испытываете сбой EC2 в другой зоне доступности или имеете автоматическое масштабирование вашей инфраструктуры

=> тогда вы потеряете все свои стручки Кассандры. До тех пор, пока зона-а не вернется в режим онлайн

Это похоже на опасную ситуацию. Есть ли способ для набора с отслеживанием состояния не заботиться о порядке и по-прежнему самовосстановиться или запустить больше подов на кассандре-3, 4, 5, X?


person VinceMD    schedule 09.02.2018    source источник


Ответы (2)


Начиная с Kubernetes 1.7 вы можете указать Kubernetes ослабить гарантии упорядочения StatefulSet, используя параметр podManagementPolicy (документация). Установив для этого параметра значение Parallel, Kubernetes больше не будет гарантировать какой-либо порядок при запуске или остановке модулей и запускать модули параллельно. Это может повлиять на обнаружение вашей службы, но должно решить проблему, о которой вы говорите.

person Lorenz    schedule 09.02.2018
comment
Это полезно. Это может быть слишком общим. Мне все еще нужно, чтобы мои семенные узлы Cassandra сначала загрузились, и только тогда я могу создавать другие параллельно. Сейчас я создал 3 набора состояний с 3 классами хранения. Используя привязку, я могу ограничить предоставление наборов состояний в их собственной зоне доступности. Это означает, что я могу сохранить заказанный способ запуска и завершения, но я делаю это для каждой зоны доступности. Я могу легко контролировать стручки в каждой зоне доступа. Пока что мои тесты были убедительными. podManagementPolicy сейчас слишком прост для моего варианта использования - person VinceMD; 21.02.2018
comment
Устаревшая ссылка, не могли бы вы ее обновить? - person Kostrahb; 10.07.2021

Два варианта:

Вариант 1. используйте podManagementPolicy и установите для него значение Parallel. Модули Pod-1 и Pod-2 будут аварийно завершены несколько раз, пока не станет доступен начальный узел (Pod-0). Это происходит при первом создании набора состояний. Также обратите внимание, что документация Cassandra раньше рекомендовала НЕ создавать несколько узлов параллельно, но похоже, что недавние обновления делают это неверным. В кластер можно добавить несколько узлов одновременно

Обнаружена проблема: при использовании 2 исходных узлов вы получите сценарий разделения мозга. Каждый начальный узел будет создан одновременно и создаст 2 отдельных логических кластера Cassandra.

Вариант 1 б: используйте podManagementPolicy, установите для него значение Parallel и используйте ContainerInit. То же, что и вариант 1, но с использованием initContainer https://kubernetes.io/docs/concepts/workloads/pods/init-containers/. Контейнер инициализации - это недолговечный контейнер, который должен проверять доступность начального узла перед запуском самого контейнера. Это не требуется, если мы счастливы, что модуль выйдет из строя до тех пор, пока начальный узел снова не станет доступным. Проблема в том, что всегда будет запускаться Init-контейнер, что не требуется. Мы хотим, чтобы кластер Cassandra был правильно сформирован при первом создании. После этого не имеет значения

Вариант 2. Создайте 3 разных состояния.

1 пакет состояний на АЗ / стойку. Каждый набор состояний имеет ограничения, поэтому он может работать только на узлах в определенной зоне доступности. У меня также есть 3 класса хранения (снова ограничение для определенной зоны), чтобы убедиться, что набор состояний не предоставляет EBS в неправильной зоне (набор состояний еще не обрабатывает это динамически). В каждом наборе состояний у меня есть начальный узел 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), прежде чем создавать два других набора состояний. Иначе получится разделенный мозг. Это проблема только при создании кластера. После этого вы можете потерять один или два семенных узла без какого-либо воздействия, поскольку третий знает обо всех остальных.
person VinceMD    schedule 20.02.2018