This quickstart guide will walk you through setting up a Kubernetes cluster from scratch with Cilium CNI and FluxCD GitOps. By the end, you’ll have a fully functional cluster with automatic synchronization from your Git repository.
Prerequisites
Before you begin, ensure you have:
A Linux machine with root access
Basic familiarity with Kubernetes concepts
A GitHub account and repository for your Flux configuration
GitHub Personal Access Token with repo permissions
System Preparation
Enable IP forwarding
IP forwarding is required for Kubernetes networking: # Permanent configuration
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Disable swap
Kubernetes requires swap to be disabled: sudo swapoff -a
sudo sed -i '/swap/s/^/#/' /etc/fstab
sudo systemctl mask swap.target
# Verify swap is disabled
swapon --show
Configure containerd
Create or modify /etc/containerd/config.toml: sudo containerd config default > /etc/containerd/config.toml
Update the configuration to enable SystemdCgroup: version = 2
[ plugins ]
[ plugins . "io . containerd . grpc . v1 . cri" ]
[ plugins . "io . containerd . grpc . v1 . cri" . containerd ]
[ plugins . "io . containerd . grpc . v1 . cri" . containerd . runtimes ]
[ plugins . "io . containerd . grpc . v1 . cri" . containerd . runtimes . runc ]
runtime_type = "io.containerd.runc.v2"
[ plugins . "io . containerd . grpc . v1 . cri" . containerd . runtimes . runc . options ]
SystemdCgroup = true
Restart containerd: sudo systemctl restart containerd
Install Kubernetes Components
Install kubeadm, kubelet, and kubectl
Install Kubernetes v1.33.0: sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# Add Kubernetes apt repository
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
# Install specific version
sudo apt-get update
sudo apt-get install -y kubelet=1.33.0-1.1 kubeadm=1.33.0-1.1 kubectl=1.33.0-1.1
sudo apt-mark hold kubelet kubeadm kubectl
Initialize the cluster
Replace 192.168.0.101 with your control plane node’s IP address. The --skip-phases=addon/kube-proxy flag is crucial because Cilium will replace kube-proxy.
sudo kubeadm init \
--skip-phases=addon/kube-proxy \
--apiserver-advertise-address=192.168.0.101 \
--pod-network-cidr= "10.1.0.0/16" \
--upload-certs
Configure kubectl access: mkdir -p $HOME /.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/config
sudo chown $( id -u ) : $( id -g ) $HOME /.kube/config
Add worker nodes (optional)
If you want to add worker nodes, use the kubeadm join command that was output from the kubeadm init command. It will look similar to: kubeadm join 192.168.0.101:6443 --token < toke n > \
--discovery-token-ca-cert-hash sha256: < has h >
Install Cilium CNI
Cilium provides advanced networking capabilities and replaces kube-proxy.
Install Cilium CLI
Download and install the Cilium CLI tool: CILIUM_CLI_VERSION = $( curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt )
CLI_ARCH = amd64
if [ "$( uname -m )" = "aarch64" ]; then CLI_ARCH = arm64 ; fi
curl -L --fail --remote-name-all \
https://github.com/cilium/cilium-cli/releases/download/ ${ CILIUM_CLI_VERSION } /cilium-linux- ${ CLI_ARCH } .tar.gz{,.sha256sum}
sha256sum --check cilium-linux- ${ CLI_ARCH } .tar.gz.sha256sum
sudo tar xzvfC cilium-linux- ${ CLI_ARCH } .tar.gz /usr/local/bin
rm cilium-linux- ${ CLI_ARCH } .tar.gz{,.sha256sum}
Install Cilium with Gateway API support
Replace 192.168.0.101 with your control plane node’s IP address.
cilium install \
--set kubeProxyReplacement= true \
--set k8sServiceHost= 192.168.0.101 \
--set k8sServicePort= 6443 \
--set nodePort.enabled= true \
--set gatewayAPI.enabled= true
This configuration:
Enables kube-proxy replacement
Configures the API server address
Enables NodePort support
Enables Gateway API support for advanced ingress capabilities
Verify Cilium installation
Wait for Cilium to be ready: You should see output indicating all components are healthy.
Bootstrap FluxCD
FluxCD will continuously synchronize your cluster state with your Git repository.
Set up your GitHub repository
Make sure you have:
A GitHub repository (can be private or public)
A GitHub Personal Access Token with repo permissions
Your repository contains the FluxCD configuration structure
Bootstrap Flux
Replace the placeholders with your actual GitHub username, repository name, and path to the cluster configuration.
export GITHUB_TOKEN = "<your-github-token>"
flux bootstrap github \
--owner= < your-github-username > \
--repository= < your-repo-name > \
--private=false \
--personal=true \
--path=cluster/kimawesome \
--token-auth=false \
--read-write-key=true \
--components-extra= 'image-reflector-controller,image-automation-controller'
This command:
Creates a deploy key in your repository
Installs FluxCD components in the cluster
Sets up continuous synchronization
Includes image automation controllers for automatic image updates
Verify Flux installation
Check that all Flux components are running: flux check
kubectl -n flux-system get pods
You should see pods for:
source-controller
kustomize-controller
helm-controller
notification-controller
image-reflector-controller
image-automation-controller
Monitor synchronization
Watch Flux synchronize your cluster: flux get kustomizations --watch
This will show the status of all Kustomizations being applied to your cluster.
Verify Your Cluster
Check node status
All nodes should show Ready status.
Check Flux resources
kubectl get gitrepositories -A
kubectl get kustomizations -A
kubectl get helmreleases -A
These commands show the GitOps resources that Flux is managing.
View cluster components
You should see pods in various namespaces including:
flux-system - FluxCD controllers
kube-system - Kubernetes system components and Cilium
Next Steps
Now that your cluster is running with FluxCD, you can:
Configure Infrastructure Set up MetalLB, cert-manager, and other infrastructure components
Deploy Applications Deploy your applications using GitOps workflows
Manage Secrets Configure sealed-secrets for secure secret management
Set Up Monitoring Deploy the Grafana stack for observability
Troubleshooting
Check Cilium status: cilium status
cilium connectivity test
Review Cilium logs: kubectl -n kube-system logs -l k8s-app=cilium
Check Flux logs: flux logs --all-namespaces
Verify Git repository access:
Common issues:
Ensure swap is disabled: swapon --show
Check if ports 6443, 10250, 10259, 10257 are available
Verify containerd is running: sudo systemctl status containerd
View kubeadm logs:
Reference Configuration
The repository structure used in this guide:
.
├── cluster/
│ └── kimawesome/
│ ├── flux-system/ # Flux system components
│ ├── kustomization.yaml # Cluster-level kustomization
│ └── kustomization.flux.yaml # Overlay kustomization
├── overlays/
│ ├── base/ # Base configurations
│ │ ├── cert-manager/
│ │ ├── metallb/
│ │ ├── sealed-secrets/
│ │ ├── kgateway/
│ │ └── grafana/
│ └── kimawesome/ # Environment-specific overlays
│ ├── infrastructure/
│ ├── applications/
│ └── site/
└── cilium-values.yaml # Cilium configuration
The kustomization.flux.yaml in your cluster directory points to the overlays for your environment, enabling GitOps management of all infrastructure and applications.