G
GuideDevOps
Lesson 4 of 10

FluxCD

Part of the GitOps tutorial series.

What is Flux?

While ArgoCD dominates the visual/"UI-first" crowd, Flux is the favorite for hardcore DevOps engineers who prefer CLI tooling and minimal footprints.

Created by Weaveworks (the company that originally coined the term "GitOps"), Flux is also a CNCF Graduated project.

Flux vs ArgoCD

  • ArgoCD stores all its application configurations in a centralized UI/Database. It was designed originally for managing multiple different clusters from one massive pane of glass.
  • Flux is radically decentralized. It installs tiny, distinct micro-controllers into the cluster. It has no native web UI (though community ones exist). Its configuration is managed entirely by standard Kubernetes Custom Resource Definitions (CRDs).

The Core Flux Controllers

Flux is not a single monolith. It is a collection of specific controllers (the GitOps Toolkit) that do one tiny job perfectly.

1. Source Controller

The Source Controller's only job is to connect to external systems (GitHub, GitLab, Helm Repositories, S3 buckets), download the raw configuration files, and package them into standardized artifacts.

# A Flux GitRepository Source Definition
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 1m # Check Git every 60 seconds
  url: https://github.com/stefanprodan/podinfo
  ref:
    branch: master

2. Kustomize Controller

Once the Source Controller pulls the YAML files from Git, the Kustomize Controller reads them, evaluates any kustomization.yaml logic, and aggressively reconciles them into the Kubernetes cluster using Server-Side Apply.

# A Flux Kustomization Definition
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 5m # Reconcile every 5 minutes
  path: "./kustomize"
  prune: true # Delete stale resources
  sourceRef:
    kind: GitRepository
    name: podinfo

Bootstrapping Flux

Flux has the most elegant installation process in the industry, utilizing the flux bootstrap CLI command.

When you run bootstrap, Flux does something deeply meta: It writes its own installation manifests into your Git repository, and then syncs ITSELF from Git.

  1. You install the Flux CLI on your laptop.
  2. You provide it a GitHub Personal Access Token.
  3. You run the command:
flux bootstrap github \
  --owner=my-github-username \
  --repository=my-cluster-config \
  --branch=main \
  --path=clusters/production \
  --personal

What exactly did this command do?

  1. It connected to GitHub and literally created a real repository named my-cluster-config using your account.
  2. It wrote the YAML files required to install Flux into the clusters/production/flux-system/ folder in that repo.
  3. It pushed the code to the main branch.
  4. It installed the Flux operator onto your active Kubernetes cluster.
  5. It configured the Flux operator to point at the GitHub repo and folder.

From this exact moment forward, the cluster is strictly managing itself via GitOps. If you want to upgrade Flux to a newer version, you do not run a CLI command. You edit the Flux version number in the GitHub repository, and Flux upgrades itself!


Managing Helm Releases with Flux

While GitOps strongly pushes plain YAML, the industry runs on Helm charts. Flux handles Helm beautifully via the Helm Controller.

Instead of running helm install manually, you commit two files to Git:

  1. HelmRepository (telling Flux where the external chart lives).
  2. HelmRelease (telling Flux what version of the chart to install, and providing your custom values.yaml overrides).
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: backend-redis
  namespace: default
spec:
  interval: 5m
  chart:
    spec:
      chart: redis
      version: '17.3.x'  # Semantic versioning supported!
      sourceRef:
        kind: HelmRepository
        name: bitnami
  values:
    # Your standard Helm values.yaml injected here
    architecture: standalone
    auth:
      enabled: false

Because the HelmRelease acts as a declarative wrapper around Helm, it forces traditional Helm deployments to conform to the strict rules of GitOps immutability.