DEV Community

Uchechukwu Enyi
Uchechukwu Enyi

Posted on

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:
    • <github-username>/flux-config: Stores Flux configurations.
    • <github-username>/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
Enter fullscreen mode Exit fullscreen mode
  1. Initialize Git Repository: Set up a local Git repository for configuration management:
   git init
   git branch -M main
Enter fullscreen mode Exit fullscreen mode
  1. Configure GitHub Credentials: Set environment variables for authentication, replacing <github-username> and <your-token> with your GitHub credentials:
   export GITHUB_USER=<github-username>
   export GITHUB_TOKEN=<your-token>
Enter fullscreen mode Exit fullscreen mode
  1. Verify Cluster Compatibility: Confirm the cluster is ready for Flux:
   flux check --pre
Enter fullscreen mode Exit fullscreen mode
  • 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 <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
Enter fullscreen mode Exit fullscreen mode

Steps:

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

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/<github-username>/app-repo
     ref:
       branch: main
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  • 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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • Creates or updates <github-username>/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
Enter fullscreen mode Exit fullscreen mode
  • 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/<github-username>/app-repo.git
   cd app-repo
   mkdir -p kubernetes/manifests
Enter fullscreen mode Exit fullscreen mode
  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
Enter fullscreen mode Exit fullscreen mode
  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
Enter fullscreen mode Exit fullscreen mode
  1. Commit and Push:
   git add .
   git commit -m "Add my-app manifests"
   git push origin main
Enter fullscreen mode Exit fullscreen mode

Step 7: Create Namespace

Ensure the staging namespace is present:

kubectl create namespace staging --dry-run=client -o yaml | kubectl apply -f -
Enter fullscreen mode Exit fullscreen mode

Step 8: Verify Deployment

Confirm Flux has correctly applied the manifests.

  1. Check GitRepository:
   flux get sources git my-app -n flux-system
Enter fullscreen mode Exit fullscreen mode
  • Expect Ready: True, indicating repository sync.
  1. Check Kustomization:
   flux get kustomizations my-app -n flux-system
Enter fullscreen mode Exit fullscreen mode
  • Expect Ready: True, confirming manifest deployment.
  1. Verify Resources:
   kubectl get deployments,services -n staging
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  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
Enter fullscreen mode Exit fullscreen mode
  1. Reconcile (Optional): Accelerate the update:
   flux reconcile kustomization my-app -n flux-system
Enter fullscreen mode Exit fullscreen mode
  1. Verify Update: Inspect running pods:
   kubectl get pods -n staging -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  1. Verify Increase:
   kubectl get deployment my-app -n staging
Enter fullscreen mode Exit fullscreen mode
  • Expect 3 replicas.
  1. Reconcile: With deployment.yaml specifying replicas: 1, Flux will revert the change:
   flux reconcile kustomization my-app -n flux-system
Enter fullscreen mode Exit fullscreen mode
  1. Verify Pruning:
   kubectl get deployment my-app -n staging
Enter fullscreen mode Exit fullscreen mode
  • 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 <github-username>/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.

Top comments (0)