Dlaczego Argo CD i GitOps zmieniają sposób wdrażania na Kubernetesie
Od kubectl apply do kontrolowanych wdrożeń
Czy Twoje wdrożenia na Kubernetes wciąż opierają się na serii komend kubectl apply -f i ręcznych poprawkach YAML-i? W małym zespole to jakoś działa, ale przy kilku środowiskach i kilkunastu usługach łatwo o chaos: nikt nie wie, jaki aktualnie jest stan klastra, a „hotfix na produkcji” zrobiony z laptopa admina żyje tylko w pamięci tego admina.
Tradycyjne podejście to:
- zmiana manifestu lokalnie,
- commit do Gita (jeśli ktoś pamięta),
- ręczne odpalenie
kubectlna odpowiednim kontekście, - czasem modyfikacja „na żywca” przez
kubectl editw nagłej sytuacji, - brak pełnego audytu, co kiedy i gdzie poszło.
Taki proces jest słabo powtarzalny, trudny do odtworzenia na nowym klastrze i praktycznie nie daje gwarancji, że stage i production są faktycznie zbieżne. Do tego dochodzi problem „ręcznych poprawek” w klastrze, które nie trafiają do repozytorium – pojawia się dryf konfiguracyjny.
Idea GitOps: jedno źródło prawdy i ciągła synchronizacja
GitOps zakłada, że cały pożądany stan klastra Kubernetes jest opisany deklaratywnie w repozytorium Git. To repozytorium staje się jedynym źródłem prawdy. Klaster nie jest miejscem, gdzie „ręcznie coś się klika”, ale jedynie odzwierciedleniem tego, co zapisane w Git.
Jak to działa w praktyce?
- Opisujesz aplikacje, konfigurację i polityki w plikach YAML/JSON (lub generujesz je np. z Helm/Kustomize).
- Składasz wszystko w repozytorium Git – z czytelną strukturą katalogów.
- System GitOps (tu: Argo CD) obserwuje repozytorium i porównuje je ze stanem klastra.
- Każda zmiana w Git jest traktowana jak żądanie zmiany w klastrze i może wywoływać automatyczne wdrożenie.
- Jeżeli ktoś zmienia coś ręcznie w klastrze, Argo CD wykrywa dryf i może go cofnąć.
Zauważ, jak zmienia się myślenie: zamiast „wchodzę na klaster i zmieniam”, przyjmujesz podejście „robię pull requesta, a kontroler dba o resztę”. Deployment staje się zwykłą zmianą w kodzie, ze wszystkimi korzyściami: review, historia zmian, rewizje, możliwość szybkiego diffu między wersjami.
Push vs pull: klasyczne CI/CD a GitOps
Klasyczne podejście CI/CD do Kubernetesa opiera się najczęściej na push:
- pipeline (np. w Jenkins, GitLab CI, GitHub Actions) po zbudowaniu obrazu łączy się z API serwera Kubernetesa,
- ma uprawnienia do wykonywania
kubectl applylub używa API klienta, - pipeline „pcha” zmianę do klastra.
Model GitOps z Argo CD działa na zasadzie pull:
- Argo CD ma skonfigurowane repozytoria Git i klastry docelowe,
- obserwuje Git (polling lub webhooki),
- w momencie zmiany sam „ściąga” pliki i porównuje ze stanem klastra,
- jeśli polityka na to pozwala, samodzielnie wykonuje synchronizację.
Pipeline CI kończy się zwykle na zbudowaniu i opublikowaniu obrazu kontenera oraz aktualizacji manifestów w Git (np. zmiana tagu obrazu). Wdrożeniem zajmuje się Argo CD w klastrze, który wie najlepiej, w jakim jest stanie, jakie polityki obowiązują i jak ma wyglądać docelowa konfiguracja.
Rola Argo CD jako kontrolera stanu klastra
Argo CD zachowuje się jak kontroler stanu specyficzny dla Twoich aplikacji:
- regularnie pobiera definicje aplikacji z repozytorium Git,
- porównuje „desired state” (to, co w Git) z „actual state” (to, co w klastrze),
- sygnalizuje różnice w UI, API i przez notyfikacje,
- potrafi wykonać synchronizację – ręczną lub automatyczną – aby doprowadzić klaster do stanu zgodnego z Git.
Do tego dochodzą mechanizmy typu auto-prune (usuwanie zasobów, których już nie ma w repozytorium) oraz self-heal (przywracanie „nadpisanej” konfiguracji w klastrze). Efekt: mniej niespodzianek, mniej „tajemniczych różnic” między środowiskami, lepsza obserwowalność zmian.
Czy production i stage naprawdę są takie same?
Jak często zdarzało Ci się usłyszeć: „ale przecież na stage działało…” – a potem okazywało się, że na produkcji ktoś kiedyś zmienił limit zasobów albo zmodyfikował ConfigMapę z poziomu konsoli? GitOps z Argo CD wymusza inną dyscyplinę: klaster jest odzwierciedleniem Git. Jeśli stage i prod mają mieć taki sam setup, różnice muszą być widoczne w repozytorium, a nie w tajemnych komendach „na szybko”.
Pytanie do Ciebie: ile dziś masz miejsc, w których przechowujesz konfiguracje Kubernetesa? Jeden repozytorium? Trzy? A może część w Git, część w Wiki, część w notatniku SRE? To dobry moment, żeby zdecydować, gdzie chcesz mieć jedyne źródło prawdy.
Fundamenty – Kubernetes, manifesty i podejście deklaratywne
Jakie zasoby Kubernetesa kontroluje Argo CD
Argo CD nie jest magicznym narzędziem „do wszystkiego”. Działa w warstwie, w której Kubernetes przetwarza swoje manifesty. Jego praca sprowadza się do: „co jest opisane w pliku, ma się znaleźć w klastrze”. W praktyce Argo CD operuje na:
- podstawowych obiektach: Deployment, StatefulSet, DaemonSet, Job, CronJob,
- sieci: Service, Ingress, Gateway API (jeśli masz CRD),
- konfiguracji: ConfigMap, Secret (z ograniczeniami, np. szyfrowanie/sealed-secrets),
- zasobach klastrowych: Namespace, Role, ClusterRole, RoleBinding, NetworkPolicy,
- CRD i zasobach niestandardowych – wszystko, co rozumie apiserver Kubernetesa.
Argo CD czyta manifesty z Git, generuje „renderowany” zestaw obiektów (np. z Helm lub Kustomize), a następnie porównuje go z tym, co w danej chwili istnieje w klastrze. Różnice są wizualizowane i mogą być automatycznie korygowane.
Deklaratywne vs imperatywne zarządzanie klastrem
Imperatywne podejście: mówisz klastrowi, jakie akcje wykonać:
kubectl create– utwórz zasób,kubectl delete– usuń zasób,kubectl scale– zmień liczbę replik,kubectl edit– zmodyfikuj aktualną definicję.
W takim modelu operacje są sekwencją komend, a odtworzenie stanu wymaga powtórzenia tej sekwencji. Często jest to zapisane w czyjejś głowie lub w kilku skryptach Bash.
Deklaratywne podejście: opisujesz jaki ma być stan końcowy, a nie listę kroków. Manifest Deploymentu mówi: „ma być aplikacja X, z 3 replikami, limitem zasobów takim i takim, konfiguracją Y”. Kubernetes bierze ten opis i stara się doprowadzić klaster do zgodności z nim. Argo CD rozszerza to o aspekt wersjonowania i utrzymania zgodności ze źródłem (Git).
Jak opisać aplikację pod GitOps – minimalny zestaw
Zanim włączysz Argo CD, spójrz na swoje manifesty. Jaki masz cel? Chcesz szybkie POC czy od razu przygotować repozytorium na produkcję? Minimalny zestaw do sensownego GitOps dla typowej aplikacji webowej to zwykle:
- Deployment – definicja pods, kontenerów, zasobów, sond, zmiennych środowisk,
- Service – ekspozycja aplikacji w klastrze,
- Ingress lub odpowiednik (Gateway, VirtualService) – dostęp z zewnątrz,
- ConfigMap/Secret – konfiguracja, hasła, klucze (secrets najlepiej szyfrowane),
- opcjonalnie: HorizontalPodAutoscaler, NetworkPolicy, PodDisruptionBudget.
Do tego dochodzą zasady nazewnictwa i wersjonowania obrazów. W GitOps tag obrazu jest kluczowy – to on determinuje, jaka wersja aplikacji jest wdrożona. Zmiana tagu to sygnał do Argo CD: „wdrażamy nową wersję”.
Przykładowy prosty manifest aplikacji webowej
Przykład minimalnego Deploymentu z myślą o GitOps (bez pełnej produkcyjnej „otoczki”):
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-web
labels:
app: hello-web
spec:
replicas: 2
selector:
matchLabels:
app: hello-web
template:
metadata:
labels:
app: hello-web
spec:
containers:
- name: hello-web
image: registry.example.com/hello-web:1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
livenessProbe:
httpGet:
path: /live
port: 8080
W kontekście GitOps najważniejsze tutaj są:
- image – tag wersji, który zmieniasz w commitach,
- labels – spójność etykiet ułatwia selektory i porządkuje zasoby,
- probes – Argo CD dba o docelowy stan, ale bez poprawnych sond rollout będzie mniej przewidywalny.
Gdzie trzymasz swoje manifesty dziś?
Pytanie kontrolne: czy Twoje aktualne manifesty są w jednym repozytorium Git, czy rozsiane po różnych miejscach? Jeśli masz pliki na dyskach lokalnych, w wiki, w kilku repo, a część generuje osobny zespół – zacznij od inwentaryzacji. Argo CD wymaga, żeby to, co ma się znaleźć w klastrze, dało się odczytać z konkretnych ścieżek w konkretnych repozytoriach. Chaos w źródłach wejściowych przekłada się na chaos w GitOps.

