Flux CD: GitOps-доставка приложений в Kubernetes

GitOps и Flux CD: принципы и архитектура

GitOps — это подход к управлению инфраструктурой и приложениями, при котором Git-репозиторий является единственным источником истины. Все изменения в кластере Kubernetes происходят через коммиты в Git: нужен новый деплой — обновите манифест, нужно откатиться — сделайте revert.

Flux CD — это один из двух главных GitOps-операторов для Kubernetes (второй — ArgoCD). Flux v2 состоит из набора специализированных контроллеров:

  • Source Controller — отслеживает Git-репозитории, Helm-репозитории и S3-бакеты
  • Kustomize Controller — применяет Kustomize-оверлеи и plain YAML-манифесты
  • Helm Controller — управляет Helm-релизами декларативно
  • Notification Controller — отправляет уведомления о событиях (Slack, Teams, webhook)
  • Image Automation Controller — автоматически обновляет теги образов в Git

Преимущества GitOps с Flux:

  • Аудит изменений через Git-историю
  • Простой откат через git revert
  • Pull-based модель — кластер сам забирает изменения, не нужен доступ к API извне
  • Drift detection — автоматическое исправление ручных изменений в кластере

Установка Flux CLI и bootstrap кластера

Для работы с Flux потребуется CLI-утилита flux и доступ к Kubernetes-кластеру.

Установка Flux CLI

Установите CLI:

# Linux
curl -s https://fluxcd.io/install.sh | sudo bash

# Или через Homebrew
brew install fluxcd/tap/flux

# Проверка
flux --version

# Проверка совместимости с кластером
flux check --pre

Команда flux check --pre проверит, что kubectl настроен, кластер доступен и версия Kubernetes совместима с Flux (требуется 1.25+).

Bootstrap с GitHub

Bootstrap — это процесс установки Flux в кластер и подключения к Git-репозиторию. Flux создаст репозиторий (или использует существующий) и установит свои компоненты.

# Экспортируйте GitHub token
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx

# Bootstrap
flux bootstrap github \
  --owner=my-org \
  --repository=k8s-fleet \
  --branch=main \
  --path=clusters/production \
  --personal

Что произойдёт:

  1. Flux создаст репозиторий k8s-fleet (если не существует)
  2. Добавит в него манифесты своих компонентов в clusters/production/flux-system/
  3. Установит компоненты в namespace flux-system
  4. Настроит SSH deploy key для доступа к репозиторию

Проверьте установку:

flux check
kubectl get pods -n flux-system
flux get sources git

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

Правильная структура репозитория — ключ к масштабируемому GitOps. Рекомендуемая структура для мультикластерного окружения:

Рекомендуемая структура каталогов

k8s-fleet/
├── clusters/
│   ├── production/
│   │   ├── flux-system/           # Авто-сгенерировано bootstrap
│   │   ├── infrastructure.yaml    # Ссылка на infrastructure/
│   │   └── apps.yaml              # Ссылка на apps/
│   └── staging/
│       ├── flux-system/
│       ├── infrastructure.yaml
│       └── apps.yaml
├── infrastructure/
│   ├── base/
│   │   ├── cert-manager/
│   │   ├── ingress-nginx/
│   │   └── monitoring/
│   ├── production/
│   │   └── kustomization.yaml
│   └── staging/
│       └── kustomization.yaml
└── apps/
    ├── base/
    │   ├── app-frontend/
    │   └── app-backend/
    ├── production/
    │   └── kustomization.yaml
    └── staging/
        └── kustomization.yaml

Файл clusters/production/infrastructure.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: infrastructure
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./infrastructure/production
  prune: true
  wait: true
  timeout: 5m

Деплой приложений через Kustomize

Kustomize позволяет управлять вариациями манифестов для разных окружений без дублирования кода.

Базовые манифесты приложения

Создайте базовые манифесты в apps/base/app-backend/:

# apps/base/app-backend/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app-backend
  template:
    metadata:
      labels:
        app: app-backend
    spec:
      containers:
        - name: app
          image: registry.example.com/app-backend:1.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: app-backend
spec:
  selector:
    app: app-backend
  ports:
    - port: 80
      targetPort: 8080
# apps/base/app-backend/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml

Оверлеи для production

Создайте production-оверлей с увеличенными ресурсами:

# apps/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
  - ../base/app-backend
patches:
  - target:
      kind: Deployment
      name: app-backend
    patch: |
      - op: replace
        path: /spec/replicas
        value: 4
      - op: replace
        path: /spec/template/spec/containers/0/resources/limits/memory
        value: 1Gi

После коммита и пуша Flux автоматически обнаружит изменения (по умолчанию проверка каждые 10 минут) и применит их к кластеру:

git add -A && git commit -m "deploy: app-backend to production"
git push origin main

# Или принудительно запустить синхронизацию
flux reconcile kustomization apps --with-source

Управление Helm-релизами

Flux позволяет управлять Helm-чартами декларативно через CRD HelmRepository и HelmRelease.

Добавление Helm-репозитория

Пример установки ingress-nginx через Flux:

# infrastructure/base/ingress-nginx/source.yaml
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: ingress-nginx
  namespace: flux-system
spec:
  interval: 24h
  url: https://kubernetes.github.io/ingress-nginx
