DevOps Featured 8.09.2026 г. 15 мин

GitOps с ArgoCD + Flux: Сравнение и Best Practices

Детайлен анализ на двата водещи GitOps инструмента. Кога да избереш ArgoCD, кога Flux, как се комбинират и практически best practices от production.

ArgoCD и Flux сравнение
GitOpsArgoCDFluxKubernetesCI/CD

Какво е GitOps и защо всички говорят за него

GitOps е операционен модел, при който Git е единственият източник на истина за желаното състояние на инфраструктурата. Вместо да прилагаш промени с kubectl apply или през CI pipeline, ти commit-ваш в Git и агент в клъстера автоматично синхронизира реалното състояние с това в repo-то.

Традиционният CI/CD pipeline изглежда така:

Developer → Git push → CI build → CI push to cluster → kubectl apply

Проблемите:

  • CI има admin достъп до production — компрометиран CI = компрометиран клъстер
  • Няма drift detection — ако някой ръчно промени нещо, CI не знае
  • Трудно rollback — трябва да пуснеш pipeline-а отново с обратен commit
  • Няма audit trail — кой какво е приложил и кога

GitOps обръща модела:

Developer → Git push → Agent в cluster pull-ва от Git → Прилага

Предимства:

  • Pull, не push — клъстерът сам издърпва промените, CI няма нужда от достъп
  • Continuous reconciliation — агентът проверява на всеки N секунди дали реалното състояние съвпада с Git
  • Drift detection — ако някой промени нещо ръчно, агентът го връща към Git състоянието
  • Rollback = revert commit — Git историята е deployment историята
  • Пълен audit trail — всеки commit, кой, кога, защо

ArgoCD vs Flux — високо ниво

И двата инструмента са CNCF graduated проекти (най-високото ниво на зрялост в CNCF). И двата правят GitOps правилно. Разликите са в философията и UX-а.

КритерийArgoCDFlux
Философия“GitOps с UI”“GitOps като набор от controllers”
АрхитектураЕдин голям контролерМножество малки контролери (source, kustomize, helm, notification)
UIБогат web UI (по подразбиране)CLI-центричен, UI-то е опционално
Multi-tenancyВградено (Projects)Чрез Kubernetes RBAC и namespace isolation
Крива на обучениеПо-ниска (UI помага)По-висока (много CRDs)
Git repo структураЕдин repo може да управлява много клъстериЕдин repo на клъстер (обикновено)
Helm поддръжкаНативнаNative Helm Controller
Kustomize поддръжкаНативнаNative Kustomize Controller
Secret managementВъншно (Sealed Secrets, SOPS, Vault)Вградено с SOPS
NotificationsВградениОтделен Notification Controller
Image automationНе (нужен Image Updater)Вградено (Image Reflector + Automation)
Progressive deliveryArgo Rollouts (отделен проект)Flagger (отделен проект)
Ресурси~500MB RAM за пълен setup~200MB RAM

Практическо правило:

  • Искаш бърз onboarding с UI → ArgoCD
  • Искаш минималистичен, composable setup → Flux
  • Имаш много клъстери и много екипи → и двата работят, но ArgoCD UI помага
  • Искаш всичко в Git, zero UI → Flux

ArgoCD — дълбоко потапяне

Архитектура

ArgoCD се състои от няколко компонента:

  • argocd-server — API сървър + web UI
  • argocd-repo-server — клонира Git repo-та и рендерира манифести
  • argocd-application-controller — Kubernetes controller, който синхронизира
  • argocd-redis — кеш за repo-та (не е задължителен, но се препоръчва)
  • argocd-dex — SSO/OIDC (опционално)

Инсталация

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Вземи admin паролата
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# Port-forward за UI
kubectl port-forward -n argocd svc/argocd-server 8080:443

Отвори https://localhost:8080 и влез с admin / паролата от горната команда.

Application CRD

