Implementing GitOps with FluxCD for Kubernetes Applications

This guide provides a clear, standardized process for configuring FluxCD to manage Kubernetes applications using GitOps principles. It automates the deployment of application manifests from a Git repository to a staging namespace, utilizing a streamlined folder structure for simplicity and efficiency. The guide includes practical tests to validate GitOps functionality through an image tag update and pruning via replica adjustments, while preserving local Git integration for robust configuration management. Prerequisites Kubernetes Cluster: A running cluster, such as Kind, Minikube, AKS, or EKS. kubectl: Installed and configured to interact with the cluster. Flux CLI: Installed (e.g., curl -s https://fluxcd.io/install.sh | bash). Git: Installed for managing repositories. GitHub Account: Maintaining two repositories: /flux-config: Stores Flux configurations. /app-repo: Contains application manifests. GitHub Personal Access Token (PAT): Configured with repo scope permissions. Working Directory: /flux-config. Step 1: Set Up the Environment Create Working Directory: mkdir -p /flux-config cd /flux-config Initialize Git Repository: Set up a local Git repository for configuration management: git init git branch -M main Configure GitHub Credentials: Set environment variables for authentication, replacing and with your GitHub credentials: export GITHUB_USER= export GITHUB_TOKEN= Verify Cluster Compatibility: Confirm the cluster is ready for Flux: flux check --pre Expect confirmation of kubectl (version 1.26 or higher), cluster connectivity, and Flux CLI readiness. Resolve issues, such as setting kubeconfig with kubectl config use-context . Step 2: Create Folder Structure The folder structure is minimal, including only critical configuration files, with flux-system/ generated during setup. /flux-config/ ├── .git/ ├── clusters/ │ ├── staging/ │ │ ├── app-repo.yaml │ │ └── apps.yaml ├── flux-system/ (auto-generated) │ ├── gotk-components.yaml │ ├── gotk-sync.yaml │ └── kustomization.yaml Steps: Create directories: mkdir -p clusters/staging Create configuration files: touch clusters/staging/app-repo.yaml clusters/staging/apps.yaml Step 3: Configure Resources Define resources to monitor the application’s Git repository and deploy its manifests. Edit clusters/staging/app-repo.yaml: apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: my-app namespace: flux-system spec: interval: 1m url: https://github.com//app-repo ref: branch: main Instructs Flux to check the repository every minute for changes. Edit clusters/staging/apps.yaml: apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: my-app namespace: flux-system spec: interval: 5m sourceRef: kind: GitRepository name: my-app path: ./kubernetes/manifests prune: true targetNamespace: staging Configures Flux to apply manifests from kubernetes/manifests/ to the staging namespace, with pruning enabled to remove undefined resources, reconciling every five minutes. Step 4: Commit Configurations Add and commit configurations to the local repository: git add clusters/staging/ git commit -m "Add GitRepository and Kustomization for my-app" Step 5: Bootstrap Flux Initialize Flux to deploy its controllers and synchronize configurations with GitHub. Run Bootstrap: flux bootstrap github \ --owner=$GITHUB_USER \ --repository=flux-config \ --branch=main \ --path=clusters/staging \ --personal Creates or updates /flux-config. Installs Flux controllers (e.g., source-controller, kustomize-controller) in the flux-system namespace. Generates flux-system/ with gotk-components.yaml, gotk-sync.yaml, and kustomization.yaml. Pushes configurations to GitHub and sets Flux to monitor clusters/staging/. Verify Setup: Ensure Flux components are running: kubectl get pods -n flux-system Confirm pods like source-controller-... and kustomize-controller-... are active. Step 6: Configure Application Manifests Set up manifests in the application repository to define Kubernetes resources. Clone Application Repository: cd / mkdir temp-app cd temp-app git clone https://github.com//app-repo.git cd app-repo mkdir -p kubernetes/manifests Create kubernetes/manifests/deployment.yaml: apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: staging spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: nginx

Apr 13, 2025 - 21:37
 0
Implementing GitOps with FluxCD for Kubernetes Applications

This guide provides a clear, standardized process for configuring FluxCD to manage Kubernetes applications using GitOps principles. It automates the deployment of application manifests from a Git repository to a staging namespace, utilizing a streamlined folder structure for simplicity and efficiency. The guide includes practical tests to validate GitOps functionality through an image tag update and pruning via replica adjustments, while preserving local Git integration for robust configuration management.

Prerequisites

  • Kubernetes Cluster: A running cluster, such as Kind, Minikube, AKS, or EKS.
  • kubectl: Installed and configured to interact with the cluster.
  • Flux CLI: Installed (e.g., curl -s https://fluxcd.io/install.sh | bash).
  • Git: Installed for managing repositories.
  • GitHub Account: Maintaining two repositories:
    • /flux-config: Stores Flux configurations.
    • /app-repo: Contains application manifests.
  • GitHub Personal Access Token (PAT): Configured with repo scope permissions.
  • Working Directory: /flux-config.

Step 1: Set Up the Environment

  1. Create Working Directory:
   mkdir -p /flux-config
   cd /flux-config
  1. Initialize Git Repository: Set up a local Git repository for configuration management:
   git init
   git branch -M main
  1. Configure GitHub Credentials: Set environment variables for authentication, replacing and with your GitHub credentials:
   export GITHUB_USER=
   export GITHUB_TOKEN=
  1. Verify Cluster Compatibility: Confirm the cluster is ready for Flux:
   flux check --pre
  • Expect confirmation of kubectl (version 1.26 or higher), cluster connectivity, and Flux CLI readiness.
  • Resolve issues, such as setting kubeconfig with kubectl config use-context .

Step 2: Create Folder Structure

The folder structure is minimal, including only critical configuration files, with flux-system/ generated during setup.

/flux-config/
├── .git/
├── clusters/
│   ├── staging/
│   │   ├── app-repo.yaml
│   │   └── apps.yaml
├── flux-system/ (auto-generated)
│   ├── gotk-components.yaml
│   ├── gotk-sync.yaml
│   └── kustomization.yaml

Steps:

  1. Create directories:
   mkdir -p clusters/staging
  1. Create configuration files:
   touch clusters/staging/app-repo.yaml clusters/staging/apps.yaml

Step 3: Configure Resources

Define resources to monitor the application’s Git repository and deploy its manifests.

  1. Edit clusters/staging/app-repo.yaml:
   apiVersion: source.toolkit.fluxcd.io/v1
   kind: GitRepository
   metadata:
     name: my-app
     namespace: flux-system
   spec:
     interval: 1m
     url: https://github.com//app-repo
     ref:
       branch: main
  • Instructs Flux to check the repository every minute for changes.
  1. Edit clusters/staging/apps.yaml:
   apiVersion: kustomize.toolkit.fluxcd.io/v1
   kind: Kustomization
   metadata:
     name: my-app
     namespace: flux-system
   spec:
     interval: 5m
     sourceRef:
       kind: GitRepository
       name: my-app
     path: ./kubernetes/manifests
     prune: true
     targetNamespace: staging
  • Configures Flux to apply manifests from kubernetes/manifests/ to the staging namespace, with pruning enabled to remove undefined resources, reconciling every five minutes.

Step 4: Commit Configurations

Add and commit configurations to the local repository:

git add clusters/staging/
git commit -m "Add GitRepository and Kustomization for my-app"

Step 5: Bootstrap Flux

Initialize Flux to deploy its controllers and synchronize configurations with GitHub.

  1. Run Bootstrap:
   flux bootstrap github \
     --owner=$GITHUB_USER \
     --repository=flux-config \
     --branch=main \
     --path=clusters/staging \
     --personal
  • Creates or updates /flux-config.
  • Installs Flux controllers (e.g., source-controller, kustomize-controller) in the flux-system namespace.
  • Generates flux-system/ with gotk-components.yaml, gotk-sync.yaml, and kustomization.yaml.
  • Pushes configurations to GitHub and sets Flux to monitor clusters/staging/.
  1. Verify Setup: Ensure Flux components are running:
   kubectl get pods -n flux-system
  • Confirm pods like source-controller-... and kustomize-controller-... are active.

Step 6: Configure Application Manifests

Set up manifests in the application repository to define Kubernetes resources.

  1. Clone Application Repository:
   cd /
   mkdir temp-app
   cd temp-app
   git clone https://github.com//app-repo.git
   cd app-repo
   mkdir -p kubernetes/manifests
  1. Create kubernetes/manifests/deployment.yaml:
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: my-app
     namespace: staging
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: my-app
     template:
       metadata:
         labels:
           app: my-app
       spec:
         containers:
         - name: my-app
           image: nginx:1.14.2
           ports:
           - containerPort: 80
  1. Create kubernetes/manifests/service.yaml:
   apiVersion: v1
   kind: Service
   metadata:
     name: my-app-service
     namespace: staging
   spec:
     selector:
       app: my-app
     ports:
     - protocol: TCP
       port: 80
       targetPort: 80
     type: ClusterIP
  1. Commit and Push:
   git add .
   git commit -m "Add my-app manifests"
   git push origin main

Step 7: Create Namespace

Ensure the staging namespace is present:

kubectl create namespace staging --dry-run=client -o yaml | kubectl apply -f -

Step 8: Verify Deployment

Confirm Flux has correctly applied the manifests.

  1. Check GitRepository:
   flux get sources git my-app -n flux-system
  • Expect Ready: True, indicating repository sync.
  1. Check Kustomization:
   flux get kustomizations my-app -n flux-system
  • Expect Ready: True, confirming manifest deployment.
  1. Verify Resources:
   kubectl get deployments,services -n staging
  • Expect a my-app deployment (1 replica, nginx:1.14.2) and my-app-service.

Step 9: Test GitOps with Image Tag Update

Validate GitOps by updating the application’s image tag and confirming Flux applies the change.

  1. Update Image Tag: Edit /temp-app/app-repo/kubernetes/manifests/deployment.yaml:
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: my-app
     namespace: staging
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: my-app
     template:
       metadata:
         labels:
           app: my-app
       spec:
         containers:
         - name: my-app
           image: nginx:1.18.0
           ports:
           - containerPort: 80
  1. Commit and Push:
   cd /temp-app/app-repo
   git add kubernetes/manifests/deployment.yaml
   git commit -m "Update my-app image to nginx:1.18.0"
   git push origin main
  1. Reconcile (Optional): Accelerate the update:
   flux reconcile kustomization my-app -n flux-system
  1. Verify Update: Inspect running pods:
   kubectl get pods -n staging -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
  • Expect new pods running nginx:1.18.0, with old nginx:1.14.2 pods terminated.

Step 10: Test Pruning with Replica Adjustment

Ensure pruning maintains the Git-defined state by introducing and correcting a configuration drift.

  1. Increase Replicas Manually: Modify the deployment:
   kubectl scale deployment my-app -n staging --replicas=3
  1. Verify Increase:
   kubectl get deployment my-app -n staging
  • Expect 3 replicas.
  1. Reconcile: With deployment.yaml specifying replicas: 1, Flux will revert the change:
   flux reconcile kustomization my-app -n flux-system
  1. Verify Pruning:
   kubectl get deployment my-app -n staging
  • Expect 1 replica, confirming Git state enforcement.

Step 11: Troubleshoot

Address issues to ensure a reliable GitOps pipeline.

  • Bootstrap Issues:
    • Verify GITHUB_TOKEN has repo scope: curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user.
    • Confirm network access and repository settings.
  • GitRepository Problems:
    • Validate repository URL and branch.
    • Check status: kubectl describe gitrepository my-app -n flux-system.
  • Kustomization Errors:
    • Ensure path: ./kubernetes/manifests exists in app-repo.
    • Review logs: kubectl logs -n flux-system -l app=kustomize-controller.
  • Update or Pruning Failures:
    • Confirm prune: true in apps.yaml.
    • Inspect events: kubectl describe kustomization my-app -n flux-system.

FluxCD: Transforming Kubernetes with GitOps

FluxCD redefines Kubernetes application management by leveraging GitOps, DevSecOps, CD pipeline, and DevOps principles. With a compact /flux-config structure, it automates deployments, ensuring consistency, security, and collaboration for any application.

  • GitOps: FluxCD establishes Git as the single source of truth, synchronizing manifests from /app-repo. Updating an image from nginx:1.14.2 to 1.18.0 illustrates automated deployment, while pruning replicas from 3 to 1 enforces the declared state, enhancing traceability and control.

  • DevSecOps: Security is integrated through Git’s access controls and Flux’s pull-based synchronization, reducing manual cluster interactions. Declarative configurations enable early validation, supporting DevSecOps’ emphasis on secure development and operations.

  • CD Pipeline: FluxCD’s continuous polling drives seamless updates, automating changes like image tag updates without manual intervention, accelerating delivery for modern applications.

  • DevOps: Centralized Git configurations unite development and operations teams, while automated synchronization and pruning minimize operational effort, reflecting DevOps’ focus on collaboration and efficiency.

FluxCD delivers a robust, secure, and automated GitOps framework, empowering teams to manage Kubernetes applications with confidence and precision.