GitOps: The Modern Way to Manage Kubernetes Deployments
GitOps is an operational framework that uses Git as the single source of truth for declarative infrastructure and applications. Changes are made through pull requests, and an automated agent ensures the cluster matches the desired state in Git.
Why GitOps?
Traditional deployment: developer pushes code → CI builds image → someone runs kubectl apply or a script pushes to the cluster.
GitOps deployment: developer pushes code → CI builds image and updates the manifest repo → GitOps agent detects drift and reconciles.
Benefits:
- Auditability — every change is a Git commit with author and timestamp
- Rollbacks — revert a deployment by reverting a commit
- Consistency — the cluster always matches what's in Git
- Security — no direct
kubectlaccess needed; the agent pulls changes
ArgoCD: The GitOps Controller
ArgoCD is the most popular GitOps tool for Kubernetes.
Installing ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Get the initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# Port-forward the UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
Defining an Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/my-app/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Key settings:
automated.prune— delete resources removed from Gitautomated.selfHeal— revert manual cluster changestargetRevision— the Git branch or tag to track
Repository Structure
A typical GitOps repo:
k8s-manifests/
├── apps/
│ ├── my-app/
│ │ ├── base/
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── staging/
│ │ │ └── kustomization.yaml
│ │ └── production/
│ │ └── kustomization.yaml
│ └── another-app/
└── infrastructure/
├── nginx-ingress/
├── cert-manager/
└── monitoring/
The GitOps Workflow
- Developer pushes code to the app repo
- CI pipeline builds a Docker image and pushes it to a registry
- CI pipeline (or a bot) updates the image tag in the manifest repo
- ArgoCD detects the change and syncs the cluster
- If something breaks, revert the commit in the manifest repo
Image Updater
Automate image tag updates with ArgoCD Image Updater:
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: myapp=myregistry/my-app
argocd-image-updater.argoproj.io/myapp.update-strategy: semver
argocd-image-updater.argoproj.io/myapp.allow-tags: "regexp:^v[0-9]+\\.[0-9]+\\.[0-9]+$"
Best Practices
- Separate app code and manifests into different repositories
- Use Kustomize or Helm for environment-specific configuration
- Protect the main branch — require PR reviews for manifest changes
- Use sealed secrets or external secrets operators — never commit plain secrets
- Set up notifications — ArgoCD can notify Slack on sync success/failure
- Monitor sync status — create alerts for applications stuck in "OutOfSync"
Alternatives to ArgoCD
- Flux — another CNCF GitOps tool with a different architecture
- Jenkins X — combines CI/CD with GitOps
- Rancher Fleet — GitOps at scale for multi-cluster
GitOps takes the guesswork out of Kubernetes deployments. When your cluster state is defined in Git, you gain confidence, traceability, and the ability to recover quickly from any failure.
Tagged with
Enjoyed this article?
Get more DevOps insights delivered to your inbox.
Get new posts by email
Subscribe to get an email when a new blog post is published. Skip anytime.
No spam, unsubscribe anytime.
Discussion
0 comments
Sign in to join the conversation.
Be the first to comment
Start a conversation about this post
