An open API service indexing awesome lists of open source software.

https://github.com/xfenix/pycon2022

Примеры к докладу «Современный CI/CD пайплайн для python микросервисов» на конференции pycon 2022
https://github.com/xfenix/pycon2022

ci cicd conference docker gitlab gitlab-ci kubernetes microservices pycon pycon2022

Last synced: 6 months ago
JSON representation

Примеры к докладу «Современный CI/CD пайплайн для python микросервисов» на конференции pycon 2022

Awesome Lists containing this project

README

          

# Современный CI/CD пайплайн для python микросервисов
![](https://badgen.net/badge/pycon/2022/?color=yellow)

Этот репозиторий содержит примеры кода для моего доклада. Я не сомневаюсь, что все это не подходит для продакшена, но при этом уверен, что кого-то это натолкнет на мысли, кто-то сможет отсюда взять куски, узнать какие-то типично кривые трюки с башем или просто вдохновиться или огорчиться и сделать что-то своё, лучше.
Данный код, как и весь код в репозитории, хоть и из живого проекта, но никогда не полировался и не затачивался для публикации в виде опенсорса. Он существует как дополнительный материал к презентации.

### Содержимое
* Презентация доступна тут [./presentation.pdf](./presentation.pdf)
* Полноценные куски CI/CD джоб (а точнее, шаблонов) вы можете посмотреть в файле [./jobs.yml](./jobs.yml). Конечно, там много специфики, но что-то из этого вам может пригодится.
* Вот тут можно посмотреть как можно полноценно устроить CD для helm + k8s [./helm-cd.yml](./helm-cd.yml) с поддержкой staging/production сред. Вероятно, вас удивит странный подход к формированию переменных окружения для разных сред с помощью страшных баш трансформаций. Это происходит из общего желания уменьшить дублирование кода (а именно, переменных). Дело в том, что переменные в гитлабе хоть и можно привязывать к средам, но в рамках 1 репозитория, а в случае моей презентации и моего пайплайна, есть группа и подгруппа над каждым репозиторием, и в каждом из них указаны переменные, которые наследуются и попадают в пайплайн. И вот их получать контекстно, в зависимости от окружения не получается (или в моей версии гитлаба невозможно). Поэтому вы и видите некрасивые трансформации.
* Автоверсионирование с защитой от чистки вы можете посмотреть вот здесь [./scripts/auto-semver.py](./scripts/auto-semver.py)
* [./scripts/validate-gitlab-ci.py](./scripts/validate-gitlab-ci.py) неработоспособный скрипт (он работал только в лейауте моего централизованного пайплайна, а под ваш нужно будет немного адаптировать), цель которого продемонстрировать, что если у вас есть централизованный пайплайн (как в моем докладе) и вы хотите тестировать и его самого, то можно базово отвалидировать через сам gitlab собранные файлы этого пайплайна. Разумеется, написав для него .gitlab-ci.yml (получается по смыслу мета-пайплайн — пайплайн для пайплайна). Вы должны отдать ваши template jobs и «публичный интерфейс» (или несколько) и отправить его в gitlab линтер. Это поможет вам проверить ваш пайплайн на базовую корректность и работоспособность.
* [./scripts/lint.py](./scripts/lint.py) тут лежит pylint & mypy линтинги с поддержкой baseline, возможности падения при оценке ниже требуемой оценки, а так же поддержкой «автопоиска» того, что нужно линтить в pylint. Сам алгоритм поиска это три очень плохих строчки и его легко улучшить, но это я уже оставлю вам.

### Возможности, на которые я делаю акцент
* `set -x` в начале пайплайна: даёт вам возможность видеть как запускаются ваши баш команды и значительно упрощают их отладку.
* `set -u` в `.vars-check-job` — штука, которая позволяет вам с помощью простого echo защитить свой пайплайн от отсутсвующих переменных. Установите флаг, распечатайте переменные и если каких-то из них нет, пайплайн упадёт.
* «Двойная докеризация» — собирайте в вашем пайплайне ваш образ с помощью `docker build`, [kaniko](https://github.com/GoogleContainerTools/kaniko) или [buildah](https://buildah.io/). В [./jobs.yml](./jobs.yml) пример с использованием buildah. В кавычках, потому что это не совсем двойная докеризация, но я не нашёл термин лучше, поэтому использую его. Имеется ввиду сборка контейнера внутри контейнера и запуск команд внутри контейнера, который запущен внутри контейнера.
* Наследуйтесь от одной job'ы: потом проще ей задавать разные атрибуты, такие как interruptible или retry.
* Для множества микросервисов вам поможет централизация — сделать единый репозиторий и использовать пресеты. Т.е., например, вы используете текущий [./jobs.yml](./jobs.yml), а дальше пишете в `.gitlab-ci.yml` следующее:
```yaml
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](./group-vars.yml)
* Сборка образов в идеале должна предшествовать всем следующим шагам: сначала собираем образ, пушим его в удаленный registry, затем тестируем его, проводим статический анализ, а в конце скачиваем этот образ из registry, перетегиваем его и пушим с новым release тегом (характерным для вас) в удаленный registry. Смысл этого заключается в том, что в продакшн идут строго те образы, чьё окружение мы протестировали и статически проанализировали.
* Немного bash — не страшно!
* Шаблонные подстановки вроде `${VARIABLE:-default value}` очень помогают.