Привет, всем! В предыдущих статьях мы рассмотрели общую концепцию и составные части платформы, git-сервер и непрерывную интеграцию CI, подсистему непрерывной доставки CD, систему единой аутентификации SSO и приватный репозиторий Docker-образов. В данной статье мы расскажем, как строили кластер высокой доступности Kubernetes для нашей платформы.
Абстрактная постановка задачи
Абстрактно задача была озвучена так - масштабировать кластер Kubernetes на два дата центра и проработать Highly Avalable архитектуру, не имеющую единой точки отказа и позволяющую кластеру Kubernetes пережить падение любого из дата центров.
Highly Available решение из официального руководства
Kubernetes хранит настройки в базе данных etcd. Соответственно Highly Available кластер Kubernetes хранит настройки в кластере etcd, состоящем из нескольких нод etcd. Поэтому построение Highly Avalable кластера Kubernetes сводится к построению кластера etcd. Официальная документация предлагает две топологии: Stacked etcd topology и External etcd topology
В обоих случаях придется строить кластер etcd, которому требуется n/2+1 ноды etcd в строю, чтобы провести кворум и выбрать лидера, где n-общее количество нод. В противном случае, кластер etcd становится недоступен и падает плоскость управления Kubernetes. Таблицу можно найти в разделе FAQ официального руководства etcd.
Количество нод в кластере |
Требуется живых нод |
Может упасть |
1 |
1 |
0 |
2 |
2 |
0 |
3 |
2 |
1 |
4 |
3 |
1 |
5 |
3 |
2 |
6 |
4 |
2 |
7 |
4 |
3 |
8 |
5 |
3 |
9 |
5 |
4 |
В итоге какое количество нод etcd не размести в двух дата центрах, с падением одного из дата центров падает половина или большинство нод etcd. Оставшиеся в меньшинстве ноды etcd в выжившем дата центре не смогут провести кворум и выбрать лидера, и кластер Kubernetes упадет в обоих дата центрах. Минимальное решение (которое нам удалось найти), способное пережить падение одного из дата центров - это 3 дата центра по 2 ноды etcd в каждом. Но данное решение для нас оказалось избыточным.
Замена etcd на SQL-базу данных
Мы нашли способ заменить базу данных etcd на SQL-базу данных, в которой Kubernetes также может хранить свои настройки - это Kine от проекта K3S. Kine, с одной стороны, реализует интерфейс etcd для Kubernetes, а с другой может хранит настройки кластера Kubernetes в одной из трех SQL-баз данных: SQLite, PostgreSQL или MySQL/MariaDB. Также Kine может использовать для хранения данных брокер NATS, но у нас не получилось настроить NATS без единой точки отказа.
Поэтому решили остановиться на одной из трех предложенных SQL-баз данных. Выбор базы данных дело вкуса. От базы потребуется только Master-Slave репликация. Указанные SQL-базы данных не имеют архитектурных особенностей etcd по связности, приведенных в предыдущем пункте, и позволяют построить Highly Available кластер Kubernetes в двух дата центрах без избыточности и дополнительных затрат.
Архитектура Highly Available кластера Kubernetes
В итоге у нас получилась вот такая архитектура
Зеркально в двух дата центрах мы разместили Control Plane ноды плоскости управления Kubernetes - Control Plane1 и Control Plane 2. Для запуска компонентов CI/CD платформы и пользовательских приложений в каждом дата центре подключили в кластер Worker ноды - Worker node 1 и Worker node 2. Ingress-nginx принимает запросы из Интернета и перенаправляет их в модули компонентов CI/CD платформы и пользовательских приложений.
В каждом дата центре на Control Plane ноду установили Kine и подключили к SQL-базе данных. Важный нюанс! Все Kine в любой момент времени должны писать в одну и ту же базу данных. Вариант, при котором каждый Kine пишет в базу данных в своем же дата центре, а затем сделать репликацию Master-Master между базами данных не получится. Репликация вскоре развалится из-за дублирующихся записей. Рабочий вариант приведен на рисунке выше - оба Kine пишут в одну и ту же базу данных, являющуюся мастером. А база данных в соседнем дата центре подключается как Slave и реплицирует базу данных, на случай падения дата центра с мастером.
Сценарий падения дата центра со Slave репликой
При падении дата центра в котором располагается Slave реплика SQL-базы данных никаких действий выполнять не требуется. Кластер Kubernetes продолжит работать в выжившем дата центре, а упавшие ноды просто будут помечены плоскостью управления как NotReady.
После возвращения в строй дата центра со Slave репликой нужно восстановить Master-Slave репликацию. Упавшие Control Plane и Worker ноды будут найдены плоскостью управления и переведены в состояние Ready автоматически. Если по какой-то причине ноды в упавшем дата центре не возможно восстановить, их можно установить с нуля и подключить в кластер Kubernetes командой kubeadm.
Сценарий падения дата центра с Master репликой
Если упадет дата центр с Master-репликой, то в выжившем дата центре скрипт liveness-script автоматически выявит падение Master реплики, и API Kubernetes остановит на Slave репликацию и сделает ее мастером. Затем переключит Kine на работу с SQL-базой данных в своем же дата центре.
После восстановления упавшего дата центра, Control Plane и Worker ноды будут автоматически найдены плоскостью управления и переведены в состояние Ready. Также можно установить ноды с нуля и подключить в кластер командой kubeadm в случае невозможности их восстановления. Далее в поднятом дата центре нужно запустить liveness-script, который подключит SQL-базу данных как Slave реплику к ушедшему вперед мастеру в выжившем дата центре и переключит Kine на мастер в выжившем дата центре.
Заключение
В итоге мы получили распределенный на два дата центра Highly Available кластер Kubernetes, который хранит свои настройки в SQL-базе данных. В каждом дата центре располагается копия настроек кластера Kubernetes, что позволяет ему выжить при падении любого из дата центров. На случай падения обоих дата центров или ошибок в SQL-базе данных, следует сохранять ежедневный бэкап на отчуждаемый носитель. Дамп базы данных занимает несколько мегабайт. В следующих статьях мы рассмотрим Highly Avalable решения для CI/CD компонентов платформы и пользовательских приложений. Спасибо за внимание!
Комментарии (7)
regret
31.07.2024 10:54Благодарю за статью!
Etcd позиционирует себя как "высокоскоростное" хранилище key-value, и возникает вопрос - а не сравнивали ли случайно производительность API kubernetes с etcd и c kine+pg? Или может kine берет на себя какие-то кеширующие задачи а "исторические" данные закидывает в pg? Сам с kine не работал - очень интересно стало.gitorion Автор
31.07.2024 10:54Спасибо за фидбек. К сожалению производительность API Kubernetes с etcd и SQL-базой данных не сравнивали. Просто не совсем понятна методика тестирования. Если есть возможность, подскажите методику мы с удовольствием протестируем и отпишемся о результатах. Про кэширование в Kine информации не встречали. Тут только смотреть код
regret
31.07.2024 10:54На самом деле предполагал даже не сколько сам ETCD, сколько его в связке с API Kubernetes на условные чтение-запись, просаживается ли и сильно ли.
В целом еще раз спасибо за статью, возможно с коллегами тоже пощупаем данный подход и проверим.
inkvizitor68sl
А как проблему со splitbrain решаете?
В статье нет ничего про случай, если оба ДЦ работают, но потеряли связь друг с другом.
gitorion Автор
Хороший вопрос! В случае потери связи между дата центрами обе реплики SQL-базы данных станут мастерами, и сообщение об этом высылается админам. Чтобы не разъехались данные, админы настраивают балансер HAProxy или DNS Round Robin так, чтобы весь трафик пошел в выбранный ими дата центр. Реплика SQL-базы данных выбранного дата центра становится мастером после восстановления связи между дата центрами.
inkvizitor68sl
Ну сам по себе старый мастер слейвом же не станет?
У ДЦ выключается сеть, происходит splitbrain, ДЦ без сети (точнее, база) продолжает считать себя мастером (и переключить её невозможно, т.к. сети нет), haproxy в этом ДЦ продолжает проксировать трафик туда.
Или есть стопкран/арбитр/etc?
gitorion Автор
Можно в облаке поставить небольшой VPS, установить в него скрипт, отслеживающий ситуацию, когда оба стали мастерами, и гасить один из дата центров. При этом внешний балансер HAProxy автоматически сделает keep-alive чек и направит трафик в выживший дата центр.