[email protected]

How-to · Kubernetes

Install Kubernetes on Proxmox: k3s with three VMs

Editorial note: Versions, commands and prices may change. Please verify critical steps independently before production use. This guide does not replace individual professional, legal or tax advice.

Agree deployment and operations: WZ-IT designs, implements and operates Kubernetes on Proxmox. Planning connects the hypervisor, Kubernetes, networking and storage.

This guide creates a new k3s cluster in Proxmox KVM VMs: three servers with embedded etcd, optional workers and a fixed API endpoint. It covers deployment, while the architecture overview compares operational models. For platform selection, see Proxmox vs Kubernetes.

As of October 2026. Commands and addresses are a scaffold to adapt for new VMs. Do not install k3s on the Proxmox host. Existing clusters are not reinitialised.

Contents

1. Topology and prerequisites

For embedded-etcd HA, k3s needs at least three servers; workers are called agents and are optional. Servers can also run workloads. Check resources and disks against the k3s requirements. Vendor minimums are not sizing for your applications. Use sufficiently fast storage for etcd and plan spare capacity for maintenance and failures.

Role Example address Placement for host failure protection
API endpoint 10.20.0.10, api.k8s.example.test Redundant TCP load balancer in front of the servers
cp1 10.20.0.11 Proxmox host A
cp2 10.20.0.12 Proxmox host B
cp3 10.20.0.13 Proxmox host C
Workers as needed From your node network Distribute according to capacity and application

All addresses and names are examples. Three VMs on one host form a lab with a shared failure point. A redundant API IP does not replace independent hosts, power, network or storage paths. RKE2 is a different installation path; the distribution comparison and Talos guide cover alternatives.

2. Cloud-Init template and VMs

Follow the documented Proxmox Cloud-Init workflow: obtain a cloud image from the chosen Linux vendor and verify its checksum, create a new VM, import the image disk and attach it as the boot disk. Add a Cloud-Init drive and controller and console settings appropriate for the image. Check the image, guest OS and k3s version together against the requirements.

Before each clone's first boot, use Proxmox Cloud-Init to set an administrative user, its SSH key, a unique IP with gateway and DNS configuration. Convert the powered-off base into a template and create three full clones. Give each guest a unique VM ID, MAC address and hostname. The template contains no k3s state or cluster secrets yet.

Start the clones on the intended hosts. Inside each guest, verify completed Cloud-Init processing with cloud-init status --wait, IP configuration, DNS resolution, time synchronisation and SSH access. Record VM IDs and host placement. The official Cloud-Init source document also describes templates, cloning and IP/key assignment.

3. Networking and API endpoint

Node, pod and service networks must not overlap existing networks. This deployment uses k3s default pod and service CIDRs only if those ranges are free in your environment. Otherwise set identical cluster-cidr and service-cidr values on every server before creating the cluster. Check network requirements and firewall rules instead of disabling the firewall globally.

Traffic Access in this model
Nodes and administrative API access TCP 6443 to API endpoint and servers
Embedded etcd TCP 2379 and 2380 between servers
Flannel VXLAN UDP 8472 between nodes, not publicly exposed
Kubelet and metrics TCP 10250 between nodes

Before bootstrap, configure the TCP load balancer with health checks against the three server addresses on port 6443. A single load balancer would introduce another failure point; redundant instances and IP failover are prerequisites for the HA goal. DNS points to the API IP. Verify routing and IP ownership before using that address.

This API IP is not a Kubernetes application load balancer. A Kubernetes Service of type LoadBalancer, ingress and application certificates are planned separately. Bundled components such as Traefik and ServiceLB initially retain their k3s defaults here; introduce alternative controllers only after a deliberate decision.

4. Initialise k3s and join servers

Work inside the new Linux VMs with administrative privileges. Create /etc/rancher/k3s/ accessible only to root. On cp1, create /etc/rancher/k3s/config.yaml and protect it with file mode 0600. Replace the token placeholder with a long random secret from your protected secret management system.

# Only cp1 during initial cluster creation
cluster-init: true
token: "REPLACE_WITH_PRIVATE_CLUSTER_SECRET"
tls-san:
  - "10.20.0.10"
  - "api.k8s.example.test"
write-kubeconfig-mode: "0600"

The configuration path and YAML options are documented. Choose a specific approved k3s version from the release notes and set K3S_VERSION to its full release tag. Use the same value on all new nodes. Then, on cp1:

# Set K3S_VERSION to a specific approved release tag first
: "${K3S_VERSION:?Set a specific k3s release tag}"
curl -fL https://get.k3s.io -o install-k3s.sh
# Review the script before execution
sudo env INSTALL_K3S_VERSION="${K3S_VERSION:?Set a specific k3s release tag}" sh install-k3s.sh server
sudo k3s kubectl get nodes -o wide

On cp2 and cp3, create an individual protected config.yaml. Use the shared token, the same TLS names and, where applicable, identical customised CIDRs. No cluster-init on these nodes:

