Ответ
На последнем проекте мы использовали GitLab CI/CD для сборки микросервисов на Go и Python. Процесс был полностью автоматизирован и основан на принципах GitOps.
Архитектура пайплайна (.gitlab-ci.yml):
stages:
- build
- test
- scan
- package
- deploy
variables:
DOCKER_REGISTRY: "registry.example.com"
IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"
# 1. Сборка
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build
--build-arg VERSION="$IMAGE_TAG"
-t "$DOCKER_REGISTRY/myapp/service:$IMAGE_TAG" .
- docker push "$DOCKER_REGISTRY/myapp/service:$IMAGE_TAG"
only:
- merge_requests
- main
# 2. Многоуровневое тестирование
test:
stage: test
image: "$DOCKER_REGISTRY/myapp/service:$IMAGE_TAG"
script:
- go test ./... -v -coverprofile=coverage.out
- ./run_integration_tests.sh
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.out
# 3. Сканирование уязвимостей (Trivy)
security_scan:
stage: scan
image: aquasec/trivy:latest
script:
- trivy image --exit-code 1 --severity HIGH,CRITICAL "$DOCKER_REGISTRY/myapp/service:$IMAGE_TAG"
# 4. Создание Helm-чарта
package:
stage: package
script:
- helm package ./charts/myapp --version "1.0.$CI_PIPELINE_ID"
- helm push myapp-*.tgz oci://$DOCKER_REGISTRY/helm
# 5. GitOps-деплой через ArgoCD
# АргоCD автономно отслеживает изменения в Helm-репозитории
Ключевые практики:
- Многоступенчатые Dockerfile: Использовал
multi-stage buildsдля создания минимальных образов (от 1.2 ГБ до ~80 МБ). - Кэширование зависимостей: В Go-проектах кэшировал
$GOCACHEи$GOMODCACHEмежду запусками пайплайна, что сокращало время сборки с 5 до 1.5 минут. - Единый источник истины: Манифесты Kubernetes и конфигурация окружений (dev/stage/prod) хранились в отдельном Git-репозитории, который синхронизировался ArgoCD.
- Сборка только для MR: Пайплайн запускался для каждого Merge Request, что позволяло проводить ревью не только кода, но и результата сборки.