CI/CD Kubernetes платформа Gitorion. Реплицируемый NAS для Highly Available кластера Kubernetes

от автора

Привет всем! В данной статье мы расскажем о том, как Stateful приложения хранят свои данные в Highly Available варианте CI/CD платформы Gitorion. В составе платформы Gitorion работает три Stateful приложения:

  • Gitea/Forgejo — хранит git‑репозитории с кодом приложений;

  • Jenkins — хранит свои настройки и пайплайны;

  • Docker‑registry — хранит Docker‑образы пользовательских микросервисов.

Также свои данные могут хранить пользовательские приложения, которые будут разрабатывать на платформе и деплоить в продакшен.

Абстрактная постановка задачи

Для Highly Avalable кластера Kubernetes, территориально разнесенного в два дата центра, разработать хранилище данных, в котором Stateful приложения могли бы хранить свои файлы и директории. На случай падения одного из дата центров, во втором дата центре должна быть актуальная копия данных Stateful приложений. Модули Stateful приложений должны подключаться к хранилищу по сети, чтобы обеспечить возможность горизонтального масштабирования.

Дисковая система и менеджмент разделов

В каждом из двух дата центров выделяем по одному узлу, который будет выполнять роль NAS. В роли NAS может выступать отдельный VPS или выделенный сервер с серверными дисками. Зависит от вашего бюджета и предпочтений. Важно, чтобы была возможность подключать новые диски, когда закончится свободное место.

Для менеджмента разделов мы используем LVM.

Дисковая система и менеджмент разделов

Дисковая система и менеджмент разделов

Следующие ниже действия выполняем зеркально на обоих NAS в каждом дата центре. Создаем отдельный Volume Group с именем «nas». Отдельный VG позволит решить две задачи:

  • хранить данные приложений отдельно от операционной системы, чтобы в случае падения, операционная система не утянула за собой данные хранилища;

  • добавить в VG новые диски и расширить разделы Logical Volume, когда на них закончится свободное место.

Для инстансов Gitea/Forgejo, Jenkins и Docker‑registry создаем отдельные Logical Volume в Volume Group «nas», созданном выше. Забегая вперед, отметим, что для репликации потребуются LV одинакового размера в каждом из дата центров для конкретно взятого инстанса.

Репликация данных между дата центрами

Для репликации данных мы выбирали между Ceph, GlusterFS и DRBD. Ceph отмели из‑за требовательности к ресурсам и требований к наличию отдельной ноды для хранения метаданных. GlusterFS оказался неплох для репликации в пределах одного дата центра при небольших задержках по сети между реплицируемыми нодами и непригоден для репликации между географически разнесенными нодами и при высоких задержках по сети. В итоге наш выбор пал на DRBD — проверенный временем инструмент, включенный в ядро Linux c 2009 года.

DRBD выполняет репликацию локального блочного устройства по сети на удаленное блочное устройство. Своего рода сетевое зеркало RAID1. В роли реплицируемых блочных устройств в нашем случае выступают Logical Volume, созданные в предыдущем пункте. DRBD создает виртуальные блочные устройства /dev/drbd1, /dev/drbd2, /dev/drbd3… /dev/drbdX и ассоциирует их с реплицируемыми блочными устройствами. Впоследствии на виртуальном блочном устройстве /dev/drbdX создается файловая система, монтируется и используется приложениями.

Кластер DRBD

Кластер DRBD

Конфигурационный файл DRBD:

resource r0 {   volume 0 {     device    /dev/drbd1;     disk      /dev/nas/forgejo;     meta-disk internal;   }   volume 1 {     device    /dev/drbd2;     disk      /dev/nas/jenkins;     meta-disk internal;   }   volume 2 {     device    /dev/drbd3;     disk      /dev/nas/registry;     meta-disk internal;   }   on dc1-nas {     address   1.1.1.1:7789;   }   on dc2-nas {     address   2.2.2.2:7789;   } }

Список блочных устройств:

NAME                    MAJ:MIN RM    SIZE RO TYPE MOUNTPOINTS sda                       8:0    0      5G  0 disk ├─sda1                    8:1    0    487M  0 part /boot ├─sda2                    8:2    0      1K  0 part └─sda5                    8:5    0    4.5G  0 part   ├─template--vg-root   254:1    0    3.6G  0 lvm  /   └─template--vg-swap_1 254:3    0    980M  0 lvm sdb                       8:16   0      5G  0 disk ├─nas-forgejo           254:0    0      1G  0 lvm │ └─drbd1               147:1    0 1023.9M  0 disk ├─nas-jenkins           254:2    0      1G  0 lvm │ └─drbd2               147:2    0 1023.9M  0 disk ├─nas-registry          254:4    0      1G  0 lvm   └─drbd3               147:3    0 1023.9M  0 disk

Превращаем файловое хранилище в NAS

Существует несколько вариантов подключения внешних томов Persistent Volume к модулям Kubernetes. Мы выбрали сетевой том Persistent Volume типа NFS. Данное архитектурное решение позволяет горизонтально масштабировать кластер Kubernetes, о чем мы расскажем чуть позже.

А пока превратим наше файловое хранилище в NAS. Дальнейшие действия выполняем только на Primary ноде, являющейся источником репликации DRBD в ведущем дата центре. Форматируем виртуальные блочные устройства DRBD и монтируем в директорию /mnt

