Этот репозиторий содержит примеры кода для моего доклада. Я не сомневаюсь, что все это не подходит для продакшена, но при этом уверен, что кого-то это натолкнет на мысли, кто-то сможет отсюда взять куски, узнать какие-то типично кривые трюки с башем или просто вдохновиться или огорчиться и сделать что-то своё, лучше. Данный код, как и весь код в репозитории, хоть и из живого проекта, но никогда не полировался и не затачивался для публикации в виде опенсорса. Он существует как дополнительный материал к презентации.
- Презентация доступна тут ./presentation.pdf
- Полноценные куски CI/CD джоб (а точнее, шаблонов) вы можете посмотреть в файле ./jobs.yml. Конечно, там много специфики, но что-то из этого вам может пригодится.
- Вот тут можно посмотреть как можно полноценно устроить CD для helm + k8s ./helm-cd.yml с поддержкой staging/production сред. Вероятно, вас удивит странный подход к формированию переменных окружения для разных сред с помощью страшных баш трансформаций. Это происходит из общего желания уменьшить дублирование кода (а именно, переменных). Дело в том, что переменные в гитлабе хоть и можно привязывать к средам, но в рамках 1 репозитория, а в случае моей презентации и моего пайплайна, есть группа и подгруппа над каждым репозиторием, и в каждом из них указаны переменные, которые наследуются и попадают в пайплайн. И вот их получать контекстно, в зависимости от окружения не получается (или в моей версии гитлаба невозможно). Поэтому вы и видите некрасивые трансформации.
- Автоверсионирование с защитой от чистки вы можете посмотреть вот здесь ./scripts/auto-semver.py
- ./scripts/validate-gitlab-ci.py неработоспособный скрипт (он работал только в лейауте моего централизованного пайплайна, а под ваш нужно будет немного адаптировать), цель которого продемонстрировать, что если у вас есть централизованный пайплайн (как в моем докладе) и вы хотите тестировать и его самого, то можно базово отвалидировать через сам gitlab собранные файлы этого пайплайна. Разумеется, написав для него .gitlab-ci.yml (получается по смыслу мета-пайплайн — пайплайн для пайплайна). Вы должны отдать ваши template jobs и «публичный интерфейс» (или несколько) и отправить его в gitlab линтер. Это поможет вам проверить ваш пайплайн на базовую корректность и работоспособность.
- ./scripts/lint.py тут лежит pylint & mypy линтинги с поддержкой baseline, возможности падения при оценке ниже требуемой оценки, а так же поддержкой «автопоиска» того, что нужно линтить в pylint. Сам алгоритм поиска это три очень плохих строчки и его легко улучшить, но это я уже оставлю вам.
set -x
в начале пайплайна: даёт вам возможность видеть как запускаются ваши баш команды и значительно упрощают их отладку.set -u
в.vars-check-job
— штука, которая позволяет вам с помощью простого echo защитить свой пайплайн от отсутсвующих переменных. Установите флаг, распечатайте переменные и если каких-то из них нет, пайплайн упадёт.- «Двойная докеризация» — собирайте в вашем пайплайне ваш образ с помощью
docker build
, kaniko или buildah. В ./jobs.yml пример с использованием buildah. В кавычках, потому что это не совсем двойная докеризация, но я не нашёл термин лучше, поэтому использую его. Имеется ввиду сборка контейнера внутри контейнера и запуск команд внутри контейнера, который запущен внутри контейнера. - Наследуйтесь от одной job'ы: потом проще ей задавать разные атрибуты, такие как interruptible или retry.
- Для множества микросервисов вам поможет централизация — сделать единый репозиторий и использовать пресеты. Т.е., например, вы используете текущий ./jobs.yml, а дальше пишете в
.gitlab-ci.yml
следующее:где:include: - project: 'xfenix/pycon2022' file: 'public-example.yml'
- xfenix/pycon2022 — путь к вашему репозиторию внутри вашего gitlab инстанса.
- public-example.yml — «пресет», где вы собираете пайплайн из jobs.yml. Имеет смысл собрать несколько таких пресетов. У нас в проекте есть
python
,python-postgres
,pypi
,pypi-poetry
,docker-build
,frontend
. - если вам нужен ещё более гранулярный контроль за составом пайплайна, подключайте не пресет, а jobs.yml напрямую.
- Если возможно, имеет смысл публичные переменные тоже собирать в пресеты. Например, у вас несколько репозиториев используют одинаковые не секретные переменные (username, docker registry address и прочее). Можно занести их в gitlab group vars, но они будут всегда «скрыты» (чтобы их посмотреть вам нужно будет зайти вглубь настроек gitlab проекта), а некоторым юзерам и вовсе недоступны, поэтому я и предлагаю положить их в файл. Пример: ./group-vars.yml
- Сборка образов в идеале должна предшествовать всем следующим шагам: сначала собираем образ, пушим его в удаленный registry, затем тестируем его, проводим статический анализ, а в конце скачиваем этот образ из registry, перетегиваем его и пушим с новым release тегом (характерным для вас) в удаленный registry. Смысл этого заключается в том, что в продакшн идут строго те образы, чьё окружение мы протестировали и статически проанализировали.
- Немного bash — не страшно!
- Шаблонные подстановки вроде
${VARIABLE:-default value}
очень помогают.