# infrastructure/base/ingress-nginx/release.yaml
apiVersion: helm.toolkit.fluxcd.io/v2beta2
kind: HelmRelease
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  interval: 30m
  chart:
    spec:
      chart: ingress-nginx
      version: "4.9.*"
      sourceRef:
        kind: HelmRepository
        name: ingress-nginx
        namespace: flux-system
  values:
    controller:
      replicaCount: 2
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
      metrics:
        enabled: true
        serviceMonitor:
          enabled: true

Управление секретами в Git

Секреты нельзя хранить в Git в открытом виде. Flux интегрируется с Mozilla SOPS для шифрования:

# Установите SOPS
sudo apt install sops

# Создайте age-ключ для шифрования
age-keygen -o age.agekey

# Сохраните публичный ключ
export SOPS_AGE_RECIPIENTS=$(cat age.agekey | grep 'public key' | awk '{print $4}')

# Зашифруйте секрет
sops --age=$SOPS_AGE_RECIPIENTS --encrypt --in-place secret.yaml

Настройте Flux для расшифровки:

# Создайте секрет с ключом в кластере
cat age.agekey | kubectl create secret generic sops-age \
  --namespace=flux-system \
  --from-file=age.agekey=/dev/stdin

# Добавьте decryption в Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  decryption:
    provider: sops
    secretRef:
      name: sops-age
  # ... остальная конфигурация

Автоматическое обновление образов

Image Automation Controller позволяет Flux автоматически обнаруживать новые версии Docker-образов и обновлять манифесты в Git.

Настройка Image Automation

Установите дополнительные контроллеры (если не установлены при bootstrap):

flux bootstrap github \
  --components-extra=image-reflector-controller,image-automation-controller \
  --owner=my-org \
  --repository=k8s-fleet \
  --branch=main \
  --path=clusters/production

Создайте политику отслеживания образа:

# ImageRepository — откуда брать теги
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: app-backend
  namespace: flux-system
spec:
  image: registry.example.com/app-backend
  interval: 5m
---
# ImagePolicy — как выбирать тег
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: app-backend
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: app-backend
  policy:
    semver:
      range: ">=1.0.0"
---
# ImageUpdateAutomation — как обновлять Git
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        email: flux@example.com
        name: Flux Bot
      messageTemplate: 'chore(deploy): update {{.AutomationObject.Name}}'
    push:
      branch: main
  update:
    path: ./apps
    strategy: Setters

Добавьте маркер в Deployment:

image: registry.example.com/app-backend:1.0.0 # {"$imagepolicy": "flux-system:app-backend"}

Уведомления и мониторинг

Flux Notification Controller отправляет события о деплоях и ошибках в мессенджеры и webhook-эндпоинты.

Настройка Slack-уведомлений

Создайте Provider и Alert:

# Секрет с Slack webhook
apiVersion: v1
kind: Secret
metadata:
  name: slack-webhook
  namespace: flux-system
stringData:
  address: https://hooks.slack.com/services/T00/B00/xxxxx
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: slack
  namespace: flux-system
spec:
  type: slack
  channel: deployments
  secretRef:
    name: slack-webhook
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: on-call
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: info
  eventSources:
    - kind: Kustomization
      name: '*'
    - kind: HelmRelease
      name: '*'

Мониторинг состояния Flux:

# Статус всех ресурсов
flux get all

# Статус синхронизации
flux get kustomizations
flux get helmreleases -A

# События
flux events --for Kustomization/apps

# Логи контроллеров
flux logs --all-namespaces --level=error

Часто задаваемые вопросы

Flux — это набор контроллеров без UI (есть Weave GitOps как опциональный UI). ArgoCD имеет мощный встроенный веб-интерфейс. Flux лучше подходит для автоматизации и CI/CD-пайплайнов, ArgoCD — для команд, которым важна визуализация. Flux нативно поддерживает Kustomize и Helm как first-class citizens, ArgoCD тоже поддерживает оба, но через плагины. Для мультикластерных окружений обе системы работают хорошо.

В GitOps откат — это коммит: выполните git revert <commit-hash> и запушьте. Flux автоматически обнаружит изменения и применит предыдущую версию манифестов. Для немедленного отката используйте flux reconcile kustomization apps --with-source после пуша. Не рекомендуется откатывать через kubectl rollout undo — Flux вернёт deployment к состоянию Git при следующей синхронизации.

По умолчанию Flux проверяет Git каждые 10 минут. Уменьшите интервал: задайте spec.interval: 1m в GitRepository и Kustomization. Для мгновенной реакции настройте GitHub Webhook — Flux Notification Controller принимает webhooks и запускает синхронизацию немедленно. Также используйте flux reconcile для ручного ускорения.

Да, при правильном использовании. SOPS шифрует только значения (не ключи) в YAML-файлах, что позволяет просматривать diff. Шифрование выполняется через age или PGP ключи. Приватный ключ хранится только в кластере как Kubernetes Secret. Даже при компрометации Git-репозитория злоумышленник получит только зашифрованные данные. Альтернативы SOPS: Sealed Secrets, External Secrets Operator (для интеграции с Vault/AWS SM).

Нужна помощь с настройкой?

Специалисты АйТи Фреш помогут с внедрением и настройкой — 15+ лет опыта, обслуживание от 15 000 ₽/мес

📞 Связаться с нами
#flux cd#gitops kubernetes#flux установка#gitops доставка#flux helm#kubernetes деплой#flux kustomize#continuous delivery kubernetes
Комментарии 0

Оставить комментарий

загрузка...