GitOps: принципы

GitOps — подход к управлению инфраструктурой и деплоям, при котором Git-репозиторий является единственным источником истины: любое изменение в инфраструктуре проходит через pull request.

Зачем нужно

В классическом DevOps разработчик вручную запускает деплой или кликает кнопки в консоли. GitOps делает Git источником истины: состояние продакшна описано в репозитории, и любое изменение — через PR с review и CI-проверками. Это даёт полный аудит-лог изменений и легкий rollback через git revert.

Где используется

  • Kubernetes: манифесты хранятся в Git, ArgoCD/Flux синхронизирует кластер с репозиторием
  • Terraform: конфигурация инфраструктуры в Git, terraform apply через CI/CD
  • GitHub Actions: деплой только через слияние в main, не через ручной запуск

Основной контент

4 принципа GitOps (по Weaveworks)

  1. Декларативность — желаемое состояние системы описано декларативно (YAML, HCL)
  2. Версионность — всё состояние хранится в Git (immutable, с историей)
  3. Автоматическое согласование — агент (ArgoCD, Flux) автоматически приводит реальное состояние к желаемому
  4. Непрерывная верификация — система постоянно проверяет соответствие реального состояния описанному

Push vs Pull модель

PUSH модель (классический CI/CD):
CI/CD → деплоит → Кластер/Сервер

PULL модель (GitOps):
Git → (агент в кластере тянет изменения) → Кластер

ArgoCD: GitOps для Kubernetes

# argocd-app.yml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/k8s-configs
    targetRevision: HEAD
    path: apps/my-app
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true       # удалять ресурсы, которых нет в Git
      selfHeal: true    # восстанавливать при ручных изменениях в кластере

GitOps-деплой через GitHub Actions

# При деплое обновляем манифест в отдельном repo с конфигами
name: Update K8s manifest

on:
  push:
    branches: [main]

jobs:
  update-manifest:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout infra repo
        uses: actions/checkout@v4
        with:
          repository: myorg/k8s-configs
          token: ${{ secrets.INFRA_TOKEN }}

      - name: Update image tag
        run: |
          sed -i "s|myapp:.*|myapp:${{ github.sha }}|g" apps/my-app/deployment.yaml

      - name: Commit and push
        run: |
          git config user.email "ci@example.com"
          git config user.name "CI Bot"
          git add .
          git commit -m "chore: update my-app to ${{ github.sha }}"
          git push

ArgoCD обнаруживает изменение в конфиг-репозитории и автоматически применяет его к кластеру.

Структура GitOps-репозитория

k8s-configs/
├── apps/
│   ├── my-app/
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   └── ingress.yaml
│   └── postgres/
│       └── statefulset.yaml
└── infrastructure/
    ├── namespaces.yaml
    └── rbac.yaml

Частые ошибки

  • Хранить секреты в Git-репозитории: использовать sealed-secrets, External Secrets Operator или Vault
  • Смешивать app-код и инфраструктурные конфиги в одном репо — лучше разделять
  • Вносить изменения напрямую в кластер (kubectl apply вручную) — нарушает single source of truth

Связанные темы

Ресурсы