Надёжность и катастрофоустойчивость
Платформа позволяет управлять физическими и виртуальными ресурсами независимых по доступности зон (зоны доступности, availability zones) из единого интерфейса и иметь общую базу пользователей.
Платформа поддерживает конфигурацию с несколькими зонами доступности и с размещением в 3 ЦОД, расстояние между которыми менее 3 км. ЦОД соединены 40 ГБ каналами, сетевая задержка между ЦОД составляет не более 10 мс.
Время восстановления работоспособности после наступления аварийного события (RTO) составляет 4 часа, допустимая потеря данных (RPO) — 5 минут.
Схема сетевой связности приведена на рисунке 1.

Для обеспечения катастрофоустойчивости Dev Platform и базовые сервисы разворачиваются в кластере Kubernetes, который включает в себя группы хостов в разных зонах доступности. Оркестратор Magnum не поддерживает режим мульти-зональности для Control Plane кластера, поэтому после первичного развёртывания два из трёх master-узлов переносятся в соседние ЦОД-ы при помощи процедуры Nova Live Migrate, выполняющей миграцию узлов без перезагрузки.
Балансировщик Octavia также не поддерживает мульти-зональность, поэтому для балансировки запросов развёртываются две ВМ с HAProxy. Backend серверами являются все рабочие узлы (worker node) Kubernetes кластера. Входящий трафик поступает на сервисы через NodePort. Для обеспечения катастрофоустойчивости HAProxy использует протокол BGP. На балансировщиках (LB) помимо собственных IP-адресов заводится дополнительный Loopback интерфейс с одинаковыми адресами для всех LB. Маршрут до Loopback IP анонсируется силами фабрики через BGP, в DNS запись для балансировщика указывает на Loopback IP.
Изоляция облачных проектов осуществляется при помощи Firewall.
Сервисы, развёрнутые в Kubernetes:
- Dev Platform Public API.
- Dev Platform Queue.
- Dev Platform Operator.
- GitLab.
- Nexus.
- SonarQube.
- Dev Prom.
В ВМ разворачивается сервис HAProxy, схема развёртывания которого приведена на рисунке 2.
СУБД PostgreSQL запускается в кластере Kubernetes с использованием оператора Postgres Operator Zalando, в качестве хранилища конфигурации выступает Kubernetes ETCD (распределенная key-value база данных).
Patroni поддерживает динамическое изменение конфигурации PostgreSQL одновременно на всех узлах кластера, синхронизируя фактическое состояние каждого кластера Postgres с желаемым состоянием, определенным в манифесте. Также Patroni обеспечивает автоматическое переключение на реплику в случае выхода из строя master-узла.
Информация о том, какой узел является мастером, хранится в ETCD кластере, состоящим из 3-х нод — по одной в каждом ЦОД-е. В случае потери связи с одним ЦОД-ом, ноды ETCD из двух оставшихся ЦОД-ов временно отключают утерянную ноду и используют RAFT протокол для выбора нового лидера. ЦОД3 выступает в качестве арбитра и позволяет избежать ситуации «split brain», когда два ЦОД-а начинают независимо принимать транзакции на запись и изменение данных.
За управление пулом соединений Postgres отвечает PGbouncer, для снятия нагрузки с master-узла он предоставляет два подключения:
- Для операций чтения или записи — запросы идут на master-узел.
- Только для операций чтения — запросы идут на реплику.
Хранение резервных копий и WAL-файлов осуществляется в бакетах S3, для этого:
- Отключается процесс репликации (WAL логи начинают копиться на master-узле).
- Создаётся копия папки с данными и WAL логами на реплике.
- Восстанавливается процесс репликации.
- Архивируется копия данных на реплике и отправляется в бакет S3.
PostgreSQL поддерживает восстановление на точку времени (Point-in-time-recovery).
Кластер Gitaly, схема которого приведена на рисунке 3, обеспечивает избыточное хранение git репозиториев в виртуальном хранилище, для высокой скорости выполнения операций ввода-вывода используются локальные диски (Ceph), расположенные в трёх ЦОД.
Инстансы с Nexus разворачиваются в двух ЦОД. Схема развёртывания приведена на рисунке 4. Для обеспечения катастрофоустойчивости доступны следующие конфигурации репозиториев:
- hosted-ha: hоsted + proxy — пара хостед и прокси репозиториев, развёрнутая в двух инстансах. Доступны операции записи и чтения (PUSH, PULL).
- proxy-ha: proxy + proxy — пара прокси репозиториев, развёрнутая в двух инстансах, один из которых проксирует удалённый репозиторий (публичный репозиторий во внешней сети, у подрядчика и вендора), а другой проксирует первый прокси. Доступны операции чтения (PULL).
При недоступности Hosted Nexus ноды в конфигурации hоsted + proxy запускается восстановление Nexus Proxy. На время восстановления система переходит в режим только для чтения (Read Only).
При недоступности Nexus Proxy ноды чтение идёт из Nexus Hosted. Схема такого случая приведена на рисунке 5.
При недоступности Proxy Nexus ноды из ЦОД2 в конфигурации proxy + proxy запускается восстановление Nexus Proxy. На время восстановление чтение переключается на другую Nexus Proxy ноду из ЦОД1.
СУБД MySQL, схема развёртывания которого приведена на рисунке 6, запускается в кластере Percona XtraDB в Kubernetes и использует библиотеку Galera для обеспечения синхронной репликации из нескольких источников. Galera автоматически обрабатывает размещение данных на разных узлах, позволяя при этом отправлять запросы чтения и записи на любой узел кластера.
Балансировку нагрузки обеспечивает HAProxy, принимающий входящий трафик и перенаправляющий его на внутренние серверы MySQL.
Хранение резервных копий осуществляется в бакетах S3.