Provisioning K8s clusters
My method to bring a local-first, on-premises Kubernetes cluster to life quickly using the pairing of virtualistion and Kubespray.
Note that quickly does not mean its the fastest way to deploy a cluster. There are many Kubernetes environments available to you. See types.
This section includes preparing hosts, creating a resilient Virtual IP (VIP) for the Kubernetes API, and using Kubespray to bootstrap the cluster. Ingress is provided by Ingress-NGINX with a MetalLB service that are documented in other sections of the Sphere.
If you already have an operational Kubernetes cluster, this section may still be useful if you’re interested in building a cluster with Kubespray.
What this covers
- Preparation. Subnets and host addressing, a clean Ubuntu VM template you can clone, and DNS entries that keep names consistent on your LAN. See preparation.
- Load balancers (API only). Keepalived for VIP failover and HAProxy for TCP pass-through to the Kubernetes API. Note that this VIP is not used for ingress. See load balancers.
- Kubespray. The Ansible playbooks I use to create the cluster. Inventory examples and the exact commands to run. See kubespray.
Prerequisites
- A working hypervisor or hardware for your nodes (for example, I use Parallels for the initial development cluster, then switch to a hybrid setup using an old computer later).
- Ubuntu LTS on each node with a static IPv4 address and SSH access.
- Local DNS or
/etc/hostsentries that resolve every hostname and FQDN. - A service CIDR and a pod CIDR reserved in your design, with room to grow.
Provisioning flow at a glance
- Prepare hosts. Build a base VM template, clone per role, and assign static IPs and hostnames. Confirm DNS resolution and SSH access.
- Create the API VIP. Configure Keepalived and HAProxy on two small nodes. Verify failover and that the Kubernetes API is reachable via the VIP. Skip ingress here.
- Bootstrap with Kubespray. Build an inventory to match your hosts, choose sensible defaults, and run the Ansible playbooks to create the cluster.
- Smoke tests. Confirm
kubectl get nodes, deploy a trivial service, and check ingress via the MetalLB-assigned address.
Pages in this section
- Preparation. Subnets, VM template, and DNS. Short steps you can repeat quickly.
- Load balancers. Keepalived + HAProxy configs for a simple API VIP. Includes verification commands.
- Kubespray. Repo setup, Python requirements, inventory examples, and the playbooks to run.
Verification
ssh <host>to each node to confirm access.nc -vz <vip> 8443orcurl -sk https://<vip>:8443/healthzto check API reachability through HAProxy.kubectl get nodesandkubectl -n kube-system get podsto confirm a healthy control plane.
Rollback and rebuild
- Because each step is scripted, you can safely rebuild: destroy clones, recreate from the VM template, and rerun Kubespray.
- Keep configuration files for Keepalived, HAProxy, and Kubespray inventory in version control so changes are clear and reversible.
Next up
Once the cluster is healthy, move on to cluster add-ons (container network interface (CNI), metrics, ingress controller), storage (CSI), and backups. The goal remains the same: fit for purpose, automatic where it helps, observable, and reversible.