Модуль 09 — CI/CD ⭐⭐⭐

CI/CD — то, ради чего DevOps существует. Автоматизация пути от commit до продакшена. Цель — деплой в пятницу должен быть скучным.

Терминология

Стек 2026 года

ИнструментКогда
GitHub ActionsСтандарт для GitHub. Без раздумий, если у тебя GitHub.
GitLab CIСтандарт для GitLab. Встроенный, мощный.
Argo CD ⭐⭐Стандарт GitOps. Любой K8s деплой.
FluxАльтернатива Argo CD — Git-native, без UI.
Argo WorkflowsDAG-оркестрация для сложных пайплайнов.
TektonCloud-native CI на K8s. Корпоративные сценарии.
JenkinsLegacy. Учи последним и только если в вакансии.

Стратегия: GitHub Actions + Argo CD = 80% рынка. Освой их глубоко.

GitHub Actions глубоко ⭐

Production-grade workflow

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read
  id-token: write          # для OIDC к AWS
  packages: write          # для GHCR

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true   # отменять старые запуски

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11   # pin SHA
      - uses: astral-sh/ruff-action@d8fd47f4f9234d40ea24fc28a90b5be3f6c2dc7e
      - uses: rhysd/actionlint@v1

  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python: ["3.11", "3.12", "3.13"]
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
          cache: pip
      - run: pip install -r requirements.txt
      - run: pytest --cov --cov-report=xml
      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - name: Trivy filesystem scan
        uses: aquasecurity/trivy-action@v0.20.0
        with:
          scan-type: fs
          severity: HIGH,CRITICAL
          exit-code: 1
      - name: Gitleaks
        uses: gitleaks/gitleaks-action@v2

  build-push:
    needs: [lint, test, security]
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      - name: Sign image (Cosign keyless)
        uses: sigstore/cosign-installer@v3
      - run: cosign sign --yes ghcr.io/${{ github.repository }}:${{ github.sha }}

  deploy-prod:
    needs: [build-push]
    runs-on: ubuntu-latest
    environment: production    # required reviewers в settings
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789:role/gha-deploy
          aws-region: eu-west-1
      - run: aws eks update-kubeconfig --name prod
      - run: kubectl set image deploy/app app=ghcr.io/${{ github.repository }}:${{ github.sha }}

Best practices GitHub Actions

  1. Pin actions to SHA, не tag — supply chain attack защита
  2. Минимальные permissions: contents: read по умолчанию, явно расширяй
  3. Secrets через environments с required reviewers для prod
  4. OIDC к облакам — никаких long-lived access keys
  5. Reusable workflows — DRY между репо
  6. Matrix для параллелизма
  7. concurrency с cancel-in-progress — экономит минуты
  8. Cache агрессивно — pip, npm, docker layers
  9. Job timeoutstimeout-minutes: 30 по умолчанию
  10. Не используй устаревшие actions — следи за actions/setup-python@v5

GitLab CI глубоко

# .gitlab-ci.yml
include:
  - template: Security/SAST.gitlab-ci.yml
  - template: Security/Container-Scanning.gitlab-ci.yml
  - template: Security/Dependency-Scanning.gitlab-ci.yml

stages: [test, build, deploy]

variables:
  IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

test:
  stage: test
  image: python:3.12
  cache:
    paths: [.cache/pip]
  script:
    - pip install -r requirements.txt
    - pytest --junitxml=report.xml --cov --cov-report=xml
  artifacts:
    reports:
      junit: report.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml

build:
  stage: build
  image: docker:24
  services: [docker:24-dind]
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE .
    - docker push $IMAGE

deploy-prod:
  stage: deploy
  image: bitnami/kubectl
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual           # кнопка в UI
  environment:
    name: production
    url: https://app.example.com
  script:
    - kubectl set image deploy/app app=$IMAGE

Фишки GitLab CI

GitOps — Argo CD ⭐⭐

Концепт

Application CRD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-prod
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/me/k8s-manifests
    path: apps/my-app/overlays/prod
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app
  syncPolicy:
    automated:
      prune: true            # удалять то, чего нет в Git
      selfHeal: true         # исправлять manual changes
    syncOptions:
      - CreateNamespace=true
      - PruneLast=true

App of Apps pattern

Один Argo Application указывает на репо с другими Applications. Так управляешь десятками сервисов из одного места.

ApplicationSet

Шаблонизация Applications. Одна ApplicationSet → 50 Applications для 50 кластеров / namespaces.

Argo Rollouts

Расширение Argo для progressive delivery: canary, blue-green, авто-promotion по метрикам Prometheus.

Альтернатива: Flux v2

Более Git-native (CRDs: GitRepository, Kustomization, HelmRelease). Меньше UI (есть Weave GitOps UI отдельно). Native progressive delivery через Flagger.

Стратегии деплоя

СтратегияКогда применять
RecreateМожно simple downtime, не критично
Rolling UpdateK8s default. Постепенная замена, без downtime для stateless
Blue-GreenПолный второй стек. Откат мгновенный. Стоит x2 ресурсов
CanaryМалый % трафика → новая версия. Расширяем при OK. Стандарт production
Shadow / DarkНовая версия получает копию трафика, не отвечает клиенту. Тестинг на реальной нагрузке
Progressive DeliveryCanary + auto-analysis по метрикам/SLO с автоматическим откатом

Инструменты

Feature Flags

Деплой ≠ релиз. Можно деплоить новый код, но фичу включать постепенно.

Релиз-менеджмент

Безопасность пайплайнов

Подробно — модуль 13. Кратко:

Чек-лист

Источники

CI/CD освоено. Теперь — Kubernetes, главный навык DevOps.

Модуль 10 → Kubernetes