The question that defines GitOps: if someone deletes a Deployment at 3 a.m., does the cluster recover automatically?
If the answer is "no", you have CI with kubectl apply, not GitOps. The difference is who controls the desired state.
Course seal: tested on Kubernetes 1.35 with ArgoCD 2.x.
The model
Git (estado desejado) ──► ArgoCD (comparação) ──► Cluster (estado real)
▲ │
└──── drift detectado ───┘
- Source of truth: Git repository.
- Agent: ArgoCD runs in the cluster and compares continuously.
- Result:
Synced/OutOfSyncandHealthy/Degraded.
Nobody applies with kubectl in production. If you do, ArgoCD reverts — and that is the correct behavior.
Installation
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl -n argocd get pods
Access:
kubectl -n argocd port-forward svc/argocd-server 8080:443
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
In production: Ingress with TLS, SSO (OIDC), and ArgoCD RBAC. Local admin is only for bootstrap.
An Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: portal-homolog
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/portal-gitops.git
targetRevision: main
path: apps/portal/overlays/homolog
destination:
server: https://kubernetes.default.svc
namespace: portal
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
retry:
limit: 3
backoff:
duration: 10s
factor: 2
maxDuration: 3m
Points that matter:
prune: trueremoves what left Git.selfHeal: truecorrects manual changes.retryavoids stayingDegradeddue to a transient image error.
App-of-apps
One repository, many Applications:
gitops/
bootstrap/
root-app.yaml
apps/
portal/
base/
overlays/homolog
overlays/prod
observability/
operators/
The root-app points to apps/ and ArgoCD discovers the rest. Adding a new environment = opening a PR.
Synchronization: manual or automatic
| Mode | When to use |
|---|---|
Manual (syncPolicy empty) |
regulated production, approved window |
| Automated | homolog, staging, internal services |
Automated + selfHeal |
everything that needs to resist manual change |
Automated + prune |
disposable environments and mature GitOps |
prune in production requires care: a path error in the PR can remove resources. Use Prune=false annotation on critical objects and protect the repository with mandatory review.
Drift: the silent enemy
Drift happens when someone:
- edits the Deployment in the dashboard;
- runs
kubectl set image; - applies a stray manifest;
- changes an HPA that changes replicas (replicas managed by HPA should not be in Git).
argocd app diff portal-homolog
argocd app history portal-homolog
HPA + replicas in Git is an eternal fight: ArgoCD wants 2, HPA wants 6. Remove replicas from the managed manifest when there is an HPA.
Secrets in GitOps
Do not commit Secret. Options:
- Sealed Secrets: encrypts and can go to Git.
- External Secrets Operator: fetches from Vault/secret manager.
- SOPS + age: encryption in the repository.
ArgoCD only needs to see the final resource; the secret origin stays outside.
Lab
- Install ArgoCD and access the UI.
- Create a GitOps repository with a simple Deployment.
- Create the Application and synchronize.
- Change the Deployment by hand (
kubectl scale) and seeselfHealreturn to the Git value. - Delete the Deployment and confirm recreation.
- Make a commit with
replicas: 3and follow the automatic sync. - Remove the resource from Git and see
pruneact. - Provoke an error (non-existent image) and observe
Degraded+ retry.
Common errors
| Symptom | Cause |
|---|---|
Eternal OutOfSync |
field managed by another controller (HPA, webhook) |
ComparisonError |
wrong repo/path/branch or credential |
Degraded after sync |
image pull, quota, PVC pending |
| Orphan resource | prune: false |
| Sync overwrites HPA | replicas in manifest |
| Secret in Git | lack of Sealed/External Secrets |
| Sync loop | cluster default differs from manifest (ignoreDifferences) |
ignoreDifferences is palliative: use when the field is really managed by another component, not to hide real drift.
Checklist
- [ ] ArgoCD with SSO and RBAC (local admin only at bootstrap).
- [ ] GitOps repository separate from application code.
- [ ]
selfHealandpruneconscious per environment. - [ ]
replicasoutside manifest where there is HPA. - [ ] Secrets via Sealed/External Secrets.
- [ ]
argocd app diffpart of the PR process. - [ ] Alerts for
DegradedandOutOfSync. - [ ] Backup of the GitOps repository.
Glossary
- Application: CRD that links repo/path to a destination.
- sync: apply the desired state.
- prune: remove resources absent from Git.
- selfHeal: automatically revert drift.
- drift: divergence between Git and cluster.
- app-of-apps: pattern of Applications that manage Applications.
Next
With versioned and reconciled deploy, the detail that the user feels is missing: zero downtime. Probes, rolling update, PDB, and HPA in the next chapter.
Next: Kubernetes Course 23 — Deploy without downtime: probes, rolling update, and HPA
Keep reading
Read also

StorCLI - Complete Cheat Sheet
StorCLI is the official and modern tool for managing Broadcom/LSI RAID controllers. This guide covers essential commands, syntax and use cases.
12 min de leitura
Portal ITSMBusiness Services in Nyverra Portal: Translating IT into Business
The business doesn't feel a server go down — it feels email stop. The Business Services (Service Mapping) module of Nyverra ITSM Portal connects services like Email, ERP or PACS to CMDB assets, revealing the real impact of each failure.
5 min de leitura
SegurançaRPO vs RTO: How to Define Before Buying Backup (and Why Most Companies Get It Wrong)
Most companies buy backup asking the wrong question: "how much does it cost?". The right question is: how much data can I lose (RPO) and how long can I be down (RTO). Discover how to define these numbers per system and avoid purchasing protection based on price, not on real need.
9 min de leitura
Comments
No comments yet
Be the first to share your thoughts on this article.

Leave a comment