GitOps for Kubernetes

GitOps for Kubernetes: Implementation Guide (2025)

Complete guide to GitOps for Kubernetes: learn core principles, compare ArgoCD vs Flux, implement GitOps workflows with step-by-step guides, handle secrets securely with Sealed Secrets, structure Git repositories, and integrate progressive delivery with Flagger for automated canary deployments.

Introduction to GitOps: Git as Single Source of Truth

GitOps is a modern operational framework for Kubernetes where Git repositories serve as the single source of truth for declarative infrastructure and application configuration, with automated agents continuously synchronizing the actual cluster state to match the desired state defined in Git. Instead of manually running kubectl apply commands or using CI/CD pipelines that push changes directly to clusters, GitOps inverts the model: you commit YAML manifests to Git, and specialized operators running in your cluster (ArgoCD, Flux) automatically detect changes and apply them, creating a pull-based deployment model that provides numerous operational advantages including complete audit trails through Git history, easy rollback by reverting Git commits, declarative disaster recovery where rebuilding a cluster just means pointing a fresh cluster at your Git repository, and enhanced security since cluster credentials don't need to exist outside the cluster.

The GitOps methodology has gained massive adoption because it solves fundamental problems in Kubernetes deployment workflows. Traditional CI/CD pipelines where Jenkins or GitLab CI runs kubectl apply to push changes require storing cluster credentials in CI systems creating security risks, lack comprehensive audit trails since pipeline execution logs aren't as permanent or queryable as Git history, make rollbacks complex requiring re-running previous pipeline versions or manual kubectl commands, create configuration drift when emergency hotfixes are applied manually but not committed to Git, and struggle with multi-cluster deployments requiring complex logic to deploy the same application with environment-specific variations across development, staging, and production clusters.

This comprehensive guide teaches you everything about implementing GitOps for Kubernetes in production environments, covering: core GitOps principles and how they differ from traditional CI/CD push-based deployments, the two dominant GitOps tools ArgoCD and Flux with detailed comparison helping you choose, complete ArgoCD implementation from installation through application deployment with best practices, Flux implementation guide including bootstrap, source configuration, and kustomization, repository structure patterns organizing Kubernetes manifests for multiple environments and applications, handling secrets in GitOps using Sealed Secrets or External Secrets Operator since committing plain Secrets to Git violates security, implementing progressive delivery and canary deployments with Flagger, multi-cluster GitOps managing deployments across development, staging, and production clusters, and how Atmosly's Pipeline Builder integrates with GitOps workflows providing visual pipeline creation that generates ArgoCD or Flux configurations, deployment coordination across multiple services, automated rollback on health check failures, and environment cloning for testing changes before production.

By implementing GitOps following this guide, you'll achieve declarative, version-controlled, auditable, and easily rollback-able Kubernetes deployments while maintaining security and enabling team collaboration through Git's familiar pull request workflows.

Core GitOps Principles

The Four GitOps Principles

1. Declarative Configuration

Infrastructure and applications described declaratively using Kubernetes YAML manifests, not imperative scripts. Git stores the desired state (Deployment with 5 replicas), not commands to achieve it (kubectl scale --replicas=5).

2. Versioned and Immutable

All configuration stored in Git providing complete version history, ability to view any previous state, and rollback by reverting commits. Git commits are immutable—history cannot be rewritten protecting audit trail.

3. Pulled Automatically

Changes pulled from Git by agents running in cluster (ArgoCD, Flux), not pushed by external CI/CD. Cluster credentials stay in cluster, never exported to CI systems. Agents continuously reconcile actual state to match Git.

4. Continuously Reconciled

Agents continuously verify cluster state matches Git, automatically fixing drift. If someone manually runs kubectl delete to remove a deployment, GitOps operator detects missing resource and recreates it from Git within minutes.

GitOps vs Traditional CI/CD

AspectTraditional CI/CD (Push)GitOps (Pull)
Deployment MethodPipeline runs kubectl apply pushing changesAgent in cluster pulls from Git, applies changes
Cluster CredentialsStored in CI system (security risk)Stay in cluster (more secure)
Audit TrailPipeline logs (ephemeral)Git history (permanent)
RollbackRe-run old pipeline or manual kubectlGit revert (simple, auditable)
Drift DetectionNone (manual changes persist)Automatic (manual changes reverted)
Multi-ClusterComplex pipeline logicMultiple agents, same Git repo

GitOps Tools: ArgoCD vs Flux

