Single-node Kubernetes cluster on local VMs.
Terraform → Ansible → Kubernetes
- Single Debian VM (4 vCPU / 4 GB RAM / 40 GB disk)
- Kubernetes v1.36.0 with Flannel CNI
- Fully automated: cloud-init → running cluster
- containerd runtime with systemd cgroup driver
- One-command deployment
| Component | Command |
|---|---|
| Hardware virtualization | lscpu | grep Virtualization |
| Libvirt + QEMU | sudo systemctl status libvirtd |
Host bridge (br0) |
nmcli con show | grep bridge |
sudo nmcli con add type bridge ifname br0
sudo nmcli con add type bridge-slave ifname eth0 master br0
sudo nmcli con up br0# 1. Configure
cp tf/terraform.tfvars.example tf/terraform.tfvars
# Edit tf/terraform.tfvars with: prefix, node_ip, bridge_interface, etc.
# 2. Deploy (full cycle: init → apply → wait → ansible → kubeconfig)
make install| Command | Description |
|---|---|
make install |
Full cycle: init → apply → wait → ansible → kubeconfig |
make init |
Initialize Terraform providers |
make plan |
Show Terraform plan |
make apply |
Apply Terraform changes |
make wait |
Wait for VM SSH availability |
make ansible |
Run Kubernetes setup |
make kubeconfig |
Copy kubeconfig from node |
make destroy |
Destroy all resources |
make check |
Verify cluster with kubectl |
make clean |
Remove generated files |
Or use ./deploy.sh with same targets for backwards compatibility.
export KUBECONFIG=~/.kube/single-node-config
kubectl get nodesExpected output:
NAME STATUS ROLES AGE
single Ready control-plane 2m
┌─────────────────────────────────────────────┐
│ Host Machine │
│ ┌───────────────────────────────────────┐ │
│ │ Libvirt (KVM) │ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ Debian 12 VM (single) │ │ │
│ │ │ ┌───────────────────────────┐ │ │ │
│ │ │ │ Kubernetes Control Plane │ │ │ │
│ │ │ │ + Worker │ │ │ │
│ │ │ │ ┌─────────────────────┐ │ │ │ │
│ │ │ │ │ containerd │ │ │ │ │
│ │ │ │ │ + Flannel CNI │ │ │ │ │
│ │ │ │ │ + kubelet │ │ │ │ │
│ │ │ │ └─────────────────────┘ │ │ │ │
│ │ │ └───────────────────────────┘ │ │ │
│ │ └─────────────────────────────────┘ │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
▲ ▲
Terraform Ansible
(provision) (configure)
| Component | Tool |
|---|---|
| VM provisioning | Terraform + libvirt |
| OS setup | Ansible + cloud-init |
| Container runtime | containerd |
| Pod networking | Flannel (10.244.0.0/16) |
| Node IP | Configurable via node_ip in terraform.tfvars |
make destroy
make clean| Path | Description |
|---|---|
Makefile |
Deployment commands |
tf/ |
Terraform configuration |
roles/k8s_single/ |
Ansible role for K8s setup |
playbook.yaml |
Ansible playbook |
deploy.sh |
Legacy deployment script (wraps Make) |
Built with Terraform, Ansible, and ☸️