Основният ресурс в ArgoCD е Application:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/my-app-config.git
    targetRevision: main
    path: apps/my-app/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Ключови полета:

  • source.repoURL — Git repo с манифестите
  • source.path — път до манифестите в repo-то (може Kustomize overlay, Helm chart, raw YAML)
  • destination.server — кой клъстер (може external)
  • syncPolicy.automated.prune — изтрива ресурси, които вече не са в Git
  • syncPolicy.automated.selfHeal — връща ръчни промени обратно към Git състоянието

App of Apps pattern

За управление на много applications, ArgoCD използва App of Apps:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/gitops.git
    path: apps
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

В apps/ папката имаш YAML файлове, всеки от които дефинира друг Application. Така един root Application управлява всички останали.

Projects — multi-tenancy

AppProject дефинира границите на екипите:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-frontend
  namespace: argocd
spec:
  sourceRepos:
    - 'https://github.com/myorg/frontend-*'
  destinations:
    - namespace: 'frontend-*'
      server: https://kubernetes.default.svc
  clusterResourceWhitelist:
    - group: ''
      kind: Namespace
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota

Frontend екипът може да deploy-ва само в frontend-* namespace-и, само от repo-та с име frontend-*. Не могат да пипат production базата.

ArgoCD предимства

  • Web UI — виждаш статус на всички applications в реално време
  • Diff view — показва какво ще се промени преди sync
  • Rollback с един клик — от UI или CLI
  • SSO интеграция — OIDC, SAML, LDAP
  • Multi-cluster от един control plane — един ArgoCD управлява N клъстера
  • Sync waves и hooks — контрол на реда на прилагане

Flux — дълбоко потапяне

Архитектура

Flux v2 е набор от независими controllers:

  • source-controller — дърпа от Git, Helm repos, OCI registries, S3
  • kustomize-controller — прилага Kustomize overlays
  • helm-controller — прилага Helm charts
  • notification-controller — изпраща events към Slack, Teams, webhooks
  • image-reflector-controller — сканира image registries за нови tags
  • image-automation-controller — commit-ва нови image tags в Git

Всеки controller може да се инсталира самостоятелно. Това е философията на Unix — малки инструменти, които правят едно нещо добре.

Инсталация

# CLI
brew install fluxcd/tap/flux

# Bootstrap — свързва клъстера с Git repo и инсталира всичко
flux bootstrap github \
  --owner=myorg \
  --repository=gitops \
  --branch=main \
  --path=clusters/production \
  --personal

Тази една команда:

  1. Инсталира Flux controllers в клъстера
  2. Създава deploy key и го добавя към GitHub repo
  3. Commit-ва Flux manifests към repo-то
  4. Настройва Flux да sync-ва от clusters/production

GitRepository + Kustomization

Двата основни ресурса:

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/myorg/my-app-config.git
  ref:
    branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 10m
  targetNamespace: production
  sourceRef:
    kind: GitRepository
    name: my-app
  path: ./overlays/production
  prune: true
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: my-app
      namespace: production

Разлики с ArgoCD:

  • Два ресурса вместо един — единият дефинира source-а, другият какво да се направи с него
  • Explicit intervalinterval: 1m за GitRepository означава “провери Git на всяка минута”
  • healthChecks — изрично указваш кои ресурси да се следят за готовност
  • Може да реферираш всеки GitRepository от всяка Kustomization — по-гъвкаво

HelmRelease

Flux има и специален ресурс за Helm:

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: nginx-ingress
  namespace: flux-system
spec:
  interval: 5m
  chart:
    spec:
      chart: ingress-nginx
      version: '4.10.*'
      sourceRef:
        kind: HelmRepository
        name: ingress-nginx
      interval: 1m
  values:
    controller:
      replicaCount: 3
      metrics:
        enabled: true
  install:
    crds: CreateReplace
  upgrade:
    crds: CreateReplace

