- PVSM.RU - https://www.pvsm.ru -

7 ноября на конференции HighLoad++ 2017 [1], в секции «DevOps и эксплуатация» прозвучал доклад «Лучшие практики CI/CD с Kubernetes и GitLab». В нём мы делимся практическим опытом решения проблем, возникающих при построении эффективного процесса CI/CD на базе указанных Open Source-решений.
По традиции рады представить видео с докладом [2] (около часа, гораздо информативнее статьи) и основную выжимку в текстовом виде.
Под CI/CD (Continuous Integration, Continuous Delivery, Continuous Delivery) мы понимаем все этапы доставки кода из Git-репозитория в production и последующее его обслуживание вплоть до «снятия» с production. Существующие интерпретации терминов CI/CD допускают различное отношение к этому последнему этапу (эксплуатации в production), но наш опыт говорит, что его исключение из CI/CD приводит к многочисленным проблемам.
Перед тем, как описывать конкретные практики, мы обобщили те основные факторы, которые влияют на сложность CI/CD:
Все эти варианты сведены в общий график, на котором проиллюстрировано, какими инструментами можно закрыть те или иные потребности:

Есть и другие — более общие (но не менее важные!) — требования, предъявляемые к CI/CD:

Наконец, у нас как компании, внедряющей и обслуживающей системы для CI/CD, есть дополнительные требования к используемым продуктам:
Стек продуктов, удовлетворяющих всем требованиям, у нас получился следующий:
А общий цикл CI/CD от Git до эксплуатации при использовании перечисленных инструментов выглядит так:

Образ должен содержать всё, что требуется для работы приложения:

Собранный однажды Docker-образ должен использоваться везде. Иначе на проверку к QA может попасть не то же самое, что будет выкачено на production (повторно собранное в другой момент времени).
У себя мы собираем временные образы из git branch и релизные образы из git tag:

Работа различных компонентов, описанных в Kubernetes (бэкенд как Deployment, СУБД как StatefulSet и т.п.), может зависеть друг от друга. В случае «прямолинейного» выката K8s будет обновлять компоненты и перезапускать их (в случае неуспешного старта):

И даже при корректной обработке всех этих событий компонентами (что тоже надо предусмотреть) общее время выката затянется из-за различных таймаутов в Kubernetes, срабатывающих (и накапливающихся) из-за необходимости ожидания запуска других служб (например, бэкенд ждёт доступности обновлённой базы данных, т.е. с проведённой миграцией).
Чтобы сократить время выката, нужно учитывать (и прописывать) не только явные зависимости между компонентами (бэкенд ждёт доступности СУБД), но и косвенные (бэкенд не должен обновляться до проведения миграций).

СУБД наполняют данными двумя путями: загрузкой готового дампа или загрузкой сидов/фикстур. Путь в Kubernetes для первого случая — это после старта СУБД запускать задание (Job), которое загружает дамп. После этого — запуск миграций (они косвенно зависят от дампа), а затем — запуск бэкенда (косвенно зависит от миграций).
Последовательность запуска для случая с сидами меняется и выглядит так: 1) СУБД, 2) миграции, 3) задание с сидами, 4) бэкенд (можно запустить в параллель с сидами, т.к. от сидов не должен зависеть).

Перебрав различные пути bootstrap'а БД, мы пришли к оптимальности двух: ночной дамп с seeds/fixtures из master и ночной дамп для staging.

Даже при правильном деплое новых версий приложения в Kubernetes не все нюансы будут автоматически учтены. Чтобы действительно гарантировать полное отсутствие простоя:

Если во время обновления какого-либо компонента инфраструктуры произошла ошибка (обновление не смогло выкатиться), в пайплайнах GitLab будет соответствующее уведомление, однако сама инфраструктура останется в переходном состоянии. Проблемный компонент не сохранит оригинальную (старую) версию, как «подумает» GitLab, а будет в состоянии не до конца выкатившейся новой версии.
Проблема решается использованием встроенной возможности отката (rollback) в случае возникновения такой ошибки. Причем скорее всего это стоит предусмотреть только в production, т.к. в dev-контурах вы с большой вероятностью захотите посмотреть на проблемный компонент в его переходном состоянии (разобраться в причинах возникновения проблемы).
Встроенные в GitLab возможности позволяют при git push'е любого branch (при наличии Helm chart для полного bootstrap'а инфраструктуры) разворачивать в Kubernetes готовую к использованию инсталляцию приложения (с одноимённым пространством имён). Аналогично будет происходить удаление пространства имён при удалении branch'а.
Однако при активном использовании этой возможности, требуемые для инфраструктуры ресурсы быстро разрастаются. Поэтому есть несколько рекомендаций по оптимизации динамических окружений:

Если с реализацией простых тестов (не нуждающихся в окружении) всё просто, то для функционального и интеграционного тестирования предлагаем создавать динамическое окружение с помощью Helm:

Возвращаясь к начальному графику с требованиями к CI/CD…

Описанные практики на базе Open Source-продуктов позволяют решать задачи, отмеченные зелёным цветом. Фиолетовым выделена область проблем, с которыми мы в компании «Флант» работаем буквально каждый день.
Видео с выступления (около часа) опубликовано в YouTube [2].
Презентация доклада:
Другие доклады в нашем блоге:
Вероятно, вас также заинтересуют следующие публикации:
Автор: distol
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sistemnoe-administrirovanie/271373
Ссылки в тексте:
[1] HighLoad++ 2017: http://www.highload.ru/2017/
[2] видео с докладом: https://www.youtube.com/watch?v=G3nELxmECd8&index=4&list=PL1mJ-PkCYnmB9vljnjxCMP3dlxQY3Dfcq
[3] dapp: https://github.com/flant/dapp
[4] Наш опыт с Kubernetes в небольших проектах (обзор и видео доклада): https://habrahabr.ru/company/flant/blog/331188/
[5] Собираем Docker-образы для CI/CD быстро и удобно вместе с dapp: https://habrahabr.ru/company/flant/blog/324274/
[6] Практики Continuous Delivery с Docker: https://habrahabr.ru/company/flant/blog/322686/
[7] Инфраструктура с Kubernetes как доступная услуга: https://habrahabr.ru/company/flant/blog/341760/
[8] GitLab CI для непрерывной интеграции и доставки в production. Часть 1: наш пайплайн: https://habrahabr.ru/company/flant/blog/332712/
[9] GitLab CI для непрерывной интеграции и доставки в production. Часть 2: преодолевая трудности: https://habrahabr.ru/company/flant/blog/332842/
[10] Источник: https://habrahabr.ru/post/345116/?utm_campaign=345116
Нажмите здесь для печати.