DevOps ⭐ Препоръчан 8.09.2026 г. • 15 мин

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

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

ArgoCD и Flux сравнение
GitOps ArgoCD Flux Kubernetes CI/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-а.

Критерий ArgoCD Flux
Философия “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 delivery Argo 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 interval — interval: 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 — при временни грешки
  • Dependencies — dependsOn между 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: fluxcdbot@users.noreply.github.com
      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 започва да си заслужава много бързо.