Как предотвратить несогласованность данных, когда один узел теряет подключение к сети в кубернетах
У меня есть ситуация, когда у меня есть кластер со службой (мы назвали его A1) и его данными, которые в моем случае находятся в удаленном хранилище, например cephFS. количество реплик для моей службы равно 1. Предположим, у меня есть 5 узлов в моем кластере, а служба A1 находится в узле 1. Что-то происходит с сетью узла 1, и он теряет связь с кластером cephFS и моим кластером Kubernetes (или докер- рой). кластер помечает его как недоступный и запускает новую службу (мы назвали ее A2) на узле 2, чтобы сохранить реплику как 1. после, например, 15 минут, когда сеть узла 1 зафиксирована, а узел 1 вернется в кластер, и служба A1 уже запущена (предположим, что это не произошел сбой при потере связи с удаленным хранилищем).
Я работал с docker-swarm и недавно перешел на Kubernetes. Я вижу, что у Kuber есть вызов функции StatefulSet, но когда я читал об этом. это не отвечает на мой вопрос. (или я могу что-то пропустить, когда читаю об этом)
Вопрос A: что делает кластер. сохраняет ли он A2 и выключает A1 или позволяет A1 продолжать работу и выключать A2 (логически он должен выключить A1)
Вопрос B (а также мой основной вопрос!): Предположим, что кластер хочет завершить работу этих служб (например, A1). Эта служба немного экономит на хранилище, когда она хочет выключиться. в этом случае состояние A1 сохраняет на диск, а A2 с более новым состоянием что-то сохраняет до того, как сеть A1 будет исправлена. Должны быть некоторые блокировки, когда мы монтируем том в контейнер, в котором, когда он присоединен к одному контейнеру, другой контейнер не может писать в него (пусть A1 потерпел неудачу, когда хочет сохранить данные своего старого состояния на диск)
1 ответ
Как это работает — используя терминологию docker swarm —
У вас есть услуга. Служба — это описание некоторого образа, который вы хотите запустить, сколько реплик и так далее. Предполагая, что служба указывает, что по крайней мере 1 реплика должна быть запущена, она создаст задачу, которая запланирует контейнер на узле роя. Таким образом, служба связана с 0 для многих задач, где каждая задача имеет 0 — если она все еще запущена или 1 контейнер — если задача выполняется или остановлена — которая находится на узле.
Итак, когда рой (оркестратор) обнаруживает, что узел отключился, он в основном видит, что ряд задач, связанных со службой, потеряли свои контейнеры, и поэтому репликация (с точки зрения запущенных задач) больше не является правильной для службы, и он создает новые задачи, которые, в свою очередь, планируют новые контейнеры на доступных узлах.
На отключенном узле рабочий роя замечает, что он потерял связь с менеджерами роя, поэтому он очищает все задачи, которые он держит, поскольку у него больше нет текущей информации о них. В процессе очистки задач связанные контейнеры останавливаются.
Это хорошо, потому что, когда узел, наконец, повторно подключается, нет состояния гонки, когда выполняются две задачи. Работает только "А2", а "А1" выключен. Это плохо, если у вас есть ситуация, когда узлы могут часто терять связь с менеджерами, но вам нужно, чтобы службы продолжали работать на этих узлах, так как они будут закрываться каждый раз, когда рабочие отсоединяются.
Процесс на K8s почти такой же, просто измените терминологию.