Implementing GitOps
1. Understanding GitOps Principles
| Principle | Description | Key Benefit |
|---|---|---|
| Declarative Configuration | Infrastructure and application state are defined using configuration files (e.g., YAML manifests) stored in a Git repository. | Ensures consistency and reproducibility across environments by treating infrastructure as code. |
| Version Control | All changes to configurations are tracked using Git, enabling rollback and auditability. | Provides a complete history of changes with the ability to revert to previous states if needed. |
| Automation | Changes are automatically applied to the cluster via CI/CD pipelines or GitOps tools like Argo CD or Flux. | Reduces manual errors and accelerates deployment cycles by automating the reconciliation process. |
| Continuous Sync | GitOps tools continuously sync the desired state from Git to the cluster, ensuring alignment between source and runtime. | Maintains desired state even after manual or accidental changes to the cluster. |
Note: GitOps is not just about deploying code; it's a philosophy that treats infrastructure and application configuration as code, managed through version control.
Core GitOps Concepts
- Source of Truth: The Git repository holds the authoritative configuration.
- Reconciliation Loop: Tools like Argo CD or Flux continuously reconcile cluster state with Git.
- Change Management: All changes must go through a Git commit and merge process before being applied.
2. Installing Flux
Example: Install Flux CLI
# Install Flux CLI on macOS
brew install flux
# Install Flux CLI on Linux
curl -s https://fluxcd.io/install.sh | bash
# Install Flux CLI on Windows (PowerShell)
winget install flux
| Component | Description | Installation Method |
|---|---|---|
| flux cli | Command-line interface for GitOps operations | Binary download or package manager (brew, winget) |
| flux controllers | Core Kubernetes controllers for GitOps | Deployed via Helm or Kustomize |
Note: Ensure
kubectl is configured to connect to your target Kubernetes cluster before installing Flux.
Installation Steps
- Install the Flux CLI on your local machine
- Initialize Flux in a Git repository
- Deploy Flux controllers to your Kubernetes cluster
- Configure Git repository synchronization
3. Installing ArgoCD
Example: Install ArgoCD using Helm
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd --namespace argocd --create-namespace
| Component | Description | Version |
|---|---|---|
| argocd-server | ArgoCD API server and UI | v2.12.0 |
| argocd-repo-server | Manages Git repository operations | v2.12.0 |
| argocd-application-controller | Manages application lifecycle | v2.12.0 |
| argocd-dex-server | Authentication server (optional) | v2.12.0 |
Note: ArgoCD requires Kubernetes 1.24 or higher.
Warning: Ensure that the namespace
argocd exists or is created before installing.Installation Steps
- Add ArgoCD Helm repository
- Update Helm repositories
- Install ArgoCD using Helm chart
- Expose the ArgoCD server for external access (optional)
4. Creating GitRepository Source
| Field | Description | Example |
|---|---|---|
| apiVersion | API version of the GitRepository resource | source.toolkit.fluxcd.io/v1 |
| kind | Kind of the GitRepository resource | GitRepository |
| metadata.name | Name of the GitRepository resource | my-app-repo |
| spec.url | URL to the Git repository | https://github.com/example/my-app.git |
| spec.ref.branch | Branch to watch for changes | main |
| spec.ref.tag | Tag to watch for changes | v1.0.0 |
| spec.ref.commit | Commit hash to watch for changes | abc123def456 |
| spec.interval | How often to check for updates (default: 1m) | 5m |
| spec.timeout | Timeout for Git operations (default: 60s) | 30s |
Example: GitRepository with branch reference
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app-repo
spec:
url: https://github.com/example/my-app.git
ref:
branch: main
interval: 5m
Example: GitRepository with tag reference
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app-repo
spec:
url: https://github.com/example/my-app.git
ref:
tag: v1.0.0
interval: 5m
Note: The GitRepository resource must be created in the same namespace as the Flux components or in a namespace that is watched by Flux.
5. Creating Kustomization
| Property | Description | Values | Notes |
|---|---|---|---|
| apiVersion | API version of the Kustomization resource | kustomize.toolkit.fluxcd.io/v1 |
Must be set to the correct version |
| kind | Kind of the Kustomization resource | Kustomization |
Must be set to Kustomization |
| metadata.name | Name of the Kustomization resource | my-app |
Unique within the namespace |
| spec.path | Path to the kustomization directory in the Git repository | ./k8s/overlays/prod |
Relative path from the root of the repo |
| spec.sourceRef | Reference to the GitRepository resource | { kind: GitRepository, name: my-app-repo } |
Must point to a valid GitRepository |
| spec.targetNamespace | Namespace to apply the resources to | production |
Optional, defaults to the namespace of the Kustomization |
| spec.prune | Whether to prune resources that are no longer in the kustomization | true or false |
Defaults to false |
Example: Creating a Kustomization resource
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
spec:
path: ./k8s/overlays/prod
sourceRef:
kind: GitRepository
name: my-app-repo
targetNamespace: production
prune: true
6. Creating ArgoCD Application
| Field | Description | Example |
|---|---|---|
| metadata.name | Name of the ArgoCD application | my-app |
| spec.source.repoURL | Git repository URL containing the application manifests | https://github.com/example/my-app.git |
| spec.source.targetRevision | Git revision (branch, tag, or commit) to sync from | main |
| spec.source.path | Path within the repo to the application manifests | manifests/ |
| spec.destination.server | Kubernetes API server URL | https://kubernetes.default.svc |
| spec.destination.namespace | Kubernetes namespace to deploy the app | production |
Example: ArgoCD Application Manifest
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
source:
repoURL: https://github.com/example/my-app.git
targetRevision: main
path: manifests/
destination:
server: https://kubernetes.default.svc
namespace: production
Note: Ensure the ArgoCD controller has appropriate RBAC permissions to access the Git repository and deploy resources in the target namespace.
7. Configuring Auto-Sync
| Property | Value | Description |
|---|---|---|
| autoSync | true / false |
Enables or disables automatic synchronization of the Git repository with the cluster. |
| syncPolicy | automated / manual |
Determines whether sync is automatic or requires manual trigger. |
| prune | true / false |
If enabled, resources not present in the Git repo will be deleted from the cluster. |
| selfHeal | true / false |
Enables self-healing to restore drifts in cluster state back to desired state. |
Example: Auto-Sync Configuration
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
source:
repoURL: https://github.com/example/my-app.git
targetRevision: HEAD
path: .
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
Note: Auto-sync is particularly useful in CI/CD pipelines where changes should be automatically deployed to the cluster upon commit.
8. Managing Helm Releases
| Property | Description | Values |
|---|---|---|
| helm release | Represents a deployed instance of a chart | my-release |
| helm chart | Package of pre-configured Kubernetes resources | nginx-ingress-1.2.3.tgz |
| helm repo | Repository storing Helm charts | https://charts.bitnami.com/bitnami |
Example: Installing a Helm Release
helm install my-release bitnami/nginx-ingress \
--set controller.service.type=LoadBalancer \
--set controller.config.proxy-body-size=10m
Example: Upgrading a Helm Release
helm upgrade my-release bitnami/nginx-ingress \
--set controller.service.type=NodePort \
--version 1.2.4
Note: Helm releases are tracked in the Kubernetes API server using ConfigMaps and Secrets.
Warning: Ensure that your GitOps tooling (e.g., Argo CD) is configured to sync Helm releases from the correct chart repository.
9. Monitoring Sync Status
| Resource | Status Field | Description | Example Value |
|---|---|---|---|
| Kustomize | status.conditions |
Conditions indicating sync status | [{type: "Ready", status: "True", reason: "SyncSuccessful"}] |
| HelmRelease | status.conditions |
Conditions reflecting sync health | [{type: "Ready", status: "True", reason: "HelmChartSynced"}] |
| Application | status.sync.status |
Sync status of the application | "synchronized" |
| Application | status.health.status |
Health status of the application | "Healthy" |
Example: Check Application Sync Status
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
source:
repoURL: https://github.com/example/my-app.git
targetRevision: HEAD
path: .
destination:
server: https://kubernetes.default.svc
namespace: default
status:
sync:
status: <span class="highlight">synchronized</span>
revision: abc123
health:
status: <span class="highlight">Healthy</span>
Note: The
status.sync.status field can be "Unknown", "Progressing", "Synchronized", or "OutOfSync".
Warning: If
status.sync.status is "OutOfSync", the application is not in sync with the Git repository.
10. Troubleshooting Sync Issues
| Issue | Potential Cause | Solution |
|---|---|---|
| Sync fails with "unknown field" | Invalid or outdated resource definition in Git | Validate YAML syntax and check for deprecated fields. Update to supported API versions. |
| Sync stuck in "Progressing" | Resource dependencies not resolved or missing | Check logs from Argo CD controller and application pods. Ensure all dependencies are present. |
| Sync fails with "timeout" | Slow or unresponsive cluster components | Increase timeout values in Argo CD settings. Check cluster resource usage and network connectivity. |
| Sync shows "Missing" resources | Resources not defined in Git or incorrect namespace | Verify that all resources exist in the correct Git path and namespace matches between config and cluster. |
Example: Debugging a failed sync
argocd app get my-app --log-level debug
kubectl logs -n argocd deployment/argocd-application-controller
Note: Use
argocd app logs to view detailed logs from the application sync process.
Warning: Avoid modifying resources directly in the cluster while Argo CD is managing them.