ArgoCD: The Declarative GitOps CD Tool

ArgoCD, created by Intuit and now a CNCF graduated project, is the most popular GitOps tool for Kubernetes with rich UI, extensive features, and mature ecosystem.

Key Features:

  • Web UI: Rich interface showing application health, sync status, resource tree, diff viewer
  • Multi-Cluster Support: Manage deployments across hundreds of clusters from single ArgoCD instance
  • Application CRD: Defines what to deploy (Git repo + path + cluster)
  • Sync Strategies: Automatic (changes auto-deployed) or manual (require approval)
  • Sync Waves: Deploy resources in specific order (databases before applications)
  • Health Assessment: Knows if Deployment healthy (all replicas available)
  • Kustomize and Helm: Native support for both templating tools
  • RBAC: Fine-grained access control (who can deploy what where)
  • SSO Integration: OIDC, SAML, GitHub, GitLab authentication

ArgoCD Architecture:

┌──────────────┐
│  Git Repo    │  ← Developers commit YAML
│  (GitHub)    │
└──────┬───────┘
       │
       │ Monitors for changes
       ↓
┌──────────────────┐
│  ArgoCD Server   │  ← Runs in cluster
│  (Controller)    │
└──────┬───────────┘
       │
       │ Applies changes
       ↓
┌──────────────────┐
│  Kubernetes      │  ← Target cluster(s)
│  Cluster         │
└──────────────────┘

Flux: The GitOps Toolkit

Flux v2, a CNCF graduated project, is a toolkit for building GitOps workflows with modular controllers.

Key Features:

  • Multi-Tenancy: Different teams manage different Git repos/paths independently
  • Modular Controllers: Source Controller (Git), Kustomize Controller (manifests), Helm Controller (charts), Notification Controller (alerts)
  • GitRepository CRD: Defines Git source
  • Kustomization CRD: Defines what to apply from Git source
  • Flux Bootstrap: Self-managing (Flux manages its own updates via Git)
  • Image Automation: Automatically updates image tags in Git when new images built
  • Notification: Slack, MS Teams alerts on sync success/failure
  • Progressive Delivery: Flagger integration for canary deployments

ArgoCD vs Flux Comparison

FeatureArgoCDFlux
UI✅ Rich Web UI❌ CLI only (UI via Weave GitOps paid)
Ease of Use✅ Easier (visual)⚠️ Steeper (CLI-focused)
Multi-Cluster✅ Excellent (hub-spoke)✅ Good (Flux per cluster)
RBAC✅ Built-in UI RBAC⚠️ K8s RBAC only
Helm Support✅ Native✅ Native (Helm Controller)
Image Updates⚠️ Manual or webhooks✅ Automatic (Image Automation)
BootstrapManual install✅ Self-managing
Best ForTeams wanting UI, multi-clusterAutomation-first, multi-tenant

Recommendation: ArgoCD if you value UI and ease of use. Flux if you prefer automation and CLI workflows. Both are production-ready.

Implementing ArgoCD: Complete Guide

Step 1: Install ArgoCD

# Create namespace
kubectl create namespace argocd

# Install ArgoCD
kubectl apply -n argocd -f \\
  https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Wait for pods to be ready
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s

# Get initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret \\
  -o jsonpath="{.data.password}" | base64 -d

# Access ArgoCD UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Visit: https://localhost:8080
# Login: admin / (password from above)

Step 2: Configure Git Repository

Structure your Git repository:

my-k8s-manifests/
├── apps/
│   ├── frontend/
│   │   ├── base/
│   │   │   ├── deployment.yaml
│   │   │   ├── service.yaml
│   │   │   └── kustomization.yaml
│   │   ├── overlays/
│   │   │   ├── dev/
│   │   │   │   └── kustomization.yaml
│   │   │   ├── staging/
│   │   │   │   └── kustomization.yaml
│   │   │   └── production/
│   │   │       └── kustomization.yaml
│   ├── backend/
│   │   └── ... (same structure)
└── infrastructure/
    ├── ingress-nginx/
    ├── cert-manager/
    └── monitoring/

Step 3: Create ArgoCD Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: frontend-production
  namespace: argocd
spec:
  project: default
  
  source:
    repoURL: https://github.com/myorg/k8s-manifests
    targetRevision: main
    path: apps/frontend/overlays/production
  
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  
  syncPolicy:
    automated:
      prune: true      # Delete resources not in Git
      selfHeal: true   # Auto-fix manual changes
    syncOptions:
    - CreateNamespace=true
