Kubernetes Continuous Delivery: GitOps Pipelines with ArgoCD & Flux
Build reliable, automated deployment pipelines for Kubernetes using GitOps with ArgoCD and Flux

Continuous delivery on Kubernetes has evolved far beyond simple kubectl apply commands. Modern teams are adopting GitOps, a paradigm that uses Git as the single source of truth for declarative infrastructure and application configuration. By combining GitOps principles with tools like ArgoCD and Flux CD, organizations can achieve reliable, auditable, and automated deployment pipelines that scale across clusters and environments.
This guide covers the architecture, setup, and best practices for building production-grade continuous delivery pipelines on Kubernetes using the GitOps approach.
GitOps Principles
GitOps is built on four core principles that fundamentally change how teams manage deployments:
- Declarative Configuration - The entire desired state of your system is described declaratively. For Kubernetes, this means YAML manifests, Helm charts, or Kustomize overlays stored in Git.
- Version Controlled - Git serves as the single source of truth. Every change goes through a pull request, providing a complete audit trail and enabling easy rollbacks by reverting commits.
- Automated Reconciliation - An agent running in the cluster continuously compares the desired state in Git with the actual state in the cluster and automatically reconciles any drift.
- Continuous Observation - The system continuously monitors both the Git repository and the cluster state, alerting on divergence and ensuring the cluster always matches the declared configuration.
These principles eliminate manual deployment steps, reduce human error, and provide a consistent workflow regardless of cluster complexity.
ArgoCD Architecture and Setup
ArgoCD is the most widely adopted GitOps tool for Kubernetes. It provides a powerful web UI, CLI, and API for managing application deployments across clusters.
Core Components
ArgoCD consists of several key components that work together:
- API Server - Exposes a gRPC/REST API and serves the web UI. Handles authentication, RBAC, and external integrations.
- Repository Server - Clones Git repositories and generates Kubernetes manifests from Helm charts, Kustomize, or plain YAML.
- Application Controller - Continuously monitors running applications and compares the live state against the desired state in Git.
- Redis - Provides caching for the repository server and application controller.
Installation
Deploy ArgoCD to your cluster using the official manifests or Helm chart:
# Create namespace and install ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Or via Helm
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--set server.service.type=LoadBalancerDefining Applications
ArgoCD uses an Application custom resource to define what to deploy and where. Here is a typical application definition:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-web-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/my-web-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3mThe syncPolicy.automated section enables automatic synchronization. The prune option removes resources that are no longer defined in Git, while selfHeal reverts manual changes made directly to the cluster.
Flux CD: An Alternative Approach
Flux CD takes a different architectural approach to GitOps. Rather than a centralized server with a UI, Flux operates as a set of Kubernetes controllers that each handle a specific concern.
Flux Components
- Source Controller - Manages Git repositories, Helm repositories, and OCI artifact sources.
- Kustomize Controller - Applies Kustomize overlays and plain YAML manifests.
- Helm Controller - Manages Helm chart releases through
HelmReleasecustom resources. - Notification Controller - Handles inbound and outbound events, integrating with Slack, Teams, and webhook providers.
- Image Automation Controllers - Scan container registries and update manifests when new images are available.
Flux Bootstrap
# Bootstrap Flux on a cluster with a GitHub repository
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/production \
--personal
# Define a HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: nginx-ingress
namespace: ingress-system
spec:
interval: 5m
chart:
spec:
chart: ingress-nginx
version: "4.x"
sourceRef:
kind: HelmRepository
name: ingress-nginx
namespace: flux-system
values:
controller:
replicaCount: 3
metrics:
enabled: trueArgoCD vs Flux: When to Choose Which
ArgoCD is ideal when you need a rich web UI for visibility, multi-tenancy with fine-grained RBAC, and a centralized management plane. Flux shines in environments that prefer a lightweight, controller-based architecture, need image automation capabilities, or want deeper integration with the Kubernetes API ecosystem.
Helm Chart Management in GitOps
Helm charts are the de facto packaging format for Kubernetes applications. In a GitOps workflow, managing Helm values across environments requires careful organization.
# Repository structure for multi-environment Helm management
k8s-manifests/
base/
my-app/
Chart.yaml
values.yaml # Default values
templates/
deployment.yaml
service.yaml
ingress.yaml
environments/
dev/
my-app/
values.yaml # Dev overrides
staging/
my-app/
values.yaml # Staging overrides
production/
my-app/
values.yaml # Production overridesBoth ArgoCD and Flux support Helm natively. ArgoCD renders charts server-side through its repository server, while Flux uses the Helm SDK directly within its Helm Controller.
Deployment Strategies
Choosing the right deployment strategy minimizes risk and ensures zero-downtime releases.
Rolling Updates
The default Kubernetes strategy. Pods are gradually replaced with new versions. Configure maxSurge and maxUnavailable to control the rollout speed.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: app
image: myapp:v2.1.0
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10Blue-Green Deployments
Run two identical environments (blue and green). Deploy the new version to the inactive environment, verify it, then switch traffic. This provides instant rollback by switching back to the previous environment. Implement with service label selectors or Istio traffic management.
Canary Deployments
Gradually route a small percentage of traffic to the new version, increasing the percentage as confidence grows. Tools like Flagger and Argo Rollouts automate canary analysis with metrics-based promotion.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-app
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 30
- pause: { duration: 5m }
- setWeight: 60
- pause: { duration: 5m }
canaryService: my-app-canary
stableService: my-app-stable
trafficRouting:
istio:
virtualService:
name: my-app-vsvc
routes:
- primaryAutomated Rollbacks
GitOps makes rollbacks straightforward: simply revert the Git commit. However, automated rollbacks based on health checks provide an additional safety net.
ArgoCD supports automated rollbacks through its sync and health assessment system. If an application enters a degraded state after a sync, ArgoCD can automatically roll back to the last known good state.
For more sophisticated rollback scenarios, Argo Rollouts and Flagger can analyze Prometheus metrics, run automated tests, and abort rollouts that show degraded performance.
Secrets Management with Sealed Secrets
Storing secrets in Git is a critical challenge for GitOps. Sealed Secrets solves this by encrypting secrets that can only be decrypted by the controller running in the target cluster.
# Install Sealed Secrets controller
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets \
--namespace kube-system
# Encrypt a secret
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=s3cure-p@ss \
--dry-run=client -o yaml | \
kubeseal --format yaml > db-credentials-sealed.yamlThe resulting SealedSecret resource can be safely committed to Git. Only the Sealed Secrets controller in the target cluster holds the private key needed to decrypt it. Alternative approaches include External Secrets Operator (for pulling from AWS Secrets Manager, HashiCorp Vault, etc.) and SOPS for file-level encryption.
Monitoring Deployments
Visibility into deployment status is essential for production GitOps pipelines. Implement monitoring at multiple levels:
- ArgoCD Metrics - ArgoCD exposes Prometheus metrics for sync status, health, and operation duration. Create Grafana dashboards to track deployment frequency and failure rates.
- Kubernetes Events - Monitor pod scheduling, image pull, and readiness probe events to detect issues early.
- Application Health Checks - Configure custom health checks in ArgoCD using Lua scripts to define what "healthy" means for your specific resources.
- Alerting - Integrate ArgoCD notifications with Slack, PagerDuty, or email to alert on sync failures, health degradation, or drift detection.
# ArgoCD Notification ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
trigger.on-sync-failed: |
- when: app.status.operationState.phase in ['Error', 'Failed']
send: [slack-notification]
template.slack-notification: |
message: |
Application {{.app.metadata.name}} sync {{.app.status.operationState.phase}}.
Revision: {{.app.status.sync.revision}}
service.slack: |
token: $slack-token
channel: deploymentsMulti-Cluster Delivery
As organizations scale, deploying across multiple clusters becomes necessary. ArgoCD supports multi-cluster management natively by registering external clusters. Flux achieves this through a management cluster that bootstraps workload clusters.
The ApplicationSet controller in ArgoCD is particularly powerful for multi-cluster scenarios. It can generate Application resources dynamically based on cluster lists, Git directories, or pull request events.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-app-set
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
template:
metadata:
name: 'my-app-{{name}}'
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: 'apps/my-app/overlays/{{metadata.labels.region}}'
destination:
server: '{{server}}'
namespace: my-appConclusion
GitOps with ArgoCD or Flux CD provides a robust foundation for Kubernetes continuous delivery. By treating Git as the source of truth, automating reconciliation, and leveraging progressive delivery strategies, teams can deploy with confidence and recover from failures quickly. Start with a simple single-cluster setup, establish your Git repository structure, and gradually adopt advanced patterns like canary deployments, multi-cluster management, and automated rollback policies as your platform matures.
The investment in GitOps infrastructure pays dividends through improved reliability, faster incident response, complete audit trails, and a developer experience that makes deployments as simple as merging a pull request.