Room 51
GITOPS & RECONCILIATION
The Self-Healing Infrastructure
- GitOps treats Git as the single source of truth for infrastructure.
- A reconciliation loop continuously ensures the cluster matches the desired state in Git.
- Master the declarative approach to Kubernetes management.
📜 Mission Briefing
- Create a Git repository structure for Kubernetes manifests.
- Organize manifests into
base/andoverlays/using Kustomize. - Deploy an application stack (Deployment + Service + ConfigMap) declaratively.
- Simulate drift by manually editing a running Deployment.
- Write a reconciliation script that detects and corrects drift back to the Git state.
- Run the reconciler and verify it restores the original state.
- The password appears in the reconciler output:
gitops51.
Key Commands
| Command | Purpose |
|---|---|
kubectl diff -f manifest.yaml |
Show drift between live and desired state |
kubectl apply -f . --prune -l app=gitops |
Apply with pruning |
kustomize build overlays/dev |
Build Kustomize overlay |
kubectl apply -k overlays/dev |
Apply Kustomize overlay |
kubectl get deploy -o yaml |
Get live state |
diff <(kubectl get deploy app -o yaml) deploy.yaml |
Compare live vs desired |
GitOps Repository Structure
gitops-repo/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ └── configmap.yaml
└── overlays/
├── dev/
│ ├── kustomization.yaml
│ └── replica-patch.yaml
└── prod/
├── kustomization.yaml
└── resource-patch.yaml
Kustomize Base
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- configmap.yaml
commonLabels:
app: gitops-demo
managed-by: gitops
# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitops-app
spec:
replicas: 2
selector:
matchLabels:
app: gitops-demo
template:
metadata:
labels:
app: gitops-demo
spec:
containers:
- name: app
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
Drift Detection Script
#!/bin/bash
# reconcile.sh - Detect and correct drift
MANIFEST_DIR="./base"
NAMESPACE="default"
echo "🔍 Checking for drift..."
# Compare live state with desired state
DIFF_OUTPUT=$(kubectl diff -f "$MANIFEST_DIR" 2>&1)
if [[ -z "$DIFF_OUTPUT" ]]; then
echo "✅ No drift detected - cluster matches desired state."
else
echo "⚠️ Drift detected!"
echo "$DIFF_OUTPUT"
echo ""
echo "🔧 Reconciling - applying desired state..."
kubectl apply -f "$MANIFEST_DIR" --prune -l managed-by=gitops
echo "✅ Reconciliation complete. Password: gitops51"
fi
Simulating Drift
# Deploy the base manifests
kubectl apply -k base/
# Wait for deployment to be ready
kubectl rollout status deploy/gitops-app
# Now simulate drift - manually change replicas
kubectl scale deploy/gitops-app --replicas=5
# Verify drift
kubectl diff -f base/
# Run the reconciler to fix it
bash reconcile.sh
💡 Hints
kubectl diffshows what would change if you re-applied manifests.- The
--pruneflag removes resources that are no longer in your manifests. - Use labels to scope what
--pruneaffects - never prune without a selector. - Kustomize overlays let you customize per-environment without duplicating YAML.
🔑 Password
Run the reconciliation script after creating drift → the output reveals the password.