Configuring Automated Deployment to a Kubernetes Cluster Using GitOps Flux CD
Deploy an application on a Kubernetes Cluster using Flux and GitOps principles
Step 1: Install Git
sudo apt update && sudo apt install -y git
git --version
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
Step 2: Create a GitHub Repository
Create a GitHub Repository to track all the cluster configuration files.
Step 3: Install the Flux CLI
Run the following command to install flux cli on your node:
curl -s https://fluxcd.io/install.sh | sudo bash
Check the installation:
flux --version
Step 4: Create a GitHub Personal Access Token
GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
Click Generate new token (classic), add a note for what the token is for (like homelab-gitops).
Select scopes for: repo and click Generate token. And then Copy the token.
Export the token value as an environment variable in your cluster:
export GITHUB_TOKEN=<token>
Step 5: Install Flux and Its Components Using Flux Bootstrap
Flux can bootstrap itself and link our cluster to our Git repository.
This is how flux bootstrap command works:
Uses the GitHub Personal Access Token (PAT) to connect to the GitHub repository.
Clones the GitHub repository and switches to the
mainbranch.Generates manifests (YAML files) for all the required Flux components.
Commits and pushes the Flux system manifests to the repository at
clusters/my-cluster/flux-systemInstalls Flux components in our cluster in the
flux-systemnamespace.Outputs the public key that will be used as the deploy key in the cluster. Flux uses this deploy key to continuously access our repository (instead of the PAT) to pull the state of the cluster.
Run this on cluster:
flux bootstrap github \
--token-auth=false \
--owner=<GITHUB_USERNAME> \
--repository=<REPO_NAME> \
--branch=main \
--path=clusters/my-cluster \
--read-write-key=true \
--components-extra='image-reflector-controller,image-automation-controller'
Command explanation:--token-auth=false : this means Flux will Use PAT only once, Create SSH deploy key and Use SSH afterwards.
--owner=<GITHUB_USERNAME> : Specifies the owner of the GitHub repository.
--repository=<REPO_NAME> : The GitHub repository name where Flux will store the GitOps configuration.
--branch=main : Specifies the Git branch Flux will watch and sync from.
--path=clusters/my-cluster : Defines where inside the repo the cluster manifests are located. Flux installs itself using the manifests inside this folder. my-cluster is our cluster name. We can include multiple clusters under the clusters folder.
--read-write-key=true : Write access is required so Flux Image Automation can automatically update image tags in the manifests.
--components-extra='image-reflector-controller,image-automation-controller' : This installs additional Flux controllers which are not installed by default for automatic container image updates.
Verify that Flux components are running:
k get pods -n flux-system
Get the status of the GitRepository sources:
## List all Git repositories and their status
flux get sources git
Step 6: Structure the repository
We'll follow Flux’s recommended repository structure, organizing our files into separate directories for apps, base configurations, environment-specific configurations (staging, production) and infrastructure configurations (configs, controllers).
We'll use the monorepo approach. Run this locally:
git clone <GITHUB_REPO_URL>
cd <REPO_NAME>
## Create the directory structure for applications and infrastructure
mkdir -p apps/{base,staging,production}
mkdir -p infrastructure/{configs,controllers}
Step 7: Deploy an Application using Flux
Let us use GitOps to deploy the mealie application.
We will create several YAML files:
namespace.yaml: a dedicated namespace for the application
deployment.yaml: kubernetes deployment for the application
kustomization.yaml files: Here we'll define resources and configurations for the application
apps.yaml: This tells Flux to look at the
apps/stagingdirectory
Create a mealie directory for our mealie application at apps/base. Then go to apps/base/mealie directory and create these yaml files:
namespace.yaml :
apiVersion: v1
kind: Namespace
metadata:
name: mealie
deployment.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mealie
name: mealie
namespace: mealie
spec:
replicas: 1
selector:
matchLabels:
app: mealie
template:
metadata:
labels:
app: mealie
spec:
containers:
- image: ghcr.io/mealie-recipes/mealie:v3.12.0
name: mealie
ports:
- containerPort: 9000
kustomization.yaml :
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mealie
resources:
- deployment.yaml
- namespace.yaml
Now go to the apps/staging directory and create a mealie directory for our mealie application. And under apps/staging/mealie directory create:
kustomization.yaml :
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mealie
resources:
- ../../base/mealie
Then Go to clusters/my-cluster directory and create the apps.yaml file.
apps.yaml :
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 60s
sourceRef:
kind: GitRepository
name: flux-system
path: ./apps/staging
prune: true
wait: true
Now commit and push these newly created files to our GitHub repo.
git add .
git commit -m "Add mealie application manifests"
git push origin main
Flux will detect these changes and automatically apply the manifests to the cluster.
This is how our repo structure would look like:
clusters/
my-cluster/
flux-system/
apps.yaml
apps/
base/
mealie/
deployment.yaml
namespace.yaml
kustomization.yaml
staging/
mealie/
kustomization.yaml
production/
infrastructure/
controllers/
configs/
Let's understand the path Flux follows to deploy our application:
Flux reads the
clusters/my-clusterdirectory.Finds and applies our
apps.yamlfile.The
apps.yamlfile tells Flux to look at theapps/stagingdirectory.Finds our Mealie application kustomization file.
Applies the resources we defined in the base configuration.
apps.yaml
▼
apps/staging
▼
apps/base
▼
mealie manifests
(deployment, namespace)
Step 8: Verify that Flux Applied the Application Manifests
After pushing the changes, Flux will pull the updated configuration and apply the resources to the cluster.
Check the Flux Kustomizations:
flux get kustomizations
Also Check the resources created by Flux:
k get ns
k get all -n mealie
If everything worked correctly, you should see the Mealie namespace, Mealie pod and deployment running in that namespace.