https://github.com/belyaevEDU/devops-app-helm - Helm для развертывания приложения + observability stack values
https://github.com/belyaevEDU/repeating-functions-sharedlib - shared library для Jenkins пайплайна, содержит функцию для ожидания поднятия приложения.
Проект заключался в:
- написании простого API на Python и FastAPI
- развертывании Kubernetes кластера на трех виртуальных машинах с помощью Ansible
- построении CI/CD процесса, который бы проводил линтинг, сборку образа, тестировал и развертывал приложение на Kubernetes кластере
Далее проект был перенесен с их инфраструктуры и GitLab Yadro на GitHub и собственную инф-ру для доработки. Список доработок:
- Перенос CNI и Ingress controller с Calico + ingress-nginx на Cilium (#9)
- Мониторинг с Grafana, Prometheus, Grafana Loki & Alloy. К тому же, приложение было инструментировано для Prometheus (#12)
При отправке изменений в репозиторий, хост репозитория отправляет сообщение вебхуку Jenkins. Запускается пайплайн, описанный в Jenkinsfile и схематично представленный на диаграмме. В диаграмме пайплайна, первый блок - триггер, далее сами шаги.
В CI пайплайне были использованы следующие инструменты для своих согласных шагов:
- Lint - линтинг исходного кода приложения на Python: Ruff
- SAST - статическое тестирование безопасности с правилами, согласно используемым в приложении технологиям: Semgrep
- Build: Docker
- Test: Docker с hardened docker-compose файлом + Newman с тестами для Postman
- SCA: Trivy
- Publish: Docker, образ отправляется на Docker Hub
В основе процесса continuous deployment взята методология GitOps.
Приложение развернуто с помощью ArgoCD, ArgoCD Image Updater и Helm.
На GitHub был создан отдельный репозиторий, на котором лежит Helm chart для развертывания приложения в staging-окружении и production-окружении.
CI, при триггере тега или master, заканчивается шагом "Publish" (не считая cleanup), который публикует новый образ в Docker Hub. Если Image Updater видит новую версию приложения, то он обновляет в Helm-specific репозитории values файлы, меняя именно версию. Далее, ArgoCD по webhook получает уведомление о изменениях в Helm-specific репозитории и обновляет те приложения, которые получили изменения.
Правила Image Updater:
- Для staging, CI публикует образ с неизменяемым тегом
staging, как следствие для него используется стратегия digest, которая обновляет хэш - Для production, CI публикует образ с тегом, который был создан в гите, соответствующий semantic versioning. Для него используется стратегия semver, которая обновляет версию согласно правилам semantic versioning.
Эта часть - доработка после завершения курса с целью освоить этот ряд технологий.
В Kubernetes кластере был развернут kube-prometheus-stack, Grafana Loki и Alloy с помощью Helm и ArgoCD. Файлы с values лежат в helm-specific репозитории, а манифесты argocd приложений в этом репозитории, здесь.
К тому же, приложение было инструментировано под Prometheus с помощью модуля prometheus-fastapi-instrumentator, который отдает метрики по ручке /metrics. Для этого приложение запускает отдельный HTTP сервер на порте 9100, который не выводится Ingress.
Kube-prometheus-stack включает в себя Grafana и Prometheus.
В helm чарте приложения был добавлен ServiceMonitor, который собирает метрики от приложения по ручке /metrics каждые 30 секунд. К тому же, был добавлен лейбл, по которому Alloy собирает логи приложения.
Нам выделенная инфраструктура от Yadro на время курса стояла за одним внешним IP и моя локальная инфраструктура стоит за CGNAT. Как следствие, для получения запросов из открытой сети требуется reverse proxy. Для этого был использован проект frp. Манифесты для деплоймента frp client находятся здесь.
Трафик идет следующим образом:
К тому же, в диаграмме неймспейса currency в секции Observability можно заметить cert-issuer, который запрашивает TLS сертификат от LetsEncrypt для запросов с HTTPS.



