Build Kubernetes Cluster from Scratch
From Scratch
Section titled “From Scratch”Use this guide to rebuild a homelab cluster from bare metal or new VM images using this repo as the source of truth.
Step 1: Prepare the workstation
Section titled “Step 1: Prepare the workstation”Follow Prerequisites to install tooling and update the Ansible inventory.
Step 2: Provision nodes with Ansible
Section titled “Step 2: Provision nodes with Ansible”Run the provisioning playbook from the repo root:
ansible-playbook -i ansible/inventory/hosts.yaml \ ansible/playbooks/provision-cpu.yaml \ -e @ansible/group_vars/all.yamlIf you need GPU support, use the GPU playbooks in ansible/playbooks/.
Step 3: Initialize the control plane
Section titled “Step 3: Initialize the control plane”Run on the control plane node. Pick a pod CIDR that does not overlap your LAN or service CIDR. If you prefer to skip pinning a pod CIDR, omit --pod-network-cidr and keep the Cilium defaults.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configkubectl taint nodes --all node-role.kubernetes.io/control-plane-If you want OIDC for Headlamp, follow the optional OIDC section in Kubernetes before the first kubeadm init.
Step 4: Install Cilium
Section titled “Step 4: Install Cilium”Update the control plane IP in infrastructure/cilium/values.cilium, then install Cilium:
CILIUM_VERSION=$(grep -E "cilium_version:" ansible/group_vars/all.yaml | head -n 1 | awk -F'"' '{print $2}')cilium install --version $CILIUM_VERSION --values infrastructure/cilium/values.ciliumStep 5: Install ArgoCD and bootstrap GitOps
Section titled “Step 5: Install ArgoCD and bootstrap GitOps”kubectl apply -k bootstrap/argocdkubectl wait --for=condition=available --timeout=600s deployment/argocd-server -n argocdkubectl apply -f bootstrap/root.yamlStep 6: Configure Vault and External Secrets
Section titled “Step 6: Configure Vault and External Secrets”Follow Vault to initialize Vault and create the required secrets for ExternalDNS, cert-manager, and the Tailscale operator.
Step 7: Validate the cluster
Section titled “Step 7: Validate the cluster”kubectl get nodeskubectl get pods -Akubectl get apps -n argocdLocal rehearsal (Multipass)
Section titled “Local rehearsal (Multipass)”Use this for a local dry run before touching hardware. To keep resources low, set a single-node cluster and smaller VM sizing. If resources are tight, disable Hubble UI and Relay for the rehearsal:
WORKER_COUNT=0 VM_CPUS=2 VM_MEMORY=3G VM_DISK=12G CILIUM_HUBBLE_ENABLED=false ./scripts/local-cluster.sh upDestroy the rehearsal cluster when done:
./scripts/local-cluster.sh down