Това е по-мощен от ArgoCD-то Application с Helm, защото:

  • Drift detection на Helm values — ако някой ръчно промени нещо, Flux го връща
  • Automatic retries — при временни грешки
  • DependenciesdependsOn между HelmRelease-и

Image Automation

Flux има вградена image automation, която ArgoCD няма:

apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  image: ghcr.io/myorg/my-app
  interval: 5m
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: my-app
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: my-app
  policy:
    semver:
      range: '>=1.0.0'
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 30m
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        name: fluxcdbot
        email: [email protected]
      messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
    push:
      branch: main
  update:
    path: ./clusters/production
    strategy: Setters

Това автоматично:

  1. Сканира image registry за нови tags
  2. Ако намери нова версия, която пасва на policy (>=1.0.0)
  3. Commit-ва новия tag обратно в Git
  4. Flux sync-ва промяната в клъстера

Резултат: push нов Docker image → автоматично deployed. Без CI pipeline за deploy. Git историята показва всяка промяна.

Flux предимства

  • Минималистичен — по-малко ресурси, по-малко компоненти
  • Composable — използваш само това, което ти трябва
  • Вградена image automation — уникална функционалност
  • Вградена SOPS интеграция — secrets в Git, криптирани
  • Event-driven — webhook-ове от Git директно към source-controller
  • Много по-гъвкав — CRD-тата са по-мощни от ArgoCD Application

Flux недостатъци

  • Няма UI по подразбиране — трябва да инсталираш weave-gitops ако искаш визуализация
  • Повече CRDs за научаване — GitRepository, Kustomization, HelmRelease, HelmRepository, ImagePolicy, ImageRepository, ImageUpdateAutomation…
  • Debug-ът е по-труден — multi-controller архитектура означава повече места за проверка

Кога кой — практически насоки

Избери ArgoCD, ако:

  • Екипът е нов в GitOps — UI-ът помага за onboarding
  • Много клъстери — централен control plane за всички
  • Много екипи — Projects дават ясна граница
  • Искаш да виждаш diff преди sync — UI-ът го прави отлично
  • Compliance изисква audit — ArgoCD има добър audit log
  • Използваш Argo Workflows/Events — интегрира се добре
  • Искаш Progressive Delivery с Argo Rollouts

Избери Flux, ако:

  • Искаш минималистичен setup — по-малко компоненти, по-малко ресурси
  • Фен си на Unix философията — малки инструменти, които правят едно нещо добре
  • Искаш image automation — Flux го има вградено, ArgoCD не
  • SOPS е част от workflow-а — вградена интеграция
  • Edge или IoT deployment — Flux е по-лек
  • GitOps за всичко — не само Kubernetes, но и Terraform (чрез tf-controller)

Моят избор

За повечето production среди през 2026: ArgoCD.

Причините:

  1. UI-ът е огромно предимство — особено при debug
  2. По-ниска крива на обучение — нови хора в екипа се ориентират по-бързо
  3. По-голяма общност — повече Stack Overflow отговори, повече blog posts
  4. Argo Rollouts дава canary deployments безплатно
  5. Multi-cluster от кутията — не ти трябва да мислиш как да го направиш

Flux е по-добър технически, но ArgoCD е по-добър за хората. А deployment-ът е human process.

Как да ги комбинираш

Възможно е — и понякога има смисъл. Например:

Flux за infrastructure, ArgoCD за applications:

  • Flux управлява cluster-wide resources: CNI, ingress controller, cert-manager, monitoring stack
  • ArgoCD управлява application deployments: microservices, configs, secrets

Защо това работи:

  • Flux е по-добър в managing cluster-scoped resources и Helm charts
  • ArgoCD UI-ът е по-добър за application екипи, които искат да виждат своето
  • Разделяне на отговорности: platform team ползва Flux, app teams ползват ArgoCD

Пример:

# Flux HelmRelease за cert-manager
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: cert-manager
  namespace: flux-system
spec:
  chart:
    spec:
      chart: cert-manager
      sourceRef:
        kind: HelmRepository
        name: jetstack
# ArgoCD Application за app
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/myorg/my-app.git
    path: k8s/overlays/production
  destination:
    namespace: production

Но: поддръжката на два инструмента има цена. Два различни workflow-а, два различни debugging process-а, два различни backup стратегии за state-а им. По-добре избери един и го направи добре.

Best Practices (общи за двата)

1. Отделен config repo от app repo

Не mix-вай application code с Kubernetes manifests:

my-app/              (application code)
├── src/
├── Dockerfile
└── README.md

my-app-config/       (Kubernetes manifests) ← отделен repo
├── base/
└── overlays/
    ├── staging/
    └── production/

Защо: application commits не трябва да trigger-ват deployment. Deploy-ът е отделно решение.

2. Един repo за всички environments

gitops-repo/
├── apps/
│   ├── my-app/
│   │   ├── base/
│   │   └── overlays/
│   │       ├── staging/
│   │       └── production/
│   └── other-app/
└── infrastructure/
    ├── cert-manager/
    ├── ingress-nginx/
    └── monitoring/

Предимство: pull request показва diff между staging и production.

3. Използвай Kustomize overlays, не Helm values per environment

Kustomize overlays са по-четими за environment-specific конфигурация:

# overlays/production/kustomization.yaml
resources:
  - ../../base
patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 10

Вместо да поддържаш values-staging.yaml и values-production.yaml с 90% припокриване.

4. Secrets — никога plain в Git

Опции:

  • Sealed Secrets — криптиране с публичен ключ, commit-ваш криптирания secret
  • SOPS + age — криптиране с age keys, Flux има вградена поддръжка
  • External Secrets Operator — secrets живеят във Vault/AWS Secrets Manager, операторът ги дърпа
  • Secrets Store CSI Driver — secrets се mount-ват директно от cloud provider

Никога не commit-вай:

  • Base64 encoded secrets (това не е криптиране)
  • .env файлове с реални credentials
  • Kubernetes Secrets в plain YAML

5. Sync waves за controlled rollout

И двата инструмента поддържат реда на прилагане:

ArgoCD:

metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "1"  # по-ниско = по-рано

Flux — чрез dependsOn:

spec:
  dependsOn:
    - name: cert-manager

Типичен ред:

  1. CRDs
  2. Namespaces
  3. RBAC
  4. Secrets
  5. ConfigMaps
  6. Databases
  7. Applications

6. Drift detection — винаги включен

ArgoCD:

spec:
  syncPolicy:
    automated:
      selfHeal: true  # ← задължително

Flux:

spec:
  prune: true       # ← изтрива извън Git
  # drift detection е винаги активен

Без drift detection, някой може да промени нещо ръчно и Git ще излъже.

7. Webhook-ове за по-бърз sync

Default-но ArgoCD/Flux проверяват Git на всеки 3-5 минути. С webhook става секунди:

ArgoCD: configure webhook в GitHub/GitLab → ArgoCD endpoint

Flux:

flux create receiver github \
  --name=github-receiver \
  --secret-ref=webhook-token \
  --resource=GitRepository/flux-system \
  --event=ping \
  --event=push

8. Notifications — знай кога нещо се обърка

ArgoCD:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  trigger.on-sync-failed: |
    - when: app.status.sync.status == 'OutOfSync'
      send: [slack]

Flux — Notification Controller:

apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: slack-alerts
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: error
  eventSources:
    - kind: Kustomization
      name: '*'

9. RBAC — кой какво може

ArgoCD — Projects:

spec:
  destinations:
    - namespace: 'team-a-*'
      server: '*'
  sourceRepos:
    - 'https://github.com/myorg/team-a-*'

Flux — Kubernetes RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: team-a-flux
  namespace: flux-system
subjects:
  - kind: ServiceAccount
    name: team-a
roleRef:
  kind: Role
  name: flux-applier

10. Backup стратегия за state-а

ArgoCD съхранява състояние в Kubernetes Secrets. Използвай argocd-util за backup:

argocd admin export > argocd-backup.yaml

Flux е stateless — всичко е в Git. Ако клъстерът се счупи, bootstrap-ваш отново.

Това е значително предимство на Flux — няма state за управление.

Практически миграционен път

Ако използваш kubectl apply или Helm ръчно сега:

Стъпка 1: Инсталирай ArgoCD/Flux в отделен namespace (не пипай production)

Стъпка 2: Премести един некритичен application в GitOps

  • Изнеси manifests в Git
  • Създай Application/HelmRelease
  • Изключи стария deployment pipeline за този app

Стъпка 3: Наблюдавай 1-2 седмици

  • Проблеми с drift detection?
  • Има ли случаи, които GitOps не покрива?
  • Екипът разбира ли workflow-а?

Стъпка 4: Мигрирай останалите, по един наведнъж

Не прави “big bang migration” — ще съжаляваш.

Чести грешки

1. Смесване на config с app code

Ако deploy-ът е в същия repo като кода, всеки feature commit trigger-ва deployment. Лошо.

2. Plain secrets в Git

Base64 не е криптиране. Secrets в Git трябва да са криптирани (SOPS, Sealed Secrets) или външно управлявани (External Secrets Operator).

3. Пренебрегване на drift detection

Ако не си включил selfHeal / prune, GitOps е просто “по-сложен CI”. Целта е да гарантираш състоянието.

4. Един Application за всичко

Един Application, който управлява целия клъстер, е anti-pattern:

  • Един неуспешен sync блокира всичко
  • Трудно debug
  • Няма isolation между екипи

Прави един Application на логическа единица (microservice, infrastructure component).

5. Без RBAC

Всички с достъп до ArgoCD виждат всичко. В production среди това е проблем.

6. Игнориране на notifications

Ако deploy-ът тихо се проваля, разбираш когато потребител се оплаче. Настрой alerts.

7. Override-ване на manifests извън Git

Ако някой прави kubectl edit в production, GitOps ще го revert-не. Това е целта, но екипът трябва да го разбира.

Verification checklist

  • Config repo е отделен от app repo
  • Secrets са криптирани (SOPS/Sealed) или външни (ESO/CSI)
  • Drift detection е включен (selfHeal/prune)
  • RBAC е конфигуриран (Projects за ArgoCD, RoleBindings за Flux)
  • Notifications са настроени (Slack/Teams на sync failures)
  • Webhook-ове са конфигурирани за бърз sync
  • Backup стратегия за state-а (ArgoCD) или bootstrap процедура (Flux)
  • Екипът знае: промени се правят само през Git PR
  • Emergency rollback процедура е документирана
  • Monitoring на ArgoCD/Flux самите те (защото и те могат да се счупят)

Заключение

ArgoCD и Flux са и двата отлични. Разликата не е в качество, а във философия:

  • ArgoCD = “batteries included” — UI, multi-tenancy, всичко на едно място
  • Flux = “composable” — малки controllers, всеки прави едно нещо

Изборът зависи от екипа, не от технологията. Ако екипът обича UI и бърз onboarding → ArgoCD. Ако екипът обича CLI и Unix философия → Flux.

Това, което не трябва да правиш, е да използваш и двата “защото са добри”. Поддръжката на два GitOps инструмента е двойна работа за нулева полза.

Започни с един. Направи го добре. Разшири, когато имаш нужда.

GitOps не е сребърен куршум — той решава специфични проблеми (drift, audit, deploy без CI admin достъп). Ако нямаш тези проблеми, kubectl apply си работи. Но ако имаш над 5 microservices в production, GitOps започва да си заслужава много бързо.