Flux GitOps is all about getting your Kubernetes deployments managed by Git, and the most surprising thing is how much less you end up thinking about deployments once it’s set up.
Let’s see it in action. Imagine you have a simple web app. We’ll define its Kubernetes deployment and service manifests in YAML, like this:
# clusters/my-cluster/app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-webapp
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: my-webapp
template:
metadata:
labels:
app: my-webapp
spec:
containers:
- name: webapp
image: nginx:1.21.6
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-webapp-svc
namespace: default
spec:
selector:
app: my-webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
This app.yaml file lives in a Git repository. Now, Flux needs to know about this repository and what to do with it. We configure Flux itself using a Kustomization resource, which tells Flux to watch a specific path within our Git repo and apply any YAML found there to our Kubernetes cluster.
# flux-system/gotk-sync.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: flux-kustomization
namespace: flux-system
spec:
interval: 10m
path: ./clusters/my-cluster
prune: true
sourceRef:
kind: GitRepository
name: flux-repo
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: flux-repo
namespace: flux-system
spec:
interval: 5m
url: ssh://git@github.com/your-org/your-gitops-repo.git
ref:
branch: main
When Flux starts up in your cluster, it will first create a GitRepository object, which points to your Git repo. Then, it will create a Kustomization object, which references that GitRepository. Flux will then periodically (every 10 minutes in this example) clone the Git repository, navigate to the ./clusters/my-cluster directory, and apply all the YAML files it finds there to your cluster. If you change the nginx image tag in app.yaml and commit it, Flux will detect the change on its next sync and update your deployment. The prune: true setting means that if you delete a resource from Git, Flux will also delete it from the cluster.
The problem this solves is the inherent drift between your declared state (what’s in Git) and your actual cluster state. Manually applying changes, running kubectl edit, or using imperative commands (kubectl scale) leads to a state where Git no longer accurately reflects what’s running. GitOps, with Flux, enforces that Git is the single source of truth. Any change to your cluster’s desired state must go through a Git commit.
Internally, Flux has several controllers: Source Controller handles fetching manifests from Git, Helm repositories, or S3 buckets. Kustomize Controller applies these manifests to your cluster, reconciling the desired state in Git with the actual state in Kubernetes. Notification Controller can send alerts about sync failures or other events. Image Reflector Controller and Image Automation Controller can watch container registries for new image tags and automatically update your Git manifests, which then triggers Flux to deploy the new version.
The exact levers you control are primarily within your Git repository. You define the desired state of your applications, infrastructure, and configurations in YAML files. Flux then ensures your cluster matches that state. You configure Flux itself via Kustomization and GitRepository (or other source) objects within the cluster, telling it where to find your manifests and how often to check for updates. You can also configure Flux to automatically update manifests based on new container image tags in your registry.
A common misconception is that GitOps means you never touch kubectl. While the goal is to minimize direct kubectl use for deployments and configuration, kubectl remains invaluable for debugging and understanding the current state of your cluster, especially when things go wrong. You’ll still use it to inspect pods, services, and events to diagnose issues that GitOps itself might be flagging.
The next concept you’ll likely explore is advanced GitOps workflows, like multi-cluster management and progressive rollouts using tools integrated with Flux.