Устройство реконфигурации во время выполнения
Реконфигурация во время выполнения — одна из самых сложных и подверженных ошибкам возможностей распределённой системы, особенно основанной на консенсусе системы вроде etcd.
Ниже описано устройство команд реконфигурации etcd и способы решения связанных проблем.
Двухфазное изменение конфигурации сохраняет безопасность кластера
В etcd каждая реконфигурация во время выполнения в целях безопасности проходит две фазы . Например, чтобы добавить участника, сначала сообщите кластеру новую конфигурацию, а затем запустите участника.
Фаза 1 — сообщение кластеру новой конфигурации
Чтобы добавить участника в кластер etcd, вызовите API с запросом на его добавление. Это единственный способ добавить нового участника в существующий кластер. Вызов API возвращается после того, как кластер согласует изменение конфигурации.
Фаза 2 — запуск нового участника
Чтобы присоединить нового участника etcd к существующему кластеру, укажите правильный initial-cluster и задайте initial-cluster-state значение existing. При запуске участник сначала связывается с существующим кластером и проверяет, соответствует ли текущая конфигурация ожидаемой, заданной в initial-cluster. После успешного запуска нового участника кластер достигает ожидаемой конфигурации.
Разделение процесса на две отдельные фазы заставляет явно задавать изменения состава кластера. Это даёт больше гибкости и упрощает анализ. Например, попытка добавить в кластер etcd нового участника с тем же ID, что у существующего, немедленно завершится ошибкой на первой фазе и не повлияет на работающий кластер. Аналогичная защита предотвращает случайное добавление участников. Если новый участник etcd попытается присоединиться до принятия кластером изменения конфигурации, кластер его не примет.
Без явной процедуры управления составом etcd был бы уязвим для неожиданных изменений. Например, если etcd работает под управлением системы инициализации вроде systemd, после удаления через API состава systemd перезапустит etcd, и тот при запуске попытается снова войти в кластер. Если systemd настроен перезапускать etcd после сбоя, этот цикл будет повторяться при каждом удалении участника через API, что является неожиданным поведением.
Реконфигурация во время выполнения предполагается редкой операцией. Явная процедура под управлением пользователя обеспечивает безопасность конфигурации и позволяет кластеру стабильно работать под непосредственным контролем.
Безвозвратная потеря кворума требует нового кластера
Если кластер безвозвратно потерял большинство участников, для восстановления предыдущего состояния потребуется запустить новый кластер из старого каталога данных.
Технически можно принудительно удалить отказавших участников из существующего кластера и восстановить его. Однако etcd не поддерживает этот способ, поскольку он обходит обычную фазу фиксации консенсусом и небезопасен. Если удаляемый участник на самом деле не отказал или принудительное удаление выполняется через разных участников одного кластера, получится расходящийся кластер с одинаковым clusterID. Это крайне опасно и впоследствии трудно диагностируется и исправляется.
При правильном развёртывании вероятность безвозвратной потери большинства очень мала. Но последствия достаточно серьёзны и требуют специальной подготовки. Перед вводом etcd в эксплуатацию настоятельно рекомендуется прочитать документацию по аварийному восстановлению и подготовиться к безвозвратной потере большинства.
Не используйте общедоступную службу обнаружения для реконфигурации
Общедоступную службу обнаружения следует применять только для начальной инициализации кластера. Для присоединения участника к существующему кластеру используйте API реконфигурации во время выполнения.
Служба обнаружения предназначена для начальной инициализации кластера etcd в облачной среде, когда IP-адреса всех участников заранее неизвестны. После успешной инициализации они становятся известны, и служба обнаружения технически больше не нужна.
Использование общедоступной службы обнаружения для реконфигурации может показаться удобным, поскольку она уже содержит всю конфигурацию кластера. Однако зависимость от неё создаёт проблемы:
Внешняя зависимость сохраняется на протяжении всего жизненного цикла кластера, а не только во время инициализации. Проблемы сети между кластером и общедоступной службой будут влиять на кластер.
В течение всего жизненного цикла общедоступная служба должна отражать правильную текущую конфигурацию кластера. Ей потребуются механизмы безопасности против вредоносных действий, что сложно реализовать.
Общедоступной службе придётся хранить десятки тысяч конфигураций кластеров. Бэкенд нашей службы не готов к такой нагрузке.
Для поддержки реконфигурации лучше всего создать частную службу обнаружения.