
Есть довольно простой вопрос, который стоит задать ИТ-архитектору: «Что произойдёт, если сервер, на котором расположена служба каталогов, решит прилечь?». Если ответ начинается со слов «ну, вообще-то у нас есть бэкап», это не совсем отказоустойчивая архитектура.
Бэкап помогает восстановить систему. Но он не помогает пользователю войти в корпоративный сервис прямо сейчас.
Поэтому в новой версии MULTIDIRECTORY мы развиваем архитектуру службы каталогов в сторону мультиконтроллерной установки: несколько контроллеров домена, локальные (автономные) копии данных, репликация файлов и балансировка запросов.
В этой статье разберём, что происходит внутри такой системы и почему поставить второй сервер — ещё не значит получить отказоустойчивое решение.

Один сервер — это не отказоустойчивость
Начнём с классической схемы.
Есть служба каталогов. В ней хранятся пользователи, группы, политики и другие данные, необходимые корпоративной инфраструктуре. Есть один контроллер домена, к которому обращаются клиенты.
Упрощённо это выглядит так:

Пока всё работает, система выглядит вполне нормально. Проблема появляется, когда какой-нибудь компонент отказывает. Например, сервер вышел из строя, проблемы с диском, недоступна виртуальная машина, потеряна сеть, начались технические работы либо случился отказ площадки.
Причём наличие резервной копии само по себе проблему не решает. Бэкап отвечает на вопрос: «Как нам вернуть систему после аварии?» Отказоустойчивая архитектура отвечает на другой: «Как сделать так, чтобы пользователь вообще не заметил аварию?».

А что, если поставить два контроллера?
Первое очевидное решение — добавить второй сервер.

Уже лучше. Но здесь появляется следующий вопрос: а что именно синхронизируется между DC-01 и DC-02?
Недостаточно просто иметь два одинаковых сервера. Нужно обеспечить согласованность данных каталога, файлов, политик, конфигурации, состояния базы данных, клиентских запросов. И отдельно нужно решить, что произойдёт, если между площадками пропадёт связь.
Именно поэтому отказоустойчивость — это не столько несколько серверов, сколько набор механизмов, которые позволяют этим серверам работать как единой системе.
Как устроена отказоустойчивая архитектура MULTIDIRECTORY
В MULTIDIRECTORY мы строим архитектуру из нескольких контроллеров домена. Каждый контроллер — полноценный узел службы каталогов. При этом инфраструктура использует общий набор данных и механизмов синхронизации.
Упрощённо архитектуру можно представить так:

В MULTIDIRECTORY есть несколько уровней отказоустойчивости.
Первый уровень — контроллеры домена. Если один узел недоступен, другие продолжают обслуживать клиентов.
Второй — база данных. Основной экземпляр PostgreSQL имеет реплики, которые могут использоваться для чтения и участвовать в сценарии переключения.
Третий — файловые данные. Изменения файлов распространяются между контроллерами.
Четвёртый — маршрутизация запросов. Клиент понимает, к какому контроллеру ему обращаться.
Подсистема данных: PostgreSQL, Patroni и etcd
Один из центральных компонентов архитектуры — кластер баз данных на базе PostgreSQL. В штатном режиме один узел кластера выполняет роль основного (Leader), а остальные работают в режиме реплик (Replica).
При этом ответственность за работу кластера разделена между несколькими компонентами:
PostgreSQL отвечает непосредственно за хранение данных и передачу изменений на соседние узлы с помощью механизмов нативной потоковой репликации.
Patroni и etcd отвечают за логику управления кластером: мониторинг состояния узлов, автоматический выбор лидера (failover) и предоставление актуальной информации о том, какой узел сейчас доступен для записи, а какие — только для чтения.
Благодаря информации от Patroni/etcd, MULTIDIRECTORY корректно маршрутизирует два типа операций:
Запись всегда направляется строго на текущий основной узел (Leader).
Чтение выполняется с локальной репликой, находящейся рядом с конкретным контроллером.
Такой подход позволяет не отправлять каждый запрос чтения через сеть к центральному узлу. Для распределённой инфраструктуры это особенно критично: филиал может находиться в сотнях или тысячах километров от основной площадки, и локальное чтение радикально снижает задержки и нагрузку на магистральные каналы связи.
Почему локальная реплика — это не просто кэш
Здесь есть важный инженерный нюанс. Локальная реплика PostgreSQL — не кэш в привычном смысле. Она содержит реплицированное состояние базы и может обслуживать операции чтения. Это позволяет контроллеру домена получать необходимые данные локально, не обращаясь каждый раз к leader.
В результате уменьшается количество сетевых обращений между площадками и снижается нагрузка на основной экземпляр базы.
При потере связи с leader, контроллер домена переходит в ограниченный режим работы и продолжает работать в режиме только чтение. Таким образом даже в случае потери связи филиала с центром, филиал продолжает работать в ограниченном режиме, в котором доступны операции: идентификация, аутентификация и авторизация. При восстановлении связи локальная реплика оперативно актуализирует данные и контроллер домена продолжает работать в штатном режиме.
Также в MULTIDIRECTORY предусмотрен режим автоматического мониторинга активного узла leader, что позволяет решению автоматически переключаться на другой узел PostgresSQL в случае смены leader-а.
Решение MULTIDIRECTORY поддерживает активный мониторинг доступности\работоспособности контроллеров домена. В случае недоступности или выхода из строя контроллера домена, остальные узлы автоматически реконфигурируются и перестают направлять клиенты и сервисы на недоступные узлы.
А что происходит с файлами?
База данных — только часть службы каталогов. Есть ещё файловые данные: политики, конфигурационные файлы и другие данные, которые должны быть доступны на нескольких контроллерах.
Если просто поставить три DC и дать каждому собственную файловую систему, очень быстро появляется классическая проблема:
DC-1: "У меня политика версии 17"
DC-2: "У меня версии 16"
DC-3: "А я вообще не знаю, о чём вы"

Поэтому файловый контур также должен быть реплицирован. При изменении данных на одном контроллере изменения распространяются на остальные узлы. Таким образом, контроллеры получают согласованный набор файлов и настроек.
Как клиент выбирает контроллер
Теперь у нас есть несколько работающих контроллеров. Но возникает вопрос: как клиент понимает, к какому из них обращаться?
В MULTIDIRECTORY для этого используются механизмы DNS. Для контроллеров создаются отдельные записи, а также общая запись домена, связанная с несколькими IP-адресами. При обращении на общую запись, клиент получает адрес доступного контроллера в режиме Round-Robin и отправляет запрос туда.
Что даёт такая архитектура пользователю
Все эти PostgreSQL, DNS и реплики нужны не ради красивой архитектурной схемы. В конечном итоге пользователь должен увидеть очень простую картину: ничего не произошло.
Он открывает корпоративный сервис, вводит логин и пароль, проходит аутентификацию, получает доступ. И не знает, что за это время один сервер мог упасть, другой принять его запрос, а PostgreSQL переключиться на новую реплику.

Вместо заключения
Отказоустойчивость службы каталогов редко воспринимается как отдельная бизнес-функция. Пока всё работает, никто не думает о контроллерах домена. Но достаточно одному из них стать недоступным, и выясняется, сколько корпоративных процессов от них зависит.
Отказоустойчивая архитектура MULTIDIRECTORY позволяет минимизировать ущерб от отказа и позволяют построить службу каталогов, которая продолжает работать даже тогда, когда отдельные компоненты инфраструктуры перестают это делать.
Потому что в хорошей отказоустойчивой системе падение одного сервера — это событие для мониторинга, а не чрезвычайное происшествие для всей компании.
