Как предотвратить несогласованность данных, когда один узел теряет подключение к сети в кубернетах

У меня есть ситуация, когда у меня есть кластер со службой (мы назвали его 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 почти такой же, просто измените терминологию.

Другие вопросы по тегам