Организация бесперебойной доставки обновлений для конечного пользователя – это крайне важный процесс, который должен учитываться в разработке с самого начала. Но что если нужно создать непрерывный поток для сторонней платформы? Попытаемся разобраться на явном примере.
Онлайн-система клиента была создана на основе Kubernetes, размещенной на собственных мощностях. Затем, все это перекочевало на платформу заказчика, что потребовало организации непрерывной доставки. Польза от этого решения очевидна – оперативное и комфортное обновление, не затрагивающее клиентов.
Разделим организацию Continuous Deployment (CD) на несколько этапов:
- Старт процесса
- Синхронизация со сторонним Git
- Бэкэнд и фронтэнд
- Тестовая среда и развертывание пробной версии
- Автоматическое развертывание в рабочей среде
1. Старт процесса непрерывной доставки обновлений
CD процесс всегда берет начало с «выкатывания» новой версии продукта в Git-репозитории.
Отметим, что созданное ПО для клиента имеет архитектуру на базе микросервисов, в котором есть лишь один единственный репозиторий для всех компонентов. Почему выбран именно этот метод? Вот несколько преимуществ:
- Свежее ПО всегда нуждается в доработке или добавлении новых возможностей, а значит, придется иметь дело с целым кодом.
- Это помогает организовать правильный CD, с помощью которого не игнорируется ни один компонент.
- Отпадает необходимость создания карты версий, так как обновляется абсолютно все.
2. Синхронизация со сторонним Git
Имеется в виду, синхронизация с репозиторием клиента, когда все обновления автоматически выкатываются на удаленную платформу. Как только в ветке появляется новая версия, начинается процесс сборки тестовой, а затем и рабочей версий.
Нужно учитывать тот факт, что клиентский репозиторий недоступен для прямого воздействия, потому что инструменты, среды разработки и другие платформы отличаются. А значит, синхронизация репозиториев – лучшее решение. Любое изменение на нашем сервере переносится на клиентский.
3. Бэкэнд и фронтэнд
На данном этапе работа должна вестись параллельно, так как они должны учитываться в системе GitLab Runner.
GitLab Runner берет из репозитория нужный для процесса код, чтобы потом собрать приложение на Java и отправить его в Docker. Именно здесь и будет происходить процесс организации бэкэнда и фронтэнда. Результатом будет готовый Docker-образ, в дальнейшем отправляемый на стороннюю платформу. Чтобы управлять образами нам пригодится специальный плагин Gradle.
Не забываем про синхронизацию в Docker! Не лишними будут следующие настройки:
1. Очень удобно, если контейнер сможет работать со всеми данными как в тестовой, так и в «боевой» версиях.
2. Чтобы реализовать процесс обновления на Helm, придется указывать версии. Всего их три: от бэкэнда, фронтэнда и самого обновления. Единый Git-репозиторий упрощает задачу.
Чтобы получить данные о текущей версии, введите следующую команду:
git describe —tags —abbrev=7
4. Тестовая среда и развертывание пробной версии
Далее мы выполняем тестовое развёртывание с помощью соответствующего скрипта на кластере K8S. Естественно, данный этап проходит лишь после успешной сборки и публикации в Docker Registry.
Сначала обновляется окружение, а сам кластер получает данные за счет Helm Update. Это удобный инструмент, который автоматически вернет все «как и было», если развертывание не удалось. Параллельно с основными данными для обновлений, на кластер приходит отдельный пакет с обновленной конфигурацией. Учитывается абсолютно каждый компонент.
Затем, Helm использует процедуру RollOut для массового обновления работающего ПО. Все действия и этапы реализуются исключительно в пределах тестовой среды. Только потом мы переходим к рабочей среде.
5. Автоматическое развертывание в рабочей среде
На самом деле, данный этап является чуть ли не самым простым, так как вся работа и тестовые процедуры уже подошли к концу. Нажимаем на нужную кнопку в GitLab и приложение обновляется полностью в рабочей среде.
В нашем примере мы используем внешние переменные, которые берутся для обновления продукта. А вот все остальные элементы одни и те же, и используются как для тестовой версии, так и для рабочей.
Стоит учитывать и то, что каждое приложение уникально и работает в собственной среде. А значит, нужно подходить к параметризации настроек достаточно гибко. Мы реализовали все через K8S конфигурации, а также индивидуальные настройки самой Helm.
В нашем примере наиболее сложным этапом реализации был именно вышеописанный процесс с параметризацией, так как приходилось учитывать все до мелочей в разных средах. Плюс ко всему, мы упрощали для себя жизни, используя внешние переменные.
Также учтите, что заданные переменные для окружения берутся из контейнеров с помощью K8S configmap. По сути, это готовый шаблон, который можно настроить на свое усмотрение. Вот простой пример реализации переменной окружения для домена:
APP_EXTERNAL_DOMAIN: {{ (pluck .Values.global.env .Values.app.properties.app_external_domain | first) }}
Немного поясним:
- .Values.global.env – переменная для хранения названия
- .Values.app.properties.app_external_domain – переменная для хранения домена, данные о котором берутся из файла .Values.yaml
В результате, Helm может реализовать создание нужных элементов, используя configmap.yaml, в котором вы зададите определенные шаблоны. Переменная APP_EXTERNAL_DOMAIN располагается в контейнере, а ее значение будет варьироваться в зависимости от окружения.
Кстати, в последних версиях Spring Cloud внедрили поддержку K8S. Мы планируем продолжать изучать новые возможности, а в данном случае, перейдем именно на это решение.
Итог
В результате, мы получили непрерывный процесс обновления на сторонней платформе, который может похвастаться своим удобством. Все происходит в автоматическом режиме и не влияет на работу пользователей приложения во время тестирования. Все системы работают исправно.
Квалифицированный DevOps инженер с опытом более 10-и лет, реализует для вашего предприятия непрерывную доставку обновлений конечному пользователю, а также решит другие задачи связанные с организацией и разработкой ПО. Обращайтесь [email protected]