mkfs.ext4 /dev/drbd1 mkfs.ext4 /dev/drbd2 mkfs.ext4 /dev/drbd3 mount /dev/drbd1 /mnt/forgejo mount /dev/drbd2 /mnt/jenkins mount /dev/drbd3 /mnt/registry

Устанавливаем NFS-сервер и экспортируем смонтированные файловые системы в сеть по протоколу NFS. Файл /etc/exports

/mnt/forgejo/ 3.3.3.3(rw,sync,no_subtree_check,all_squash) /mnt/jenkins/ 3.3.3.3(rw,sync,no_subtree_check,all_squash) /mnt/registry/ 3.3.3.3(rw,sync,no_subtree_check,all_squash)
Схема NAS

Схема NAS

В итоге мы получили NAS в ведущем дата центре, который отдает по NFS в сеть директории, смонтированные на виртуальные блочные устройства DRBD. А DRBD реплицирует данные на Seconrady DRBD ноду в ведомый дата центр.

Подключение модулей Kubernetes к NAS

В Kubernetes мы создали тома Persistent Volume типа NFS которые подключаются по сети к NAS. А уже Persistent Volume подключаются к Stateful модулям Kubernetes.

Схема подключения модулей Kubernetes к NAS

Схема подключения модулей Kubernetes к NAS

Падение ведомого дата центра

В случае падения ведомого дата центра, модули Stateful просто продолжают свою работу в ведущем дата центре. Единственное, что нужно сделать, это в ведущем дата центре отключить Primary ноду из кластера DRBD и перевести в Stand Alone режим пока будут чинить упавший дата центр. Как только починят ведомый дата центр, нужно подключить Primary ноду обратно в кластер DRBD, и накопившаяся дельта данных реплицируется на Secondary ноду DRBD.

Падение ведомого дата центра

Падение ведомого дата центра

Падение ведущего дата центра

В случае падения ведущего дата центра Kubernetes запустит модули Stateful приложений в выжившем ведомом дата центре. А тома Persistent Volume модулей Gitea/Forgejo, Jenkins, Docker‑registry подключатся к NAS в выжившем дата центре и Stateful приложения продолжат работать с данным, которые реплицировал RDBD из упавшего дата центра на момент падения.

Падение ведущего дата центра

Падение ведущего дата центра

Отдельно осветим механизм переключение Persistent Volume c одного NAS на другой. В спецификации Persistent Volume мы задали доменное имя NFS-сервера nas.gitorion.ru

apiVersion: v1 kind: PersistentVolume metadata:   name: forgejo spec:   accessModes:   - ReadWriteOnce   capacity:     storage: 50Gi   nfs:     path: /mnt/forgejo     server: nas.gitorion.ru   persistentVolumeReclaimPolicy: Retain   storageClassName: net-disks

А на worker-ах доменное имя NFS-сервера nas.gitorion.ru статикой в /etc/hosts связываем с IP-адресом NAS в том же дата центре, в котором расположен worker:

Файл /etc/hosts на dc1-worker:

127.0.0.1       localhost  1.1.1.1         nas.gitorion.ru

Файл /etc/hosts на dc2-worker:

127.0.0.1       localhost  2.2.2.2         nas.gitorion.ru

В итоге модули Stateful приложений, используя одно и то же доменное имя NFS-сервера nas.gitorion.ru, в спецификации Persistent Volume подключаются к NAS в дата центре, в котором будут запущены.

После восстановления упавшего дата центра репликацию DRBD нужно развернуть в обратном направлении — ноду DRBD в выжившем дата центре сделать Primary, а в восстановленном дата центре Secondary.

Split-brain

Это ситуация, при которой оба дата центра живы, но пропадает связь между ними. Мы используем только однонаправленную DRBD репликацию. В любой момент времени модули Stateful запущены только в ведущем дата центре и подключены к NAS и Primary ноде DRBD, являющейся источником репликации. Второй NAS всегда в роли ведомого, DRBD нода на нем работает в режиме Secondary и просто хранит копию данных на случай падения ведущего дата центра. Поэтому ситуация одновременной записи в оба NAS исключена.

Горизонтальное масштабирование

Наличие реплицируемых NAS в двух дата центрах открывает возможность горизонтального масштабирования пользовательских Stateful приложений, когда мощностей имеющихся дата центров станет не хватать.

В этом случае можно подключить в кластер Kubernetes дополнительные worker‑ы из других дата центров и запустить на них дополнительные реплики пользовательских Stateful приложений, которые будут по NFS подключаться к ведущему NAS.

Горизонтальное масштабирование кластера Kubernetes

Горизонтальное масштабирование кластера Kubernetes

Однако, не стоит забывать, что Stateful приложения будут подключаться к NAS через Интернет, и могут существенно возрасти задержки по сравнению с подключением к NAS в пределах одного дата центра.

Заключение

В итоге мы получили внешнее файловое хранилище для Highly Available кластера Kubernetes, разнесенного на два дата центра. Файловое хранилище подключается к кластеру Kubernetes как NAS по сетевому протоколу NFS, что позволяет горизонтально масштабировать Stateful приложения. В каждом дата центре имеется свой NAS, данные между которыми реплицирует DRBD, что дает возможность останавливать Stateful приложения в одном дата центре и запускать в другом в случае аварий. Спасибо за внимание!


ссылка на оригинал статьи https://habr.com/ru/articles/845120/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *