GitOps с ArgoCD + Flux: Сравнение и Best Practices
Детайлен анализ на двата водещи GitOps инструмента. Кога да избереш ArgoCD, кога Flux, как се комбинират и практически best practices от production.
Какво е 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— изтрива ресурси, които вече не са в GitsyncPolicy.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
Тази една команда:
- Инсталира Flux controllers в клъстера
- Създава deploy key и го добавя към GitHub repo
- Commit-ва Flux manifests към repo-то
- Настройва 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: [email protected]
messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
push:
branch: main
update:
path: ./clusters/production
strategy: Setters
Това автоматично:
- Сканира image registry за нови tags
- Ако намери нова версия, която пасва на policy (
>=1.0.0) - Commit-ва новия tag обратно в Git
- 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.
Причините:
- UI-ът е огромно предимство — особено при debug
- По-ниска крива на обучение — нови хора в екипа се ориентират по-бързо
- По-голяма общност — повече Stack Overflow отговори, повече blog posts
- Argo Rollouts дава canary deployments безплатно
- 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
Типичен ред:
- CRDs
- Namespaces
- RBAC
- Secrets
- ConfigMaps
- Databases
- 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 започва да си заслужава много бързо.