# Apply Application resource
kubectl apply -f frontend-app.yaml

# ArgoCD automatically:
# 1. Connects to GitHub repo
# 2. Reads manifests from apps/frontend/overlays/production
# 3. Applies to production namespace
# 4. Monitors for Git changes
# 5. Auto-syncs on new commits

Implementing Flux: Complete Guide

Step 1: Bootstrap Flux

# Install Flux CLI
brew install fluxcd/tap/flux

# Bootstrap Flux (creates components in cluster + commits to Git)
flux bootstrap github \\
  --owner=myorg \\
  --repository=k8s-manifests \\
  --branch=main \\
  --path=clusters/production \\
  --personal

# This:
# 1. Installs Flux controllers in flux-system namespace
# 2. Commits Flux manifests to your Git repo
# 3. Configures Flux to sync from repo
# 4. Flux now manages itself (self-updating)

Step 2: Define GitRepository Source

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: app-repo
  namespace: flux-system
spec:
  interval: 1m  # Check Git every minute
  url: https://github.com/myorg/k8s-manifests
  ref:
    branch: main
  secretRef:
    name: github-credentials  # If private repo

Step 3: Create Kustomization for Application

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: frontend
  namespace: flux-system
spec:
  interval: 5m
  path: ./apps/frontend/overlays/production
  prune: true  # Delete resources not in Git
  sourceRef:
    kind: GitRepository
    name: app-repo
  healthChecks:
  - apiVersion: apps/v1
    kind: Deployment
    name: frontend
    namespace: production

GitOps Best Practices for Production

1. Repository Structure: Monorepo vs Multi-Repo

Monorepo (Recommended for Most Teams):

  • Single Git repository containing all applications and infrastructure
  • Easier to manage, atomic changes across multiple apps
  • Clear directory structure separating apps, environments, infrastructure

Multi-Repo (For Large Organizations):

  • Separate repo per application or team
  • Better access control (team A can't modify team B's repo)
  • More complex (managing multiple repos)

2. Handling Secrets Securely

Never commit plaintext Secrets to Git!

Option 1: Sealed Secrets

# Install Sealed Secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# Encrypt secret
echo -n mypassword | kubectl create secret generic db-password \\
  --dry-run=client --from-file=password=/dev/stdin -o yaml | \\
  kubeseal -o yaml > sealed-db-password.yaml

# Commit sealed-db-password.yaml to Git (safe, encrypted)
git add sealed-db-password.yaml
git commit -m "Add database password (sealed)"

Option 2: External Secrets Operator

# Store secret in AWS Secrets Manager
aws secretsmanager create-secret \\
  --name prod/database/password \\
  --secret-string "mypassword"

# Commit ExternalSecret to Git (references AWS, not plaintext)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-password
spec:
  secretStoreRef:
    name: aws-secretstore
  target:
    name: db-secret
  data:
  - secretKey: password
    remoteRef:
      key: prod/database/password

3. Environment-Specific Configuration with Kustomize

# Base configuration (shared)
# apps/frontend/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3  # Default
  template:
    spec:
      containers:
      - name: app
        image: frontend:v1.0.0
        resources:
          requests:
            cpu: 100m
            memory: 128Mi

# Development overlay
# apps/frontend/overlays/dev/kustomization.yaml
bases:
- ../../base
patchesStrategicMerge:
- patch.yaml

# apps/frontend/overlays/dev/patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 1  # Only 1 replica in dev

# Production overlay
# apps/frontend/overlays/production/kustomization.yaml
bases:
- ../../base
patchesStrategicMerge:
- patch.yaml

# apps/frontend/overlays/production/patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 10  # 10 replicas in production
  template:
    spec:
      containers:
      - name: app
        resources:
          requests:
            cpu: 500m      # More resources in prod
            memory: 512Mi

4. Implementing Progressive Delivery with Flagger

Flagger automates canary deployments with automatic rollback on errors:

# Install Flagger
kubectl apply -f https://raw.githubusercontent.com/fluxcd/flagger/main/artifacts/flagger/crd.yaml
helm upgrade -i flagger flagger/flagger \\
  --namespace=istio-system \\
  --set meshProvider=istio

# Define Canary
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: frontend
  namespace: production
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: frontend
  service:
    port: 80
  analysis:
    interval: 1m
    threshold: 5
    maxWeight: 50
    stepWeight: 10
    metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99  # Rollback if success rate < 99%
    - name: request-duration
      thresholdRange:
        max: 500  # Rollback if p99 latency > 500ms

