Skip to content

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

  1. Create a Git repository structure for Kubernetes manifests.
  2. Organize manifests into base/ and overlays/ using Kustomize.
  3. Deploy an application stack (Deployment + Service + ConfigMap) declaratively.
  4. Simulate drift by manually editing a running Deployment.
  5. Write a reconciliation script that detects and corrects drift back to the Git state.
  6. Run the reconciler and verify it restores the original state.
  7. 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 diff shows what would change if you re-applied manifests.
  • The --prune flag removes resources that are no longer in your manifests.
  • Use labels to scope what --prune affects - 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.