K3s on Proxmox: Build a Lightweight Kubernetes Cluster
K3s on Proxmox is a practical way to learn Kubernetes or run non-critical services on a home server: Proxmox provides virtual machines, and K3s runs a lightweight Kubernetes distribution inside Linux guests. The design is straightforward, but reliable networking, persistent storage, backups, and failure domains still need deliberate choices. This guide walks through a small deployment and explains what it does—and does not—make highly available.
What Is K3s on Proxmox?
K3s is a lightweight, certified Kubernetes distribution maintained by Rancher. It packages the Kubernetes control plane, container runtime, networking defaults, and other components behind a relatively simple installation and service model. Its installation requirements describe supported systems, resource considerations, and network access.
Proxmox Virtual Environment is a platform for managing virtual machines, Linux containers, storage, and networks. In this design, Proxmox runs one or more Linux VMs; K3s runs inside those guests and schedules application containers as Kubernetes Pods. The Proxmox VE Administration Guide documents its virtual networking, guest, and storage options.
Using a full VM gives each Kubernetes node its own guest kernel and a familiar Linux environment. It also keeps Kubernetes upgrades and configuration inside the guest instead of mixing them with the Proxmox host. For most homelabs, that separation is easier to reason about than running a Kubernetes node inside an LXC container.
Why Run It This Way?
Proxmox and K3s solve different problems. Proxmox consolidates physical machines into manageable guests; Kubernetes coordinates containerized applications across nodes. A K3s cluster can use the same host that already runs a NAS, test VMs, or development services, while keeping the cluster’s operating system and workload lifecycle separate from the hypervisor.
The combination is useful for learning Kubernetes without immediately buying several physical machines. It also makes it easy to create, back up, clone, or rebuild a lab node. Those conveniences do not remove the need for capacity planning: VMs still compete for the physical host’s CPU, memory, disk I/O, and network bandwidth.
Keep the first deployment proportionate to the goal. If the aim is to learn Kubernetes objects or run a few home services, one K3s server VM is enough. Add more nodes to practice scheduling or to explore control-plane redundancy only when the hardware and recovery plan support them.
How the Architecture Works
The physical Proxmox host supplies CPU, memory, disks, and network interfaces. A Linux VM receives virtual CPU cores, RAM, a virtual disk, and a virtual network interface. K3s runs in that VM as a system service; its container runtime launches Pods, while the Kubernetes API and controllers manage desired state.
On one VM, the K3s server also acts as a schedulable node by default, so it can run application Pods. In a multi-node setup, agent VMs join a server and provide more places for workloads to run. The K3s Quick-Start guide explains the server-and-agent installation model.
The network has distinct layers. A Proxmox Linux bridge such as vmbr0 connects a VM’s virtual NIC to a physical LAN or VLAN. Inside the guest, K3s provides Pod networking and Kubernetes Services. The cluster’s default Pod and Service address ranges must not conflict with the LAN, a VPN, or routes used elsewhere. RFC 1918 defines the private IPv4 ranges commonly used for those networks.
| Topology | Useful for | Main limitation |
|---|---|---|
| One K3s server VM | Learning, testing, and a small non-critical service | The VM and its Proxmox host are single failure points |
| One server VM plus agent VMs on one Proxmox host | Practicing multi-node scheduling and workload placement | A host outage still takes down every cluster node |
| Three server VMs distributed across Proxmox hosts | Exploring embedded-etcd control-plane availability | Requires multiple hosts, a stable API endpoint, and enough capacity to tolerate a failure |
Three VMs on one physical host can teach cluster operations, but they do not provide host-level resilience. For a failure-tolerant design, place server VMs on separate physical Proxmox nodes and plan for a stable registration/API endpoint. K3s embedded-etcd clusters use an odd number of server nodes so they can maintain quorum; extra agents alone do not make the control plane highly available.
Components and Design Choices
VM resources and placement
For a light single-node lab, start around 2 virtual CPU cores, 4 GiB of memory, and a 32–64 GiB virtual disk, then increase capacity to match the applications. These are practical starting values, not universal minimums. K3s resource use depends on enabled components and workload size, and the Proxmox host needs memory and CPU capacity of its own.
If using multiple VMs, assign stable addresses through DHCP reservations or static guest configuration. Consider CPU and memory overcommit carefully: a cluster cannot schedule around a host that is already starved of resources. Put control-plane VMs on separate physical hosts when host failure is part of the design, rather than relying only on Kubernetes labels or Proxmox HA settings.
Network and firewall
Connect each guest to an appropriate Proxmox bridge. A bridge attached to the LAN lets the VM receive a normal LAN address; a VLAN-aware bridge can carry a selected VLAN when the switch, bridge, and VM NIC are configured consistently. Keep the Proxmox management interface in its intended management network instead of exposing it to application workloads.
Allow only the traffic required by the selected K3s network configuration. In a common setup, agents need to reach the server’s Kubernetes API on TCP port 6443, and the default Flannel VXLAN backend uses UDP port 8472 between nodes. These are examples, not a complete firewall policy: the K3s requirements documentation lists the relevant rules, and a different CNI or backend changes what is needed. Do not expose cluster-only ports to the public internet.
Disks, volumes, and backups
The Proxmox datastore holds the VM’s virtual disk; Kubernetes persistent volumes are a separate layer. K3s commonly installs a local-path provisioner for simple persistent-volume claims, which stores data on the node’s filesystem. That is convenient for a lab, but a volume on one VM does not automatically move to another VM when a node fails.
Choose a Proxmox storage backend based on the host topology and recovery needs. Local ZFS or LVM-thin can work well for one host; Ceph can provide distributed storage in a properly sized Proxmox cluster. Neither a VM snapshot nor replicated storage is a complete application backup. Preserve Kubernetes configuration and back up application data to an independent destination, then test restoring both the cluster state and the data. For shared storage architecture, see Ceph on Proxmox.
Real-World Uses
A K3s VM cluster is useful for experimenting with Helm charts, GitOps controllers, monitoring, internal dashboards, or non-critical self-hosted services. It can also provide a repeatable development environment: snapshot or rebuild a guest, redeploy manifests, and observe how workloads behave when a node is drained or stopped.
Treat household-critical services differently. A single VM can be a convenient place to learn, but maintenance, host failure, storage problems, or a bad upgrade can affect every workload on it. Keep important data backed up outside the cluster and document a recovery path before depending on the setup.
Getting Started: Create a K3s VM
This walkthrough uses one Linux server VM as the first node. It assumes a working Proxmox VE host and a supported Debian- or Ubuntu-based guest.
1. Create and prepare the VM
In the Proxmox web interface, upload a current Linux server ISO and create a VM with a virtual disk, 2 vCPUs, and 4 GiB of RAM as a starting point. Use a VirtIO network device attached to the intended bridge, and assign the guest a stable LAN address with a DHCP reservation or static configuration. Enable the QEMU Guest Agent option in the VM settings if you plan to use it, and install and start the agent package inside the guest.
After installing Linux, update the guest and confirm it can resolve names and reach the internet. Check that the chosen LAN and VPN routes do not overlap K3s’s default Pod range (10.42.0.0/16) or Service range (10.43.0.0/16). If they do, choose non-overlapping cluster ranges before installing.
2. Install K3s
Download the installer so it can be inspected before running it with administrator privileges. Replace the example IP address with the VM’s stable address:
curl -sfL https://get.k3s.io -o install-k3s.sh
less install-k3s.sh
sudo env INSTALL_K3S_EXEC="server --node-ip=192.168.10.21" sh install-k3s.sh
The installer creates and starts the k3s system service. Check that the service is active and the node is ready:
sudo systemctl status k3s --no-pager
sudo k3s kubectl get nodes -o wide
sudo k3s kubectl get pods -A
The K3s server’s node token authenticates agents. Keep it private and retrieve it only when joining another node:
sudo cat /var/lib/rancher/k3s/server/node-token
On a second Linux VM, download and inspect the installer as above, then join it as an agent. Replace the address and token with your server’s actual values; do not commit the token or put it in a shared script:
sudo env \
K3S_URL=https://192.168.10.21:6443 \
K3S_TOKEN='<server-node-token>' \
sh install-k3s.sh
On the server, run sudo k3s kubectl get nodes -o wide again and confirm both nodes reach Ready. If an agent does not register, check that its clock and address are correct, that TCP 6443 is reachable, and that the token matches. Also inspect sudo journalctl -u k3s -b --no-pager on the affected VM.
3. Verify a workload and plan recovery
Create a disposable deployment to check scheduling and container startup:
sudo k3s kubectl create deployment web --image=nginx:stable
sudo k3s kubectl get deployments,pods
sudo k3s kubectl delete deployment web
This test does not prove that a service is reachable from the LAN or that persistent data can be restored. Before adding real workloads, decide which ports should be exposed, how DNS and TLS will work, where persistent data lives, and how to recover it. Back up the VM and application data separately, and test a restore rather than treating a successful snapshot as proof of recovery.
Common Misconceptions
More Kubernetes VMs make a Proxmox host resilient. They can improve workload placement and let you practice node failure, but VMs on the same physical host share its power, disks, and network interfaces. Host-level resilience requires separate hosts and a tested recovery design.
A Proxmox snapshot is a Kubernetes backup. A snapshot captures VM disk state at a point in time; it does not define an application-consistent backup policy or prove the application can recover. Preserve cluster configuration and use workload-appropriate backups for databases and other stateful services.
A persistent volume follows a Pod to any node. A claim describes storage requested by a workload, not the storage’s replication or failure guarantees. Local-path data is tied to the node unless a separate storage system makes it available elsewhere.
Related Articles
- Kubernetes homelab: how to build a small cluster compares distributions and covers cluster fundamentals.
- Kubernetes architecture explained breaks down control planes, nodes, and workloads.
- Proxmox vs ESXi vs XCP-ng compares the virtualization platforms.
- Home lab network segmentation with VLANs covers isolating management and server traffic.
- Ceph on Proxmox explains the trade-offs of distributed storage.
Changelog
- Initial publication.

