Ludovic Poitou, 18 июня 2019 года
Пару недель назад на Конференции ForgeRock Identity Live я делал доклад о службе каталогов ForgeRock Directory Services (DS) в мире Docker/Kubernetes (K8S), пытаясь ответить на вопрос о взаимоотношениях DS и Docker/K8S: друзья они или враги?
Перед тем как погрузиться в данную тему, позвольте мне отметить пару очевидных вещей: вся наша индустрия движется по направлению к Облаку, а Docker/Kubernetes становятся стандартным способом развертывания программного обеспечения в Облаке, в любом Облаке. Поэтому сама постановка вопроса о том, кто же, в конце концов, DS и K8S — друзья или враги, не совсем корректна. Я уверен, что это неизбежно, и в ближайшем будущем мы развернем и будем полностью поддерживать Directory Services в K8S. Но насколько хорошей представляется идея сделать это уже сегодня? Давайте рассмотрим, почему мы задаёмся этим вопросом сегодня, какие преимущества можно получить от использования Kubernetes для развёртывания программного обеспечения, какие имеются ограничения для развёртывания текущей версии Directory Services (6.5) в Kubernetes, а также над чем сейчас работает ForgeRock для улучшения поддержки работы DS в K8S. В заключение я остановлюсь на том, почему Directory Services является хорошим решением для сохранения данных, будь то локально или в Облаке.
Основная причина появления подобной дискуссии связана с природой Directory Services. DS — это не просто веб-приложение без сохранения состояния. Directory Services одновременно является и приложением с сохранением состояния, и распределённым приложением. Это и есть два основных аспекта, которые требуют особого внимания при попытке развёртывания в контейнерах. Во-первых, Directory Services — это приложение с сохранением состояния, поскольку оно представляет собой место, где кто-либо может хранить состояния всех этих веб-приложений без сохранения состояния. В нашей платформе мы используем DS для хранения данных ForgeRock Access Management, будь то изменяемые во время выполнения приложений данные конфигурации, токены и идентификационные данные пользователя. Во-вторых, Directory Services — это распределённое приложение, поскольку его экземпляры должны общаться друг с другом для обеспечения репликации и согласованности данных. В связи с тем, что базы данных и распределённые приложения требуют более тесной согласованности (оркестровки) и координации между элементами системы, в мире Kubernetes они реализованы как Наборы с сохранением состояния (Stateful Sets) и используют Постоянные тома (Persistent Volumes, PV). Поэтому и наша Модель облачного развертывания (Cloud Deployment Model, CDM) для ForgeRock Directory Services также реализована по тому же принципу.
Стоит отметить, что Persistent Volume — это API Kubernetes, и что существует несколько типов таких томов, а также множество разных реализаций их провайдеров. Некоторые из этих типов PV выпущены совсем недавно и всё ещё находятся в стадии бета-версий. Таким образом, при использовании Kubernetes для приложений, сохраняющих данные, следует обладать хорошим пониманием характеристик и производительности доступных в вашем окружении вариантов Persistent Volumes.
Разработчики активно используют контейнеры, потому что так им проще сосредоточиться на том, что они должны создавать и тестировать. Вместо того, чтобы часами разбираться, как установить и настроить базу данных и построить платформу мониторинга для проверки правильности функционирования своей работы, они могут подтянуть откуда-нибудь один или несколько готовых образов Docker, которые автоматизируют эту задачу.
При переносе приложения в рабочую среду ключевым аспектом становится автоматизация. Kubernetes со своим семейством инструментов позволяет администраторам описать необходимые приложениям целевые архитектуры, автоматизировать развертывание, мониторинг и реагирование на инциденты. Обычно в кластере Kubernetes, если администратору, к примеру, требуется как минимум 3 экземпляра приложения, Kubernetes отреагирует на исчезновение одного из экземпляров и немедленно запустит новый. Ещё одним ключевым преимуществом Kubernetes является автоматическое масштабирование. Рабочее окружение Kubernetes может реагировать на предупреждения системы мониторинга или внешние сигналы и добавлять или удалять экземпляры приложения с целью поддержания большей или меньшей рабочей нагрузки. Так можно оптимизировать стоимость работы программного решения в целом, выделяя дополнительные ресурсы для компонентов с пиковыми нагрузками за счёт компонентов, работающих на нормальном или низком уровнях нагрузки.
Но автоматическое масштабирование — это не то, что подходит абсолютно всем приложениям, и обычно Directory Services, как и большинство баз данных, не масштабируются автоматически путём добавления большего количества запущенных экземпляров. Поскольку базы данных имеют состояние и данные, а также ожидают эксклюзивного доступа к файлам, добавление новой реплики является дорогостоящей операцией. Чтобы ещё один экземпляр системы управления базами данных мог использовать данные, необходимо сделать копию этих данных специально для этого экземпляра. Кроме того, добавление нового экземпляра Directory Services позволяет масштабировать (улучшить производительность) только операций чтения данных. Операцию записи, выполненную на каком-либо сервере, необходимо реплицировать на все остальные серверы. Таким образом, все серверы будут иметь одинаковую производительность записи и одинаковое количество дисковых операций ввода-вывода. В мире баз данных единственный путь масштабирования операций записи — это распределение (разбиение) данных на несколько серверов (технология shard). Такая возможность пока не доступна в Directory Services, но планируется к реализации в будущих выпусках. (Обратите внимание, что в Directory Proxy Services 6.5 уже есть поддержка разбиения данных по технологии shard, хотя и с некоторыми ограничениями. Но этот прокси ещё не является частью Модели облачного развертывания (CDM)).
Ещё одним ограничением Directory Services 6.5 является то, как работает репликация. Функционал репликации DS был спроектирован много лет назад, когда администраторы самостоятельно развёртывали серверы и не трогали их до того момента, когда что-то шло не так. У серверов были постоянные имена хостов или IP-адреса, и они знали всех своих соседей. В мире контейнеров адрес экземпляра сервиса становится известен только после старта этого экземпляра. А иногда вам нужно одновременно запустить несколько экземпляров сервиса. Текущая модель облачного развертывания ForgeRock и Docker-образы Directory Services, которые мы предлагаем, обходят ограничения системы управления репликацией путём предварительно сконфигурированной репликации для фиксированного (и небольшого) максимального количества реплик. После этого динамически добавить другую реплику невозможно. Кроме того, утилиту dsreplication нельзя использовать в Kubernetes. К счастью, мониторинг репликации и, что более важно, мониторинг её латентности возможны с помощью Prometheus — технологии мониторинга, используемой в Kubernetes по умолчанию.
За последний год мы много работали над перепроектированием системы управления и первоначальной инициализацией репликации между экземплярами Directory Services. Нашей главной задачей в этой работе было сделать это таким образом, чтобы мы могли продолжать реплицировать содержимое каталогов под управлением новых версий DS с каталогами под управлением предыдущих версий DS. Интероперабельность и совместимость репликации между разными версиями Directory Services были и останутся ключевыми ценностями этого продукта, позволяя клиентам развертывать новые версии с нулевым временем простоя службы каталогов. Мы переходим к использованию полноценных сертификатов, подписанных Корневым удостоверяющим центром, и взаимной TLS-аутентификации для установления доверия между репликами. Настройка новой реплики больше не потребует обновления всех серверов в топологии, а реплики, которые были удалены или остановлены на некоторое время, будут автоматически удалены из топологии (как и связанные с ними журналы изменений и метаданные). При старте новой реплики ей нужно будет знать только об ещё одной работающей реплике (либо ей нужно будет сообщить, что она является первой работающей репликой). Эти изменения значительно упростят автоматическое развёртывание новой реплики и снимут ограничение на количество реплик. Мы также работаем над совершенствованием способа резервного копирования и восстановления как хранилища данных, так и сервера целиком, при котором можно будет напрямую использовать облачные хранилища (cloud buckets), такие как S3 или GCS. Все описанные здесь изменения планируются к выходу в следующей версии сервера (в которой сменится старший номер версии) в первой половине 2020 года. Большинство из этого функционала будет использоваться нашей собственной платформой ForgeRock Identity Platform в качестве предлагаемых услуг, которая будет запущена в стадиях "Ранний доступ" и "Бета" уже в этом году.
Как только у нас появится возможность полностью автоматизировать развертывание и обновление кластера экземпляров Directory Services в одном или нескольких дата-центрах, мы начнём работать над горизонтальной масштабируемостью для Directory Services и обеспечением способа наращивания числа серверов по мере увеличения хранимых данных, что позволит обеспечить постоянный уровень производительности операций записи на всём протяжении работы служб каталогов. Всё это будет полностью автоматизировано для развертывания в облаке с использованием Kubernetes.
Люди часто спрашивают меня, почему им стоит использовать ForgeRock Directory Services, а не реальную базу данных? Прежде всего, Directory Services — это и есть база данных. Это специализированная база данных, построенная на стандартной модели данных, для доступа к которой используется стандартный протокол: Lightweight Directory Access Protocol (LDAP). Кое-кто даже когда-то утверждал, что LDAP, возможно, был первой успешной NoSQL-базой данных! 🙂 Более того, Directory Services также предоставляет все данные через REST/JSON API, с обеспечением тех же механизмов безопасности и детального контроля доступа, что и через LDAP. Но главная ценность Directory Services заключается в том, что вы можете добиться очень высокой доступности данных (99,999%), используя стандартные системы (будь то физические сервера, виртуальные хосты или контейнеры) даже в условиях глобального географического распределения данных. У нас много клиентов, развернувших единую службу каталогов в нескольких (от трёх до шести) дата-центрах, распределённых по всему Земному шару. Модель данных LDAP имеет гибкую схему данных, которую можно расширять и подстраивать под свои нужды без необходимости перестраивать базу данных или даже перезагружать серверы. Данные могут быть доступны даже через версионные API с помощью нашего REST API. Наконец, комбинация гибкой и расширяемой схемы данных с детальным контролем доступа позволяет различным приложениям осуществлять доступ к данным, при этом строго разграничивая то, какое приложение и какие данные может читать или записывать. В результате у пользователя получается единая идентификационная сущность и удостоверяющие данные, но несколько наборов атрибутов, которые могут как совместно использоваться разными приложениями, так и быть доступными только для одного приложения. То есть вы получаете единое централизованное представление о пользователе, простое, и, вместе с тем, эффективное и экономичное в управлении.
Возвращаясь к Kubernetes, из-за ограничений текущей Модели облачного развертывания Directory Services версии 6.5, мы бы рекомендовали пока оставить ваши каталоги на Directory Services в виртуальных машинах или на физических серверах. Но уже со следующего выпуска, который ляжет в основу ForgeRock Cloud, мы будем полностью поддерживать развёртывание Directory Services в Docker/Kubernetes. В дальнейшем мы будем развивать наш продукт, чтобы в последующих выпусках он поддерживал автоматическое масштабирование (с использованием разбиения данных по технологии shard). Построение такого решения не является чем-то невероятно сложным, но нам потребуется время, чтобы убедиться в его 100% надёжности в любых условиях, поскольку для нас наиболее востребованной и ценной характеристикой ForgeRock Directory Services является надёжность.