server: "https://10.20.0.10:6443"
token: "REPLACE_WITH_PRIVATE_CLUSTER_SECRET"
tls-san:
  - "10.20.0.10"
  - "api.k8s.example.test"
write-kubeconfig-mode: "0600"

Once cp1 is reachable through the load balancer, run the same version-pinned installation block with role server sequentially on cp2 and cp3. Check node state after each join. This follows the documented HA bootstrap using a shared token, with fixed API access. Do not repeat initialisation as a repair procedure for an existing cluster.

5. Workers and cluster access

For each additional worker VM, create a root-protected config.yaml before installation with server: "https://10.20.0.10:6443" and the same private token. Download and review the installation script as above, set the same release tag and use role agent:

: "${K3S_VERSION:?Set a specific k3s release tag}"
sudo env INSTALL_K3S_VERSION="${K3S_VERSION:?Set a specific k3s release tag}" sh install-k3s.sh agent

On a server, check nodes and system pods:

sudo k3s kubectl get nodes -o wide
sudo k3s kubectl get pods -A -o wide
sudo k3s kubectl get --raw='/readyz?verbose'

The administrative kubeconfig is stored at /etc/rancher/k3s/k3s.yaml, as documented in k3s cluster access. On the designated admin machine, create ~/.kube with mode 0700 or check its protection if it already exists. Transfer the file securely as ~/.kube/proxmox-k3s.yaml with mode 0600, without overwriting an existing configuration. In this copy, replace the server value with https://api.k8s.example.test:6443 or your actual API endpoint. It contains administrative credentials; keep it out of Git and do not make it generally readable. Then, on the admin machine, verify access through the load balancer explicitly using this file:

kubectl --kubeconfig ~/.kube/proxmox-k3s.yaml get nodes

6. Storage, backup and acceptance

The bundled Local Path Provisioner supplies node-local storage, not automatic replication. Existing Proxmox Ceph does not become a Kubernetes StorageClass just by installing k3s. Choose an appropriate CSI/storage model before deploying persistent applications. Verify a test PVC, read/write access and behaviour during a planned node change against the volume properties.

For embedded etcd, request a manual snapshot on a server:

sudo k3s etcd-snapshot save --name acceptance
sudo k3s etcd-snapshot ls

The snapshot command alone does not prove recoverability. Back up the snapshot and actual server token from /var/lib/rancher/k3s/server/token separately from the cluster with restricted access; restore requires the token. Back up application data additionally. Plan isolated recovery testing using Kubernetes backup and restore.

Acceptance area Evidence before production
Control plane Three server nodes ready; API state and host placement recorded
Networking Node connectivity, DNS and pod traffic verified
Application Your test application reachable through the intended access path
Persistence Chosen StorageClass and data access verified after an appropriate recovery
Failure Approved test of one host and the API load balancer; observe quorum and application
Recovery etcd with its token and application data restored in isolation

Run failure tests only under an agreed plan in the test environment. Healthy node status alone is not full acceptance. This scaffold provides neither automatic hardening nor complete production operations.

From installation to operations: Kubernetes on Proxmox combines agreed cluster deployment with network, storage and operational planning. The architecture overview covers HA and both layers' lifecycles.

Sources

Rather have it operated?

You'd rather not run Kubernetes yourself? WZ-IT handles setup, operations and maintenance - privacy-focused from Germany.

Enquiry

Design, take over, or operate Kubernetes

We design and operate Kubernetes on bare metal, Proxmox, and European cloud platforms, including networking, GitOps, observability, and backups.

  • Straight with Timo and Robin - no sales team, no pitch
  • A professional assessment of your situation
  • Concrete next steps for infrastructure, software or AI

The conversation is free and non-binding.

WZ-IT supported us professionally with the provisioning and setup of NetBird. Alongside the technical implementation, we also received well-founded advice on connecting our Kubernetes clusters. The recommendations were concrete and directly actionable. The collaboration was consistently reliable, fast and on equal terms. We can recommend WZ-IT without reservation.
Kai ClaußHead of Development, SweetConnect GmbH
Timo and Robin, founders of WZ-IT

Design, take over, or operate Kubernetes

WZ-IT supported us professionally with the provisioning and setup of NetBird. Alongside the technical implementation, we also received well-founded advice on connecting our Kubernetes clusters. The recommendations were concrete and directly actionable. The collaboration was consistently reliable, fast and on equal terms. We can recommend WZ-IT without reservation.
Kai ClaußHead of Development, SweetConnect GmbH

Frequently Asked Questions

Answers to the most important questions

Companies worldwide trust WZ-IT

  • Stadtwerke Brühl
  • DGHO e.V.
  • ABCO Water Systems
  • Golem.de
  • EVADXB
  • nextGYM
  • AInergy
  • ml&s
  • Odiseo Solutions
  • Annota
  • ARGE
  • SweetConnect GmbH
  • Aphy AG
  • CORGOS
  • Rekorder
  • SolidProof
  • Yonju
  • Keymate
  • Paritel
  • Mr. Clipart
  • Millenium
  • Negosh
  • Führerscheinmacher
  • Boese VA
Read client reviews