Привет, всем! В предыдущих статьях мы рассмотрели общую концепцию и составные части платформы, 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 компонентов платформы и пользовательских приложений. Спасибо за внимание!