Architektura Argo CD – z czego składa się system i jak działa
Główne komponenty Argo CD
Argo CD składa się z kilku usług działających w klastrze Kubernetes. Znajomość ich roli bardzo pomaga w diagnozowaniu problemów i planowaniu zasobów.
- API server – centralny komponent wystawiający API i UI:
- obsługuje logowanie i uwierzytelnianie (lokalne, SSO, OAuth, OIDC),
- komunikuje się z resztą komponentów,
- przetwarza komendy użytkowników (sync, rollback, diff).
- repo-server – serwer odpowiedzialny za interakcję z repozytoriami:
- klonuje repozytoria Git,
- renderuje aplikacje Helm/Kustomize,
- przygotowuje manifesty do porównania i wdrożenia.
- application-controller – „mózg” synchronizacji:
- monitoruje Application CRD,
- porównuje desired vs actual state,
- inicjuje operacje wdrożeniowe zgodnie z politykami sync.
- UI (argocd-server UI) – panel webowy:
- wizualizacja stanu aplikacji i klastrów,
- interaktywne diffy i logi,
- szybkie operacje (sync, rollback, restart).
Przepływ zdarzeń: od commita w Git do zmian w klastrze
Wyobraź sobie, że zmieniasz tag obrazu w pliku Deploymentu i robisz commit. Co dalej?
- Commit w Git – zmiana trafia na branch, który jest skonfigurowany jako
targetRevisionw Application. - Argo CD wykrywa różnicę – poprzez okresowe sprawdzanie repo lub webhook.
- repo-server pobiera repo – ściąga najnowszy stan, renderuje manifesty (Helm/Kustomize, jeśli używane).
- application-controller porównuje stan – sprawdza, czym różni się desired state od stanu klastra.
- Sync:
- jeśli sync policy = manual – widzisz aplikację jako „OutOfSync” i decydujesz o synchronizacji,
- jeśli sync policy = automated – controller sam podejmie akcję wdrożenia.
- Kubernetes wykonuje rollout – Argo CD wysyła zestaw manifestów do API serwera, resztą zajmują się kontrolery Kubernetesa.
Multi-cluster, multi-tenant – jak Argo CD skaluje się poza jeden klaster
Kiedy pierwszy klaster z Argo CD działa stabilnie, pojawia się kolejne pytanie: czy trzymasz wszystko w jednym klastrze, czy zarządzasz kilkoma środowiskami? Stage w jednym regionie, produkcja w innym, osobne klastry dla klientów? Argo CD dobrze wpisuje się w scenariusze, w których jeden „centralny” Argo CD steruje wieloma klastrami.
Podstawowy wzorzec to klaster zarządzający (management), w którym działa Argo CD, i klastry zarządzane (target), do których Argo CD ma dostęp. Dodając klaster zewnętrzny przez argocd cluster add, tworzysz w nim ServiceAccount i RoleBinding, które dają Argo CD odpowiednie uprawnienia. Od tej chwili w definicji Application możesz wskazywać destination.server jako konkretny klaster.
Jak daleko chcesz pójść z separacją? Dla wielu zespołów wygodny jest schemat:
- jeden Argo CD dla środowisk nieprodukcyjnych (dev, stage, demo),
- oddzielny Argo CD dla produkcji, często z ostrzejszymi zasadami dostępu i audytem,
- czasem osobny Argo CD dla „klastrów klientów”, jeśli masz model SaaS z izolacją na poziomie klastra.
W multi-tenant ważne jest, by przemyśleć RBAC Argo CD i Namespace’y. Czy każdy zespół ma osobne projekty Argo CD (AppProject) i przestrzenie nazw? Czy może dzielicie namespace, ale ograniczacie dostęp po etykietach i nazwach aplikacji? Spróbuj odpowiedzieć sobie: jak chcesz odseparować uprawnienia między zespołami – po klastrze, po projekcie, po namespace?
AppProject – granice i polityki w Argo CD
AppProject to często pomijany, a bardzo ważny byt w Argo CD. Ty decydujesz, czy każdy zespół ma własny projekt, czy w jednym projekcie ląduje kilkanaście aplikacji. AppProject pozwala określić:
- jakie repozytoria Git są dozwolone – np. tylko
git@github.com:org/prod-gitops.git, - jakie klastry i namespace’y mogą być celem – np. tylko klaster
production, namespacepayments-*, - jakie rodzaje zasobów są dozwolone – możesz zablokować tworzenie np.
ClusterRoleprzez zespół aplikacyjny, - politykę synchronizacji i health checki – rozszerzenia, customowe reguły.
Przykładowy szkic AppProject w YAML może wyglądać tak:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: payments
namespace: argocd
spec:
description: "Aplikacje zespolu Payments"
sourceRepos:
- git@github.com:org/payments-gitops.git
destinations:
- server: https://kubernetes.default.svc
namespace: payments-*
clusterResourceWhitelist:
- group: ""
kind: Namespace
namespaceResourceBlacklist:
- group: rbac.authorization.k8s.io
kind: RoleBinding
Widzisz tu kilka mechanizmów kontroli, ale kluczowe pytanie brzmi: które zasoby chcesz zostawić wyłącznie zespołowi platformowemu, a które oddać w ręce zespołów produktowych? AppProject pomaga to technicznie wyegzekwować.
Instalacja Argo CD na Kubernetesie krok po kroku
Wymagania wstępne – klaster i narzędzia
Zanim przejdziesz do instalacji, zatrzymaj się na chwilę i sprawdź: jakim klastrem dysponujesz? Lokalny kind, managed (EKS/GKE/AKS), a może on-premise?
Przyda się:
- klaster Kubernetes w wersji co najmniej 1.22 (lepiej nowszy),
kubectlskonfigurowany do łączenia z klastrem,- opcjonalnie:
argocdCLI – wygodne do zarządzania, - repozytorium Git, do którego masz dostęp do zapisu.
Zastanów się też, czy klaster ma dostęp do Internetu (pobieranie obrazów), czy korzystasz z prywatnego registry i czy potrzebne będą ImagePullSecrets.
Instalacja za pomocą manifestów YAML
Najprostsza ścieżka na start to instalacja z manifestu install.yaml dostarczanego przez projekt Argo CD. To dobry wariant, jeśli chcesz po prostu zobaczyć, jak narzędzie działa i nie zależy Ci jeszcze na finezyjnej konfiguracji Helm.
Podstawowe kroki:
- Utwórz namespace:
kubectl create namespace argocd - Zaaplikuj manifest:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml - Sprawdź zasoby:
kubectl get pods -n argocd
Jeśli potrzebujesz większej kontroli nad wersją, możesz wskazać konkretny tag w URL albo skopiować manifest do własnego repo i traktować go… deklaratywnie, również przez GitOps.
Ekspozycja panelu Argo CD
Domyślnie serwer Argo CD (argocd-server) jest wystawiony jako ClusterIP. Musisz zdecydować: czy chcesz mieć dostęp tylko z wewnątrz klastra, czy także z zewnątrz (VPN/Internet)?
Najprostsze opcje dla środowiska deweloperskiego:
- port-forward:
kubectl port-forward svc/argocd-server -n argocd 8080:443Po tym zabiegu UI jest dostępne pod
https://localhost:8080. - zmiana serwisu na LoadBalancer (na odpowiednich klastrach):
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' - Ingress – jeśli masz kontroler Ingress (np. NGINX, Traefik) i DNS:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: argocd-ingress namespace: argocd spec: rules: - host: argocd.example.com http: paths: - path: / pathType: Prefix backend: service: name: argocd-server port: number: 443
Dla produkcji zwykle wybierzesz Ingress z TLS i ewentualnym SSO. Pytanie dla Ciebie: czy z UI Argo CD mają korzystać tylko inżynierowie, czy także product ownerzy, QA? Od tego zależy, jak „wypuścisz” serwis na zewnątrz.
Pierwsze logowanie i zmiana hasła admina
Domyślny użytkownik to admin, a początkowe hasło w standardowej instalacji przechowywane jest w Secrecie w namespace argocd. Aby je odczytać:
kubectl -n argocd get secret argocd-initial-admin-secret
-o jsonpath="{.data.password}" | base64 -d && echo
Po wejściu na UI zaloguj się jako admin i od razu ustaw nowe hasło albo skonfiguruj SSO (np. OIDC z Keycloakiem, Azure AD, Google). Jaki masz model dostępu dzisiaj? Jeśli większość usług korzysta z centralnego IdP, sensownie jest od razu wpiąć Argo CD w tę samą tożsamość.
Instalacja Argo CD przy użyciu Helm
Jeśli na co dzień używasz Helm, prawdopodobnie wygodniejsze będzie wdrożenie Argo CD jako chartu. Pozwala to na:
- łatwe nadawanie własnych wartości (resources, tolerations, affinity),
- integrację z istniejącym pipeline CI/CD,
- traktowanie samego Argo CD jako „aplikacji GitOpsowej”.
Przykładowy minimalny zestaw komend:
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
kubectl create namespace argocd
helm install argocd argo/argo-cd
--namespace argocd
--values values-argocd.yaml
W pliku values-argocd.yaml możesz od razu zdefiniować typ serwisu, zasoby, konfigurację RBAC, SSO. Zastanów się: co w Twoim środowisku jest „nietypowe” względem domyślnej instalacji? Tam celujesz z własnymi wartościami.

