Implementing Declarative Kubernetes Delivery with ArgoCD

Consider the fragility of a traditional CI/CD pipeline deploying to Kubernetes. The CI server builds an artifact, authenticates against the cluster, and executes kubectl apply. This "Push" model introduces a critical security vulnerability: the CI environment requires write access to the production cluster. Furthermore, it creates a split-brain scenario where the cluster's actual state can drift from the configuration stored in version control due to manual ad-hoc changes. If a developer runs kubectl edit deployment directly to hotfix an issue, the Git repository becomes obsolete immediately. GitOps eliminates this divergence by inverting the workflow.

The Pull Model Architecture

ArgoCD functions as a Kubernetes controller that continuously monitors running applications and compares their live state against the desired state defined in a Git repository. This control loop ensures that Git remains the Single Source of Truth (SSOT). Unlike the Push model, ArgoCD runs inside the cluster (or manages it remotely) and pulls changes. This architecture removes the need for external CI systems to hold cluster credentials.

When a divergence—or "Configuration Drift"—is detected, ArgoCD marks the application as OutOfSync. Depending on the syncPolicy, it can automatically revert the cluster to match Git, effectively self-healing unauthorized manual changes.

Latency & Polling: By default, ArgoCD polls the Git repository every 3 minutes. For near-real-time synchronization, configure a Webhook in the Git provider (GitHub/GitLab) to trigger the ArgoCD API server immediately upon a push event.

Defining State with Application CRDs

The core abstraction in ArgoCD is the Application Custom Resource Definition (CRD). This resource maps a source (Git path, Helm chart, Kustomize overlay) to a destination (Cluster URL, Namespace). For production environments utilizing Helm Charts and Kustomize, the manifest must explicitly define value overrides and pathing to ensure deterministic deployments.

Below is a production-grade Application manifest that enables automated synchronization and pruning of orphaned resources.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: payment-service-prod
  namespace: argocd
spec:
  project: default
  # Source of Truth
  source:
    repoURL: 'https://github.com/org/payment-service-deploy.git'
    targetRevision: HEAD
    path: k8s/overlays/production
    # Kustomize specific configuration
    kustomize:
      namePrefix: prod-
      commonLabels:
        environment: production

  # Destination Cluster
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: payment-backend

  # Sync Policy ensuring strict consistency
  syncPolicy:
    automated:
      prune: true    # Deletes resources no longer in Git
      selfHeal: true # Reverts manual kubectl changes
    syncOptions:
      - CreateNamespace=true
      - PruneLast=true

Managing Secrets in a Public Git Context

One of the primary challenges in adopting GitOps is handling sensitive data. Since Git repositories—even private ones—should not store raw secrets (API keys, database passwords), a mechanism to encrypt secrets at rest in Git and decrypt them in the cluster is required. Sealed Secrets by Bitnami is the industry-standard solution compatible with ArgoCD.

The workflow involves a developer encrypting a Secret using a public key provided by the controller running in the cluster. The resulting SealedSecret CRD is safe to commit to Git. When ArgoCD syncs this resource, the Sealed Secrets controller decrypts it using the private key (stored only in the cluster) and creates a standard Kubernetes Secret.

Key Rotation: If the cluster is deleted or the private key is lost, all Sealed Secrets in Git become undecryptable. Ensure you back up the master key of the Sealed Secrets controller.

Multi-Cluster Management Strategy

In enterprise environments, a single ArgoCD instance often manages deployments across multiple clusters (e.g., dev, staging, prod-us-east, prod-eu-west). This is achieved by registering external clusters as destinations. The central ArgoCD instance requires a ServiceAccount with limited RBAC permissions in the target clusters.

This "Hub-and-Spoke" topology simplifies observability but introduces a single point of failure. If the central ArgoCD cluster goes down, deployment capability is lost across the fleet, although the applications themselves continue running. For high availability, consider a sharded approach where critical production clusters manage their own state.

Comparison: Traditional CI/CD vs. GitOps

Understanding the difference between GitOps and traditional CI/CD pipelines is crucial for justifying the architectural migration.

Feature Traditional CI/CD (Push) ArgoCD GitOps (Pull)
Cluster Access CI Server requires admin/write credentials Agent runs inside cluster; no external creds
Drift Detection None (State known only at deploy time) Continuous monitoring (Live vs. Git)
Rollback Re-run old CI pipeline (Error prone) git revert or argocd app rollback
Disaster Recovery Manual reconstruction of state Apply Git repo to new cluster

Addressing the ApplicationSet Pattern

Managing hundreds of microservices manually with individual Application manifests is not scalable. The ApplicationSet controller automates the generation of Application resources based on templates. It can traverse a Git repository structure (e.g., directories per app) or use a list of clusters defined in secrets to dynamically deploy workloads across a fleet.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: global-guestbook
spec:
  generators:
  - list:
      elements:
      - cluster: engineering-dev
        url: https://1.2.3.4
      - cluster: engineering-prod
        url: https://5.6.7.8
  template:
    metadata:
      name: '{{cluster}}-guestbook'
    spec:
      project: default
      source:
        repoURL: https://github.com/infra/guestbook.git
        targetRevision: HEAD
        path: guestbook
      destination:
        server: '{{url}}'
        namespace: guestbook

By shifting from imperative commands to a declarative state model, organizations achieve higher velocity and stricter compliance. The system becomes audit-friendly by default, as every change to the infrastructure is recorded as a commit in the version control history.

Post a Comment