# Flagger gradually shifts traffic: 0% → 10% → 20% → 30% → 50%
# Monitors metrics at each step
# Auto-rollback if metrics degrade

5. Multi-Cluster GitOps

Pattern: App of Apps

# Root application defining all other applications
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/myorg/k8s-manifests
    path: clusters/production
  destination:
    server: https://kubernetes.default.svc
  syncPolicy:
    automated: {}

# clusters/production/ contains Application manifests for:
# - frontend
# - backend
# - database
# - monitoring
# Each deployed automatically when root-app syncs

How Atmosly's Pipeline Builder Integrates with GitOps

While GitOps tools like ArgoCD and Flux handle the deployment automation, Atmosly's Pipeline Builder complements them by simplifying pipeline creation and providing deployment intelligence.

Visual Pipeline Creation (≤20% Atmosly Content)

Atmosly Pipeline Builder provides:

  • Visual Editor: Create CI/CD pipelines through drag-and-drop interface generating ArgoCD Application manifests or Flux Kustomization automatically
  • GitOps Configuration Generator: Answers questions about your setup (Git repo URL, target cluster, deployment path) and generates complete ArgoCD or Flux configuration files ready to commit to Git
  • Deployment Coordination: For microservices architectures, coordinates deployments across multiple services ensuring dependencies deploy in correct order (databases before applications using them)
  • Health Check Integration: Configures ArgoCD/Flux health checks, adds custom health assessments beyond default Kubernetes readiness (database connection tests, API endpoint validation)
  • Automated Rollback: If deployment causes elevated error rates or latency degradation detected by Atmosly monitoring, triggers automatic Git revert and ArgoCD/Flux re-sync to previous working version
  • Environment Cloning: Clone entire GitOps-managed environment (production → staging for testing) with automated manifest transformation (different namespaces, resource limits, replicas)

Atmosly enhances GitOps workflows but doesn't replace ArgoCD or Flux—it provides the layer above helping teams implement GitOps more easily.

Troubleshooting GitOps Deployments

Common Issues and Solutions

Issue 1: Application Shows "OutOfSync"

# Check sync status
kubectl get application frontend -n argocd

# View diff
argocd app diff frontend

# Manual sync if automatic sync disabled
argocd app sync frontend

Issue 2: Sync Failed with Errors

# Check sync operation status
argocd app get frontend

# View detailed error
kubectl logs -n argocd deployment/argocd-application-controller

# Common errors:
# - YAML syntax error (validate locally first)
# - Resource already exists (set sync policy to prune/replace)
# - RBAC permissions (ArgoCD service account lacks permission)

Issue 3: Manual Changes Keep Getting Reverted

This is GitOps working correctly! Manual kubectl changes are detected as drift and automatically reverted to match Git.

Solution: If change is needed, commit to Git first, then ArgoCD applies it.

Conclusion: GitOps for Reliable Kubernetes Deployments

GitOps transforms Kubernetes deployments from error-prone manual operations to declarative, version-controlled, auditable, automatically reconciled systems. Whether you choose ArgoCD for its UI and ease of use, or Flux for its automation and modularity, GitOps principles provide significant operational benefits.

Key Implementation Steps:

  1. Structure Git repository with clear separation (apps, infrastructure, environments)
  2. Install ArgoCD or Flux in your cluster
  3. Define Applications or Kustomizations pointing to Git paths
  4. Enable automatic sync for continuous deployment
  5. Handle secrets with Sealed Secrets or External Secrets
  6. Implement progressive delivery with Flagger for canary rollouts
  7. Use Atmosly's Pipeline Builder to simplify setup and add deployment intelligence

GitOps Benefits:

  • ✅ Single source of truth (Git)
  • ✅ Complete audit trail via Git history
  • ✅ Easy rollback (git revert)
  • ✅ Declarative disaster recovery
  • ✅ No cluster credentials in CI/CD
  • ✅ Automatic drift correction
  • ✅ Pull request workflows for changes

Ready to implement GitOps for your Kubernetes deployments? Start with Atmosly's Pipeline Builder to generate ArgoCD or Flux configurations visually, then enhance with automated rollback, health checks, and deployment coordination across your microservices.

Frequently Asked Questions