Pierwsza aplikacja w Argo CD – od repozytorium Git do działającej usługi
Przygotowanie repozytorium z manifestami
Zanim utworzysz pierwszą Application, potrzebujesz repozytorium z manifestami. Pytanie pomocnicze: czy chcesz na początek wrzucić do Git pojedynczy, prosty Deployment, czy od razu „prawdziwą” aplikację z kilkoma komponentami?
Bezpieczny scenariusz startowy:
- tworzysz osobne repozytorium, np.
sample-gitops, - w katalogu
apps/hello-web/umieszczasz:deployment.yaml,service.yaml,- opcjonalnie
ingress.yaml.
Struktura może wyglądać tak:
sample-gitops/
apps/
hello-web/
deployment.yaml
service.yaml
ingress.yaml
Na początek nie komplikuj. Najpierw upewnij się, że Argo CD poprawnie zaczytuje pliki i wdraża aplikację, dopiero później dołóż np. Kustomize czy Helm.
Tworzenie Application – UI vs YAML
Możesz podejść do tematu dwojako. Co wolisz na start: klikać w UI, czy od razu pisać deklaratywny YAML i wrzucać go do Git?
Wariant 1: przez UI
- Wejdź do UI Argo CD i wybierz „NEW APP”.
- Ustaw nazwę aplikacji, np.
hello-web. - Wybierz projekt (na początek może być
default). - W sekcji „SOURCE”:
- podaj URL repo,
- branch, np.
main, - path:
apps/hello-web.
- W sekcji „DESTINATION”:
- cluster: bieżący klaster,
- namespace: np.
hello-web(możesz pozwolić Argo CD na jego utworzenie).
- Polityka sync: na początek ustaw manualną (domyślną), by lepiej zobaczyć różnice między Git a klastrem.
Wariant 2: przez YAML
Jeżeli od razu chcesz mieć Application jako kod, możesz stworzyć manifest i zaaplikować go kubectl apply (lub docelowo również przez GitOps). Przykład:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: hello-web
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:org/sample-gitops.git
targetRevision: main
path: apps/hello-web
destination:
server: https://kubernetes.default.svc
namespace: hello-web
syncPolicy:
automated: {}
Zauważ, że w tym przykładzie włączona jest automatyczna synchronizacja. Czy na pierwszą aplikację chcesz mieć pełną automatyzację, czy najpierw wolisz ręcznie kliknąć sync i zobaczyć, co się zadzieje?
Obserwacja pierwszej synchronizacji
Po utworzeniu Application aplikacja pojawi się w UI z jednym z trzech głównych statusów: OutOfSync (brak zasobów w klastrze), Synced lub Unknown (gdy statusu nie da się jednoznacznie określić). Dla świeżej aplikacji zobaczysz najpewniej OutOfSync.
Przy manualnej polityce kliknij „SYNC”, wybierz, czy chcesz od razu usunąć nieużywane zasoby (przy pierwszym wdrożeniu nie ma to znaczenia) i uruchom proces. W logach aplikacji Argo CD i w UI pojawi się informacja o tworzonych obiektach: namespace, deployment, service, ingress.
Kiedy rollout dobiegnie końca i sondy zdrowia aplikacji okażą się pozytywne, status zmieni się na „Healthy, Synced”. W tym momencie masz już pierwszy, zamknięty obieg: zmiana w Git → Argo CD → Kubernetes.
Zmiana wersji aplikacji przez Git
Kolejny krok to przetestowanie tego, co w GitOps jest codzienną operacją: podbicie wersji. Jak dziś zmieniasz wersję aplikacji – ręcznie edytując Deployments, czy masz pipeline, który to robi?
Scenariusz testowy może wyglądać tak:
- W repozytorium Docker budujesz nową wersję aplikacji i wypychasz obraz z tagiem, np.
1.1.0. - W repozytorium GitOps edytujesz manifest Deploymentu:
containers: - name: hello-web image: registry.example.com/hello-web:1.1.0 - Commitujesz i pushujesz zmianę.
- Argo CD wykrywa różnicę (przez webhook albo okresowe odpytywanie) i ustawia aplikację jako OutOfSync.
- manualny sync – po commicie status zmienia się na OutOfSync, ale dopóki ktoś nie kliknie „SYNC” (albo nie wywoła
argocd app sync), nic w klastrze się nie wydarzy, - automatyczny sync – Argo CD sam wywołuje proces synchronizacji po wykryciu różnicy między Git a klastrem.
- wdrażać canary – stopniowo zwiększać udział nowej wersji w ruchu,
- korzystać z blue-green – trzymać starą i nową wersję równolegle i przełączać ruch jednym krokiem,
- dodawać automatyczne reguły cofania (rollback) przy przekroczeniu metryk błędów lub czasu odpowiedzi.
Automatyczna synchronizacja i strategie rolloutów
Gdy obraz z nową wersją trafił do rejestru, a manifest w Git został zaktualizowany, Argo CD może zadziałać dwojako. Jaką masz dziś tolerancję na „samoczynne” wdrożenia – chcesz pełnej automatyzacji, czy wolisz etap „pauzy” na akceptację?
Automatyczną synchronizację możesz wzbogacić o strategie rolloutów. Pytanie kontrolne: czy ważniejsze jest dla Ciebie szybkie wdrożenie, czy bezpieczne, stopniowe puszczenie ruchu?
Jeżeli korzystasz z Argo Rollouts, możesz:
Argo CD sam z siebie nie realizuje strategii canary/blue-green, ale świetnie współpracuje z Argo Rollouts – wystarczy, że w manifestach zamiast klasycznego Deploymentu pojawią się obiekty Rollout. Wtedy Application widzi je jako zasoby i pilnuje ich stanu tak samo jak zwykłych Deploymentów.
Reakcja na błędne wdrożenie – rollback z Git
Wcześniej czy później coś pójdzie nie tak. Jak teraz cofasz wadliwą wersję – ręcznie zmieniając obraz w Deployment, czy odtwarzasz stare YAML-e z historii?
W modelu GitOps masz kilka prostych opcji:
- Cofnięcie commita w Git (
git revert) i push zmian – Argo CD widzi, że docelowy stan to poprzednia wersja i wdraża ją ponownie. - Ręczne ustawienie poprzedniego taga obrazu w manifeście, commit i push – efekt jest taki sam, ale historia jest bardziej czytelna.
- Włączenie w Argo CD opcji auto-rollback przy automatycznej synchronizacji (zależnie od polityki, np. gdy sync zakończy się błędem).
Najzdrowszy na dłuższą metę jest wariant z git revert. Historia repozytorium dokładnie pokazuje, co się stało, kiedy, kto podjął decyzję o cofnięciu. Przy audycie albo analizie incydentu masz pełen obraz. Czy dzisiaj jesteś w stanie odtworzyć taką historię dla ostatnich kilku wdrożeń?
Przyrostowe zmiany i obserwacja diffów
Argo CD bardzo mocno wspiera pracę „małymi krokami”. Zamiast dużych, rzadkich releasów – częste, małe zmiany. Jak często dziś wypuszczasz produkcję?
Każda różnica między Git a klastrem jest pokazana w UI jako diff. W praktyce bardzo pomaga to w:
- wyłapywaniu przypadkowych zmian na klastrze (kubectl apply poza Git),
- analizie, dlaczego dany release poszedł inaczej niż poprzedni,
- prowadzeniu review nie tylko kodu aplikacji, ale też zmian infrastrukturalnych.
Jeżeli teraz chcesz zobaczyć, co dokładnie się zmieniło między wersjami, pytanie brzmi: czy wolisz patrzeć w surowe YAML-e, czy w czytelny diff w przeglądarce? Argo CD daje obie możliwości – przez UI oraz przez komendę CLI argocd app diff.
Wieloklastrowe wdrożenia i promowanie zmian
W wielu organizacjach scenariusz jest powtarzalny: dev → test → stage → prod. Jak w tej chwili „promujesz” aplikację między środowiskami – kopiując manifesty, zmieniając namespace, czy masz osobne skrypty dla każdego klastra?
Argo CD pozwala podpiąć wiele klastrów jako cele wdrożeń. Każdy klaster ma swój server URL (lub alias) i zestaw uprawnień. Na tej bazie możesz zbudować różne strategie promowania:
- osobna Application na każde środowisko (np.
hello-web-dev,hello-web-prod), - jedna Application, ale z różnymi parametrami (przez Kustomize/Helm) zależnie od klastra docelowego,
- oddzielne projekty Argo CD (
dev,prod) z różnymi zasadami RBAC.
Przykładowo możesz mieć dwie aplikacje wskazujące na to samo repo i path, ale inne docelowe klastry:
spec:
destination:
server: https://kubernetes-dev.example.com
namespace: hello-web
spec:
destination:
server: https://kubernetes-prod.example.com
namespace: hello-web
Jak chcesz kontrolować przepływ zmian? Jedna opcja to branch-per-env (np. dev, prod), inna – folder-per-env w jednym branchu. Przy większej skali łatwiej bywa zarządzać środowiskami przez katalogi, bo review jest prostsze, a polityki ochrony gałęzi nie robią się przesadnie skomplikowane.
Organizacja repozytorium GitOps – podejścia, wzorce i praktyczne przykłady
Repozytorium aplikacji vs repozytorium GitOps
Podstawowa decyzja: czy manifesty trzymać razem z kodem aplikacji, czy w osobnym repozytorium? Każde podejście ma swoje plusy.
- Monorepo aplikacja + manifesty:
- łatwo powiązać zmianę kodu z konkretnym deploymentem,
- jeden PR może zawierać zarówno zmianę w kodzie, jak i w konfiguracji zasobów,
- prostsze dla małego zespołu, mniejsza liczba repozytoriów.
- Osobne repo GitOps:
- czytelna separacja odpowiedzialności: zespół aplikacyjny vs zespół platformowy,
- możliwość centralnego zarządzania politykami dla wielu aplikacji,
- łatwiej wprowadzić wspólne wzorce (bazy chartów, kustomization) dla całej organizacji.
Jaka jest dziś struktura Twoich repozytoriów – każdy serwis ma swoje repo, czy masz monorepo? To w dużym stopniu podpowiada, które podejście będzie mniej bolesne na start.
Struktura katalogów – aplikacje, środowiska, wspólne komponenty
Niezależnie od liczby repozytoriów trzeba jakoś zorganizować katalogi. Na początek przydatne są trzy „warstwy”:
- aplikacje – definicje Deploymentów, Service, Ingressów itp.,
- środowiska – różnice między dev/test/prod,
- komponenty wspólne – np. logowanie, monitoring, ingress controller.
Możliwy układ w jednym repo GitOps:
gitops/
apps/
hello-web/
base/
deployment.yaml
service.yaml
overlays/
dev/
kustomization.yaml
values-dev.yaml
prod/
kustomization.yaml
values-prod.yaml
infra/
monitoring/
logging/
Jakiego narzędzia chcesz użyć do templatingu – czystych YAML-i, Kustomize, czy Helma? Jeżeli dziś masz dużo chartów Helm i zespół dobrze je zna, naturalne będzie oparcie się o nie również w GitOps. Przy prostszych aplikacjach Kustomize daje wystarczającą elastyczność i mniej magii.
Wzorce: „app-of-apps” i katalogi środowiskowe
Gdy aplikacji zaczyna przybywać, pojawia się problem: kto i gdzie tworzy Application dla każdej z nich? Jednym z popularnych podejść jest wzorzec app-of-apps.
Polega on na zdefiniowaniu jednej „głównej” Application, która wskazuje na katalog zawierający inne manifesty Application. Przykład:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:org/gitops.git
targetRevision: main
path: environments/prod
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
W katalogu environments/prod umieszczasz kolejne Application, np. hello-web.yaml, payments.yaml, monitoring.yaml. Argo CD po zsynchronizowaniu root-app utworzy te aplikacje i zacznie nimi zarządzać.
Zaletą jest centralne miejsce dla całego środowiska, co ułatwia:
- dodawanie nowych serwisów (PR z nowym plikiem Application),
- usuwanie starych (usunięcie pliku i automatyczny prune),
- kontrolę uprawnień (dostęp do katalogu
environments/prodjest ściśle kontrolowany).
Jaki poziom centralizacji chcesz mieć? Jeśli wolisz, by zespoły produktowe same zarządzały swoimi Application, możesz dać im przypisane katalogi i projekty Argo CD, a „root-app” traktować wyłącznie jako warstwę infrastrukturalną.
Oddzielanie konfiguracji środowiskowej od aplikacyjnej
Konfiguracja środowiskowa często „puchnie” – inne bazy danych, inne endpointy serwisów zewnętrznych, odrębne limity zasobów. Jak dziś radzisz sobie z różnymi konfiguracjami dla dev/test/prod – zmienne środowiskowe, osobne pliki YAML, ręczna edycja?
Dobrym nawykiem jest:
- utrzymywanie „base” z tym, co jest wspólne dla wszystkich środowisk (obraz, porty, liveness/readiness probe, etykiety),
- trzymanie różnic w overlays lub katalogach środowiskowych (zasoby, endpointy, konfiguracja logowania, feature flagi).
Przykładowo, dla Kustomize:
apps/hello-web/base/deployment.yaml
apps/hello-web/overlays/dev/kustomization.yaml
apps/hello-web/overlays/prod/kustomization.yaml
W kustomization.yaml dla prod możesz nałożyć inne limity zasobów i inne wartości configmap/secret. Jeżeli zmieniasz coś „globalnie” (np. wersję obrazu), dotykasz tylko base. Ile dzisiaj plików musisz poprawić, żeby podbić jedną wersję?
RBAC w repozytorium – kto może zmieniać co
GitOps mocno przenosi odpowiedzialność na repozytorium, więc pojawia się pytanie: kto ma prawo zmieniać definicje aplikacji i środowisk? Bez sensownych zasad kończy się na „wszyscy mogą wszystko” i powtarzaniu dawnych błędów.
Typowe reguły, które pomagają utrzymać porządek:
- produkcyjne katalogi chronione – wymagany co najmniej jeden review, brak możliwości force-pusha,
- środowiska niższe bardziej otwarte – zespoły mogą samodzielnie eksperymentować w dev/test,
- liniowe historie – dla katalogów środowiskowych unikaj rebasingu po publikacji, by historia była czytelna.
Bardzo pomaga również podział repozytorium na logiczne części z innymi zasadami: np. katalog infra/ dostępny tylko dla zespołu platformy, a apps/ dla zespołów produktowych. Jak dzisiaj kontrolujesz, kto może „dotknąć” produkcji?
Porządkowanie namingów i etykiet
Przy większej liczbie aplikacji krytyczne staje się konsekwentne nazewnictwo. Trudno zarządzać dziesiątkami Application nazwanych różnie przez różne zespoły. Masz już jakiś standard nazw usług i namespace’ów?
Prosty, ale skuteczny zestaw zasad:
- namespace = domena + środowisko, np.
payments-prod,payments-dev, - nazwa Application = nazwa usługi + środowisko, np.
hello-web-prod, - etykiety:
app.kubernetes.io/nameapp.kubernetes.io/componentapp.kubernetes.io/part-ofenv(dev/test/prod)
Dzięki temu w Argo CD możesz filtrować aplikacje po etykietach i szybko odszukać te powiązane z jednym produktem albo jednym środowiskiem. Jeżeli dziś debugujesz problem w produkcji, jak szybko jesteś w stanie znaleźć komplet zasobów powiązanych z daną funkcją biznesową?
GitOps dla infrastruktury klastra
Argo CD i GitOps nie muszą ograniczać się do aplikacji biznesowych. Wiele zespołów zaczyna nimi zarządzać również komponentami platformy: ingress controllery, Prometheus, Loki, cert-manager, policy engine’y.
Możesz na przykład mieć w repo katalog infra/ z kilkoma Application:
Najczęściej zadawane pytania (FAQ)
Na czym polega GitOps z Argo CD w Kubernetes i czym różni się od klasycznego CI/CD?
GitOps z Argo CD opiera się na modelu pull: klaster sam „ciągnie” konfigurację z repozytorium Git i dopasowuje się do niej. Kluczowe jest jedno źródło prawdy – manifesty w Git, opisujące docelowy stan klastra. Argo CD porównuje ten stan z tym, co faktycznie działa w Kubernetesie, i w razie różnic może automatycznie je korygować.
Klasyczne CI/CD do Kubernetesa zwykle działa w modelu push: pipeline (Jenkins, GitLab CI, GitHub Actions) po zbudowaniu obrazu łączy się z API klastra i „wypycha” zmiany (kubectl apply, helm upgrade itd.). W GitOps pipeline kończy się na aktualizacji manifestów w Git (np. tagu obrazu), a wdrożeniem zajmuje się Argo CD działające wewnątrz klastra. Zastanów się: chcesz, żeby dostęp do klastra miało wiele pipeline’ów, czy jeden wyspecjalizowany kontroler?
Jak zacząć używać Argo CD do automatycznych wdrożeń na Kubernetesie?
Najpierw potrzebujesz uporządkowanych manifestów w Git. Zadaj sobie pytanie: czy Twoje Deploymenty, Service’y, Ingressy, ConfigMapy i Secrety są już w jednym repozytorium, czy rozrzucone po kilku miejscach? Pierwszy krok to przeniesienie ich do Git z czytelną strukturą katalogów (np. podział na środowiska lub aplikacje).
Kiedy repo jest gotowe, instalujesz Argo CD w klastrze (np. przez Helm lub apply z oficjalnych manifestów) i konfigurujesz:
- połączenie z repozytorium Git,
- docelowy klaster / namespace,
- aplikacje Argo CD (definicje, które wskazują ścieżki w repo).
Od tego momentu Argo CD monitoruje Git i – w zależności od ustawień – albo tylko raportuje różnice, albo automatycznie synchronizuje stan. Na start ustaw to raczej w trybie manual sync, żeby zobaczyć, jakie zmiany wykrywa.
Jakie zasoby Kubernetes może kontrolować Argo CD?
Argo CD działa na tej samej warstwie, co kubectl apply. Jeśli coś rozumie API serwera Kubernetes, Argo CD także może tym zarządzać. Typowe przykłady:
- obiekty workload: Deployment, StatefulSet, DaemonSet, Job, CronJob,
- sieć: Service, Ingress, Gateway API (jeśli masz odpowiednie CRD),
- konfiguracja: ConfigMap, Secret (często w połączeniu z mechanizmami szyfrowania, np. sealed-secrets),
- zasoby klastrowe: Namespace, Role, ClusterRole, RoleBinding, NetworkPolicy,
- CRD i dowolne zasoby niestandardowe.
Zadaj sobie pytanie: czy masz dziś coś, co konfigurujesz „ręcznie” w klastrze, a nie jest w Git? To właśnie dobry kandydat, by przenieść go pod kontrolę Argo CD.
Jak Argo CD wykrywa i cofa ręczne zmiany w klastrze (dryf konfiguracyjny)?
Argo CD stale porównuje dwie rzeczy: desired state (to, co jest zapisane w repozytorium Git) oraz actual state (to, co faktycznie działa w klastrze). Jeśli ktoś zrobi zmianę „na żywo” przez kubectl edit albo panel UI, Argo CD zobaczy różnice i oznaczy aplikację jako niesynchronizowaną.
Możesz włączyć tryb self-heal, w którym Argo CD samodzielnie przywraca konfigurację z Git, nadpisując ręczne modyfikacje. Druga opcja to pozostanie przy ręcznym sync i świadome akceptowanie lub odrzucanie takich zmian. Kluczowe pytanie: czy chcesz, żeby klaster sam wracał do stanu z Git, czy wolisz mieć ręczny „bezpiecznik” przed rollbackiem?
Jak przygotować manifesty aplikacji pod GitOps z Argo CD?
Podstawowy zestaw dla typowej aplikacji webowej to:
- Deployment – definicja pods, kontenerów, zasobów, sond, zmiennych środowisk,
- Service – ekspozycja aplikacji w klastrze,
- Ingress / Gateway / VirtualService – dostęp z zewnątrz,
- ConfigMap/Secret – konfiguracja i wrażliwe dane (często szyfrowane),
- opcjonalnie: HPA, NetworkPolicy, PodDisruptionBudget.
Zastanów się: czy Twój manifest jasno określa, jaki stan chcesz mieć (liczba replik, limity zasobów, sondy), czy opisuje tylko „minimalne, żeby działało”? Im bardziej kompletny opis w YAML, tym mniej niespodzianek między środowiskami.
Jak w GitOps z Argo CD kontrolować wersje aplikacji i proces wdrażania?
W GitOps wersja aplikacji jest zwykle powiązana z tagiem obrazu w manifeście, np. image: registry.example.com/hello-web:1.0.0. Pipeline CI buduje obraz, publikuje go w rejestrze, a następnie aktualizuje manifest w repo (zmiana tagu). Commit w Git jest dla Argo CD sygnałem do wdrożenia nowej wersji.
Możesz wdrażać:
- ręcznie – Argo CD pokazuje diff i sam decydujesz, kiedy odpalić synchronizację,
- automatycznie – tryb auto-sync, w którym każda zaakceptowana zmiana w Git jest od razu wdrażana.
Pomyśl, jaki masz proces: czy potrzebujesz review i manualnego „OK” na produkcji, czy akceptujesz pełną automatyzację po merge’u do konkretnego brancha (np. main dla prod, develop dla stage)?
Jak upewnić się, że stage i production są naprawdę takie same przy użyciu Argo CD?
Najprostszy sposób to wspólne repozytorium z manifestami oraz jasny model rozdzielenia środowisk – np. osobne katalogi (environments/stage, environments/prod) albo osobne wartości Helm/Kustomize. Różnice między stage i prod są wtedy jawne w Git: inny rozmiar instancji, inne endpointy, ale ta sama struktura zasobów.
Argo CD dla każdego środowiska ma osobną aplikację wskazującą odpowiednią ścieżkę w repo. Dzięki temu:
- widzisz, czy oba środowiska są zsynchronizowane ze „swoją” konfiguracją,
- łatwo porównać diff manifestów między stage i prod,
- unikasz „skrytych” zmian w jednym z klastrów, które nie trafiły do Git.
Kluczowe Wnioski
- Git staje się jedynym źródłem prawdy o konfiguracji klastra – jeśli czegoś nie ma w repozytorium, w praktyce nie istnieje; ile dziś masz takich „tajnych” zmian robionych tylko z kubectl?
- Argo CD zmienia model z ręcznego
kubectl applyna kontrolowane, powtarzalne wdrożenia, gdzie każda zmiana przechodzi przez commit i pull request, a nie przez „szybką poprawkę” na produkcji. - GitOps opiera się na ciągłej synchronizacji: repozytorium opisuje stan docelowy, a Argo CD cyklicznie porównuje go z tym, co faktycznie działa w klastrze, wykrywając dryf i pozwalając go automatycznie korygować.
- Model pull (Argo CD „ściąga” zmiany z Git) zastępuje klasyczny push z pipeline’ów CI, dzięki czemu to klaster decyduje, kiedy i jak się zaktualizować – pipeline kończy się na zbudowaniu obrazu i aktualizacji manifestów w Git.
- Argo CD działa jak kontroler stanu dla Twoich aplikacji: monitoruje różnice, pokazuje je w UI/API, może samodzielnie synchronizować zasoby (w tym usuwać zbędne i przywracać nadpisane), co zmniejsza liczbę niespodzianek między stage a produkcją.
- Narzędzie obejmuje szeroki zakres zasobów (Deploymenty, Ingressy, ConfigMapy, CRD itd.), więc możesz konsekwentnie zarządzać zarówno aplikacjami, jak i politykami klastrowymi w jednym podejściu deklaratywnym.






