Kubernetes GitOps with FluxCD - Part 1 - Initial Setup
Table of Contents
GitOps practice enables us to define our infrastructure as code in a declarative manner. It serves as an audited single source of truth for our cloud/cluster state, providing benefits like:
- Version control and audit trails for infrastructure changes
- Automated reconciliation between desired and actual states
- Improved security through encrypted credentials and access control
- Simplified rollback capabilities
- Enhanced collaboration through Git workflows
FluxCD is a CNCF graduated project that enables GitOps practices in the Kubernetes ecosystem. It automates the deployment, monitoring, and reconciliation of cluster resources based on Git repositories.
This post covers the initial setup and core functionality of FluxCD in a Kubernetes cluster.
1. Setup Git dependencies
Lets start by creating git repository in Github.
Next, we need to generate a fine-grained access token that FluxCD will use to interact with our repository. These tokens provide more granular control over repository permissions compared to classic personal access tokens.
We’ll keep Read and write
permission for Administration
, Contents
access and Read-only
for Metadata
access limited to repository we created above and permissions as recommeded by official FluxCD documentation for this initial setup.
2. Setup Flux CLI
Lets start by installing FluxCD cli
sudo zypper in flux2-cli
Next step is to export github token and user details variables.
export GITHUB_TOKEN=******
export GITHUB_USER=*****
For this post we are using locally VM hosted k3s cluster, lets check if we have access to same with kubectl
.
# 1. Point to specific cluster we are setting up
export KUBECONFIG=~/.kube/local.config
# 2. Check for access and version
kubectl version
Let’s check same with Flux cli if it has access as well.
flux check --pre
3. Bootstrap FluxCD
We are going to install all components including extra for image automation.
flux bootstrap github \
--owner=$GITHUB_USER \
--repository=k8s-gitops \
--branch=main \
--path=./cluster/default \
--read-write-key \
--components source-controller,kustomize-controller,helm-controller,notification-controller \
--components-extra image-reflector-controller,image-automation-controller \
--personal
Lets verify Flux setup step by step.
- Bootstrap has created one deployment key in Github repository and stored as flux-system/flux-secret
Let’s verify deployment key in Github
Let’s verify secret with kubectl -n flux-system get secrets
- Flux has initialized the repository with initial commit having definition of components at
cluster/default
as specified bootstrap command.
- FluxCD reconclided with Git repository and installed the components in
flux-system
namespace, lets verify same withkubectl
4. Verify installation
Lets verify our installation by creating a sample deployment.
apps/nginx/deployment.yaml
apiVersion: apps/v1
metadata:
name: nginx-deployment
namespace: default
kind: Deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "64Mi"
cpu: "50m"
apps/nginx/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
cluster/default/nginx.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: nginx
namespace: flux-system
spec:
interval: 5m
path: ./apps/nginx
prune: true
retryInterval: 2m
sourceRef:
kind: GitRepository
name: flux-system
targetNamespace: default
timeout: 3m
wait: true
The Kustomization resource has several important fields:
interval
: How often Flux should reconcile this resource (5m = 5 minutes)path
: Directory containing the Kubernetes manifestsprune
: Whether Flux should delete resources that are no longer defined in GitretryInterval
: How long to wait between retries if reconciliation failswait
: Whether Flux should wait for resources to be ready before completing reconciliationtimeout
: Maximum time to wait for reconciliation
Lets push these changes and wait for reconciliation to finish.
Lets verify if nginx is deployed
5. What if
One of the core goals of GitOps is ensuring that our cluster’s state always matches the resources defined in our git repository. This continuous reconciliation process is what makes GitOps powerful for maintaining system consistency.
To demonstrate this functionality, we’ll delete our nginx deployment using kubectl and observe how Flux’s reconciliation process automatically restores it to the desired state defined in Git. This showcases the “self-healing” capability of the GitOps approach.
In screen above:
- First step is to verify the deployment with
kubectl get deployments
to check if nginx is up and running - Second step is to delete deployment with
kubectl delete deployment/nginx-deployment
- 3rd step to confirm nginx deployment is deleted with
kubectl get deployment
- 4th step is to watch over FluxCD reconciliation to kick in
- 5th step to verify that nginx is re-deployed post Flux’s reconciliation
What next ?
Future posts will explore advanced GitOps patterns with FluxCD, including:
- Helm chart automation
- Image update automation
- Notification and alerting configuration
- Secrets management with SOPS
Stay tuned for each of these topics.
References
- Official FluxCD Documentation - https://fluxcd.io/flux/
- GitOps Working Group - https://opengitops.dev
- Kubernetes Documentation - https://kubernetes.io/docs/