What is GitOps for Kubernetes?
GitOps is operational framework where Git repository serves as single source of truth for declarative Kubernetes configurations. Instead of manually running kubectl apply or CI/CD pipelines pushing changes to clusters, you commit YAML manifests to Git and specialized operators (ArgoCD, Flux) running in cluster automatically detect changes and apply them. Four principles: (1) Declarative - infrastructure described in YAML not imperative scripts, (2) Versioned and Immutable - all config in Git with complete history, (3) Pulled Automatically - agents pull from Git not pushed by CI, (4) Continuously Reconciled - automatic drift detection and correction. Benefits: Complete audit trail via Git history, easy rollback by reverting commits, disaster recovery by pointing new cluster at Git repo, enhanced security (cluster credentials stay in cluster), automated drift correction (manual kubectl changes auto-reverted to match Git). Popular tools: ArgoCD (rich UI, easy), Flux (automation-first, modular).
What is the difference between ArgoCD and Flux?
ArgoCD vs Flux comparison: ARGOCD: Rich web UI showing application health and sync status visually, easier for teams new to GitOps (visual interface), excellent multi-cluster support (manage 100+ clusters from single ArgoCD instance), built-in RBAC with SSO integration (GitHub, OIDC, SAML), Application CRD defines what to deploy, manual or automatic sync policies, best for: teams wanting UI, multi-cluster management, easier learning curve. FLUX: CLI-focused (UI available via paid Weave GitOps), modular controllers (Source, Kustomize, Helm, Notification), automatic image update when new container images built (unique to Flux), self-managing via bootstrap (Flux manages its own updates via Git), multi-tenancy native (different teams manage different repos independently), best for: automation-first teams, multi-tenant environments, CI/CD integration. Both production-ready CNCF projects. Choose ArgoCD if you value UI and simplicity. Choose Flux if you prefer automation and CLI workflows. Both support Helm, Kustomize, multi-cluster, and GitOps principles equally well.
How do I handle secrets in GitOps without committing them to Git?
Handle secrets in GitOps using encryption or external references: (1) SEALED SECRETS (Recommended): Install Sealed Secrets controller in cluster generating encryption key pair, encrypt secrets using kubeseal CLI with public key creating SealedSecret resource, commit encrypted SealedSecret to Git safely (only cluster with private key can decrypt), ArgoCD/Flux deploys SealedSecret, controller auto-decrypts creating standard Kubernetes Secret. Command: kubectl create secret generic db-password --dry-run=client --from-literal=password=mypass -o yaml | kubeseal -o yaml > sealed-secret.yaml. (2) EXTERNAL SECRETS OPERATOR: Store secrets in external system (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, HashiCorp Vault), commit ExternalSecret CRD to Git referencing external secret by name/path, ESO controller fetches from external system creating Kubernetes Secret. (3) SOPS (Mozilla): Encrypt specific fields in YAML files, commit encrypted files to Git, ArgoCD/Flux decrypt during deployment. (4) Git-Crypt: Transparent encryption of files in Git. NEVER commit base64-encoded Secrets (trivially decoded). Use Sealed Secrets for simplicity, External Secrets for centralized management across clusters.
How does Atmosly's Pipeline Builder work with GitOps?
Atmosly Pipeline Builder complements ArgoCD and Flux providing higher-level pipeline creation and deployment intelligence: (1) VISUAL PIPELINE CREATION: Drag-and-drop interface for creating CI/CD pipelines, automatically generates ArgoCD Application manifests or Flux Kustomization configurations, no manual YAML writing for GitOps setup, (2) GITOPS CONFIGURATION GENERATOR: Guides you through setup questions (Git repo URL, target cluster, deployment path, sync policy), generates complete ArgoCD or Flux configuration files ready to commit to Git, (3) DEPLOYMENT COORDINATION: For microservices (10+ services), coordinates deployment order ensuring dependencies (databases deployed before apps using them), manages cross-service deployments (deploy frontend + backend + worker together), (4) HEALTH CHECK INTEGRATION: Configures ArgoCD/Flux health assessments, adds custom health checks beyond Kubernetes defaults (database connectivity, API endpoint validation), (5) AUTOMATED ROLLBACK: If Atmosly monitoring detects elevated errors or latency after deployment, triggers automatic Git revert and forces ArgoCD/Flux re-sync to previous version, (6) ENVIRONMENT CLONING: Clones GitOps-managed environments (production → staging for testing) with automatic manifest adjustments (namespaces, resources, replicas). Atmosly is complementary layer above ArgoCD/Flux making GitOps easier to implement and more intelligent, not replacement for core GitOps tools.