[{"data":1,"prerenderedAt":1571},["ShallowReactive",2],{"blog-en-k3s-on-proxmox-cluster":3,"blog-en-k3s-on-proxmox-cluster-alt":271},{"id":4,"title":5,"author":6,"body":7,"date":1555,"description":1556,"extension":1557,"image":236,"locale":1558,"meta":1559,"navigation":271,"path":1560,"seo":1561,"stem":1562,"tags":1563,"__hash__":1570},"blog\u002Fblog\u002Fen\u002Fk3s-on-proxmox-cluster.md","Building a K3s Cluster on Proxmox: A Step-by-Step Guide","Kubo Team",{"type":8,"value":9,"toc":1529},"minimark",[10,22,31,36,45,50,120,124,127,210,219,223,226,230,513,517,520,665,668,709,718,722,726,735,817,823,851,855,858,911,915,923,975,982,986,989,1064,1068,1072,1081,1207,1211,1218,1234,1238,1246,1300,1304,1308,1386,1390,1393,1449,1456,1460,1463,1470,1479,1484,1525],[11,12,13,14,21],"p",{},"Kubernetes has become the de facto standard for modern application deployment, but building and operating a full K8s cluster demands significant expertise. ",[15,16,20],"a",{"href":17,"rel":18},"https:\u002F\u002Fk3s.io\u002F",[19],"nofollow","K3s"," is a lightweight Kubernetes distribution developed by Rancher Labs that delivers full Kubernetes functionality with minimal resource overhead. Combined with Proxmox VE, it enables you to build a flexible, cost-effective Kubernetes foundation.",[11,23,24,25,30],{},"For organizations needing enterprise-grade managed Kubernetes, ",[15,26,29],{"href":27,"rel":28},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fkubo\u002Fon-premise",[19],"Kubo On-Premise"," delivers a fully managed K8s environment on Proxmox, minimizing infrastructure management overhead so your team can focus on development.",[32,33,35],"h2",{"id":34},"architecture-design-and-vm-planning","Architecture Design and VM Planning",[11,37,38,39,44],{},"K3s cluster design balances availability requirements against resource budgets. The ",[15,40,43],{"href":41,"rel":42},"https:\u002F\u002Fdocs.k3s.io\u002F",[19],"K3s official documentation"," recommends a minimum of 3 server nodes for production environments.",[46,47,49],"h3",{"id":48},"recommended-configuration","Recommended Configuration",[51,52,53,78],"table",{},[54,55,56],"thead",{},[57,58,59,63,66,69,72,75],"tr",{},[60,61,62],"th",{},"Role",[60,64,65],{},"Count",[60,67,68],{},"CPU",[60,70,71],{},"RAM",[60,73,74],{},"Storage",[60,76,77],{},"OS",[79,80,81,102],"tbody",{},[57,82,83,87,90,93,96,99],{},[84,85,86],"td",{},"Server (Control Plane)",[84,88,89],{},"3",[84,91,92],{},"4 vCPU",[84,94,95],{},"8 GB",[84,97,98],{},"50 GB SSD",[84,100,101],{},"Ubuntu 24.04 LTS",[57,103,104,107,110,112,115,118],{},[84,105,106],{},"Worker (Data Plane)",[84,108,109],{},"3+",[84,111,92],{},[84,113,114],{},"16 GB",[84,116,117],{},"100 GB SSD",[84,119,101],{},[46,121,123],{"id":122},"network-design","Network Design",[11,125,126],{},"Assign static IPs outside the DHCP range to cluster nodes:",[51,128,129,142],{},[54,130,131],{},[57,132,133,136,139],{},[60,134,135],{},"Node",[60,137,138],{},"Hostname",[60,140,141],{},"IP Address",[79,143,144,155,166,177,188,199],{},[57,145,146,149,152],{},[84,147,148],{},"Server 1",[84,150,151],{},"k3s-server-1",[84,153,154],{},"192.168.1.101",[57,156,157,160,163],{},[84,158,159],{},"Server 2",[84,161,162],{},"k3s-server-2",[84,164,165],{},"192.168.1.102",[57,167,168,171,174],{},[84,169,170],{},"Server 3",[84,172,173],{},"k3s-server-3",[84,175,176],{},"192.168.1.103",[57,178,179,182,185],{},[84,180,181],{},"Worker 1",[84,183,184],{},"k3s-worker-1",[84,186,187],{},"192.168.1.111",[57,189,190,193,196],{},[84,191,192],{},"Worker 2",[84,194,195],{},"k3s-worker-2",[84,197,198],{},"192.168.1.112",[57,200,201,204,207],{},[84,202,203],{},"Worker 3",[84,205,206],{},"k3s-worker-3",[84,208,209],{},"192.168.1.113",[11,211,212,213,218],{},"Leverage VLANs in ",[15,214,217],{"href":215,"rel":216},"https:\u002F\u002Fpve.proxmox.com\u002Fwiki\u002FNetwork_Configuration",[19],"Proxmox network configuration"," to isolate management and cluster traffic.",[32,220,222],{"id":221},"creating-vm-templates","Creating VM Templates",[11,224,225],{},"Build a Cloud-Init enabled VM template for efficient node provisioning. This allows you to spin up new nodes in minutes through simple clone operations.",[46,227,229],{"id":228},"downloading-ubuntu-cloud-image-and-creating-the-template","Downloading Ubuntu Cloud Image and Creating the Template",[231,232,237],"pre",{"className":233,"code":234,"language":235,"meta":236,"style":236},"language-bash shiki shiki-themes tokyo-night","# Run on Proxmox host\n# Download Ubuntu 24.04 Cloud Image\nwget https:\u002F\u002Fcloud-images.ubuntu.com\u002Fnoble\u002Fcurrent\u002Fnoble-server-cloudimg-amd64.img\n\n# Create VM (ID 9000 reserved for templates)\nqm create 9000 --name ubuntu-2404-template --memory 4096 --cores 2 \\\n  --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single\n\n# Import disk image\nqm set 9000 --scsi0 local-lvm:0,import-from=\u002Froot\u002Fnoble-server-cloudimg-amd64.img\n\n# Add Cloud-Init drive\nqm set 9000 --ide2 local-lvm:cloudinit\nqm set 9000 --boot order=scsi0\nqm set 9000 --serial0 socket --vga serial0\n\n# Set Cloud-Init defaults\nqm set 9000 --ciuser ubuntu --cipassword \u003Cpassword>\nqm set 9000 --sshkeys ~\u002F.ssh\u002Fid_rsa.pub\nqm set 9000 --ipconfig0 ip=dhcp\n\n# Convert to template\nqm template 9000\n","bash","",[238,239,240,249,255,266,273,279,315,330,335,341,357,362,368,383,398,419,424,430,461,476,491,496,502],"code",{"__ignoreMap":236},[241,242,245],"span",{"class":243,"line":244},"line",1,[241,246,248],{"class":247},"sbD-w","# Run on Proxmox host\n",[241,250,252],{"class":243,"line":251},2,[241,253,254],{"class":247},"# Download Ubuntu 24.04 Cloud Image\n",[241,256,258,262],{"class":243,"line":257},3,[241,259,261],{"class":260},"sE3pS","wget",[241,263,265],{"class":264},"sPY7s"," https:\u002F\u002Fcloud-images.ubuntu.com\u002Fnoble\u002Fcurrent\u002Fnoble-server-cloudimg-amd64.img\n",[241,267,269],{"class":243,"line":268},4,[241,270,272],{"emptyLinePlaceholder":271},true,"\n",[241,274,276],{"class":243,"line":275},5,[241,277,278],{"class":247},"# Create VM (ID 9000 reserved for templates)\n",[241,280,282,285,288,292,296,299,302,305,308,311],{"class":243,"line":281},6,[241,283,284],{"class":260},"qm",[241,286,287],{"class":264}," create",[241,289,291],{"class":290},"sOJ5S"," 9000",[241,293,295],{"class":294},"sT800"," --name",[241,297,298],{"class":264}," ubuntu-2404-template",[241,300,301],{"class":294}," --memory",[241,303,304],{"class":290}," 4096",[241,306,307],{"class":294}," --cores",[241,309,310],{"class":290}," 2",[241,312,314],{"class":313},"sAklC"," \\\n",[241,316,318,321,324,327],{"class":243,"line":317},7,[241,319,320],{"class":294},"  --net0",[241,322,323],{"class":264}," virtio,bridge=vmbr0",[241,325,326],{"class":294}," --scsihw",[241,328,329],{"class":264}," virtio-scsi-single\n",[241,331,333],{"class":243,"line":332},8,[241,334,272],{"emptyLinePlaceholder":271},[241,336,338],{"class":243,"line":337},9,[241,339,340],{"class":247},"# Import disk image\n",[241,342,344,346,349,351,354],{"class":243,"line":343},10,[241,345,284],{"class":260},[241,347,348],{"class":264}," set",[241,350,291],{"class":290},[241,352,353],{"class":294}," --scsi0",[241,355,356],{"class":264}," local-lvm:0,import-from=\u002Froot\u002Fnoble-server-cloudimg-amd64.img\n",[241,358,360],{"class":243,"line":359},11,[241,361,272],{"emptyLinePlaceholder":271},[241,363,365],{"class":243,"line":364},12,[241,366,367],{"class":247},"# Add Cloud-Init drive\n",[241,369,371,373,375,377,380],{"class":243,"line":370},13,[241,372,284],{"class":260},[241,374,348],{"class":264},[241,376,291],{"class":290},[241,378,379],{"class":294}," --ide2",[241,381,382],{"class":264}," local-lvm:cloudinit\n",[241,384,386,388,390,392,395],{"class":243,"line":385},14,[241,387,284],{"class":260},[241,389,348],{"class":264},[241,391,291],{"class":290},[241,393,394],{"class":294}," --boot",[241,396,397],{"class":264}," order=scsi0\n",[241,399,401,403,405,407,410,413,416],{"class":243,"line":400},15,[241,402,284],{"class":260},[241,404,348],{"class":264},[241,406,291],{"class":290},[241,408,409],{"class":294}," --serial0",[241,411,412],{"class":264}," socket",[241,414,415],{"class":294}," --vga",[241,417,418],{"class":264}," serial0\n",[241,420,422],{"class":243,"line":421},16,[241,423,272],{"emptyLinePlaceholder":271},[241,425,427],{"class":243,"line":426},17,[241,428,429],{"class":247},"# Set Cloud-Init defaults\n",[241,431,433,435,437,439,442,445,448,451,454,458],{"class":243,"line":432},18,[241,434,284],{"class":260},[241,436,348],{"class":264},[241,438,291],{"class":290},[241,440,441],{"class":294}," --ciuser",[241,443,444],{"class":264}," ubuntu",[241,446,447],{"class":294}," --cipassword",[241,449,450],{"class":313}," \u003C",[241,452,453],{"class":264},"passwor",[241,455,457],{"class":456},"sGX4V","d",[241,459,460],{"class":313},">\n",[241,462,464,466,468,470,473],{"class":243,"line":463},19,[241,465,284],{"class":260},[241,467,348],{"class":264},[241,469,291],{"class":290},[241,471,472],{"class":294}," --sshkeys",[241,474,475],{"class":264}," ~\u002F.ssh\u002Fid_rsa.pub\n",[241,477,479,481,483,485,488],{"class":243,"line":478},20,[241,480,284],{"class":260},[241,482,348],{"class":264},[241,484,291],{"class":290},[241,486,487],{"class":294}," --ipconfig0",[241,489,490],{"class":264}," ip=dhcp\n",[241,492,494],{"class":243,"line":493},21,[241,495,272],{"emptyLinePlaceholder":271},[241,497,499],{"class":243,"line":498},22,[241,500,501],{"class":247},"# Convert to template\n",[241,503,505,507,510],{"class":243,"line":504},23,[241,506,284],{"class":260},[241,508,509],{"class":264}," template",[241,511,512],{"class":290}," 9000\n",[46,514,516],{"id":515},"cloning-nodes","Cloning Nodes",[11,518,519],{},"Create full clones from the template for each node:",[231,521,523],{"className":233,"code":522,"language":235,"meta":236,"style":236},"# Server nodes\nqm clone 9000 101 --name k3s-server-1 --full\nqm clone 9000 102 --name k3s-server-2 --full\nqm clone 9000 103 --name k3s-server-3 --full\n\n# Worker nodes (with increased resources)\nqm clone 9000 111 --name k3s-worker-1 --full\nqm set 111 --memory 16384 --cores 4\nqm clone 9000 112 --name k3s-worker-2 --full\nqm set 112 --memory 16384 --cores 4\n",[238,524,525,530,550,568,586,590,595,613,631,649],{"__ignoreMap":236},[241,526,527],{"class":243,"line":244},[241,528,529],{"class":247},"# Server nodes\n",[241,531,532,534,537,539,542,544,547],{"class":243,"line":251},[241,533,284],{"class":260},[241,535,536],{"class":264}," clone",[241,538,291],{"class":290},[241,540,541],{"class":290}," 101",[241,543,295],{"class":294},[241,545,546],{"class":264}," k3s-server-1",[241,548,549],{"class":294}," --full\n",[241,551,552,554,556,558,561,563,566],{"class":243,"line":257},[241,553,284],{"class":260},[241,555,536],{"class":264},[241,557,291],{"class":290},[241,559,560],{"class":290}," 102",[241,562,295],{"class":294},[241,564,565],{"class":264}," k3s-server-2",[241,567,549],{"class":294},[241,569,570,572,574,576,579,581,584],{"class":243,"line":268},[241,571,284],{"class":260},[241,573,536],{"class":264},[241,575,291],{"class":290},[241,577,578],{"class":290}," 103",[241,580,295],{"class":294},[241,582,583],{"class":264}," k3s-server-3",[241,585,549],{"class":294},[241,587,588],{"class":243,"line":275},[241,589,272],{"emptyLinePlaceholder":271},[241,591,592],{"class":243,"line":281},[241,593,594],{"class":247},"# Worker nodes (with increased resources)\n",[241,596,597,599,601,603,606,608,611],{"class":243,"line":317},[241,598,284],{"class":260},[241,600,536],{"class":264},[241,602,291],{"class":290},[241,604,605],{"class":290}," 111",[241,607,295],{"class":294},[241,609,610],{"class":264}," k3s-worker-1",[241,612,549],{"class":294},[241,614,615,617,619,621,623,626,628],{"class":243,"line":332},[241,616,284],{"class":260},[241,618,348],{"class":264},[241,620,605],{"class":290},[241,622,301],{"class":294},[241,624,625],{"class":290}," 16384",[241,627,307],{"class":294},[241,629,630],{"class":290}," 4\n",[241,632,633,635,637,639,642,644,647],{"class":243,"line":337},[241,634,284],{"class":260},[241,636,536],{"class":264},[241,638,291],{"class":290},[241,640,641],{"class":290}," 112",[241,643,295],{"class":294},[241,645,646],{"class":264}," k3s-worker-2",[241,648,549],{"class":294},[241,650,651,653,655,657,659,661,663],{"class":243,"line":343},[241,652,284],{"class":260},[241,654,348],{"class":264},[241,656,641],{"class":290},[241,658,301],{"class":294},[241,660,625],{"class":290},[241,662,307],{"class":294},[241,664,630],{"class":290},[11,666,667],{},"Set static IPs on each node:",[231,669,671],{"className":233,"code":670,"language":235,"meta":236,"style":236},"qm set 101 --ipconfig0 ip=192.168.1.101\u002F24,gw=192.168.1.1\nqm set 102 --ipconfig0 ip=192.168.1.102\u002F24,gw=192.168.1.1\n# Continue for remaining nodes\n",[238,672,673,689,704],{"__ignoreMap":236},[241,674,675,677,679,681,683,686],{"class":243,"line":244},[241,676,284],{"class":260},[241,678,348],{"class":264},[241,680,541],{"class":290},[241,682,487],{"class":294},[241,684,685],{"class":264}," ip=192.168.1.101\u002F24,gw=",[241,687,688],{"class":290},"192.168.1.1\n",[241,690,691,693,695,697,699,702],{"class":243,"line":251},[241,692,284],{"class":260},[241,694,348],{"class":264},[241,696,560],{"class":290},[241,698,487],{"class":294},[241,700,701],{"class":264}," ip=192.168.1.102\u002F24,gw=",[241,703,688],{"class":290},[241,705,706],{"class":243,"line":257},[241,707,708],{"class":247},"# Continue for remaining nodes\n",[11,710,711,712,717],{},"With ",[15,713,716],{"href":714,"rel":715},"https:\u002F\u002Fkubo.hexabase.io\u002F",[19],"Kubo",", you can bypass this complexity entirely and get a production-grade K8s environment through declarative configuration alone.",[32,719,721],{"id":720},"installing-and-configuring-k3s","Installing and Configuring K3s",[46,723,725],{"id":724},"initializing-the-first-server-node","Initializing the First Server Node",[11,727,728,729,734],{},"Initialize the K3s cluster on the first server node (k3s-server-1). Following the ",[15,730,733],{"href":731,"rel":732},"https:\u002F\u002Fdocs.k3s.io\u002Fquick-start",[19],"K3s Quick-Start Guide",":",[231,736,738],{"className":233,"code":737,"language":235,"meta":236,"style":236},"# Run on first server node\ncurl -sfL https:\u002F\u002Fget.k3s.io | K3S_TOKEN=\u003Csecure-token> sh -s - server \\\n  --cluster-init \\\n  --tls-san=192.168.1.100 \\\n  --disable traefik \\\n  --write-kubeconfig-mode 644\n",[238,739,740,745,785,792,799,809],{"__ignoreMap":236},[241,741,742],{"class":243,"line":244},[241,743,744],{"class":247},"# Run on first server node\n",[241,746,747,750,753,756,759,762,765,768,771,774,777,780,783],{"class":243,"line":251},[241,748,749],{"class":260},"curl",[241,751,752],{"class":294}," -sfL",[241,754,755],{"class":264}," https:\u002F\u002Fget.k3s.io",[241,757,758],{"class":313}," |",[241,760,761],{"class":260}," K3S_TOKEN",[241,763,764],{"class":313},"=\u003C",[241,766,767],{"class":264},"secure-token",[241,769,770],{"class":313},">",[241,772,773],{"class":260}," sh",[241,775,776],{"class":294}," -s",[241,778,779],{"class":264}," -",[241,781,782],{"class":264}," server",[241,784,314],{"class":313},[241,786,787,790],{"class":243,"line":257},[241,788,789],{"class":294},"  --cluster-init",[241,791,314],{"class":313},[241,793,794,797],{"class":243,"line":268},[241,795,796],{"class":294},"  --tls-san=192.168.1.100",[241,798,314],{"class":313},[241,800,801,804,807],{"class":243,"line":275},[241,802,803],{"class":294},"  --disable",[241,805,806],{"class":264}," traefik",[241,808,314],{"class":313},[241,810,811,814],{"class":243,"line":281},[241,812,813],{"class":294},"  --write-kubeconfig-mode",[241,815,816],{"class":290}," 644\n",[11,818,819],{},[820,821,822],"strong",{},"Option explanations:",[824,825,826,833,839,845],"ul",{},[827,828,829,832],"li",{},[238,830,831],{},"--cluster-init",": Initialize in HA mode using embedded etcd",[827,834,835,838],{},[238,836,837],{},"--tls-san",": Add load balancer VIP to the certificate's Subject Alternative Names",[827,840,841,844],{},[238,842,843],{},"--disable traefik",": Disable built-in Traefik to install a custom Ingress Controller later",[827,846,847,850],{},[238,848,849],{},"--write-kubeconfig-mode 644",": Set readable permissions on kubeconfig",[46,852,854],{"id":853},"joining-additional-server-nodes","Joining Additional Server Nodes",[11,856,857],{},"Add remaining server nodes to the cluster:",[231,859,861],{"className":233,"code":860,"language":235,"meta":236,"style":236},"# Run on k3s-server-2 and k3s-server-3\ncurl -sfL https:\u002F\u002Fget.k3s.io | K3S_TOKEN=\u003Csecure-token> sh -s - server \\\n  --server https:\u002F\u002F192.168.1.101:6443 \\\n  --tls-san=192.168.1.100\n",[238,862,863,868,896,906],{"__ignoreMap":236},[241,864,865],{"class":243,"line":244},[241,866,867],{"class":247},"# Run on k3s-server-2 and k3s-server-3\n",[241,869,870,872,874,876,878,880,882,884,886,888,890,892,894],{"class":243,"line":251},[241,871,749],{"class":260},[241,873,752],{"class":294},[241,875,755],{"class":264},[241,877,758],{"class":313},[241,879,761],{"class":260},[241,881,764],{"class":313},[241,883,767],{"class":264},[241,885,770],{"class":313},[241,887,773],{"class":260},[241,889,776],{"class":294},[241,891,779],{"class":264},[241,893,782],{"class":264},[241,895,314],{"class":313},[241,897,898,901,904],{"class":243,"line":257},[241,899,900],{"class":294},"  --server",[241,902,903],{"class":264}," https:\u002F\u002F192.168.1.101:6443",[241,905,314],{"class":313},[241,907,908],{"class":243,"line":268},[241,909,910],{"class":294},"  --tls-san=192.168.1.100\n",[46,912,914],{"id":913},"adding-worker-nodes","Adding Worker Nodes",[11,916,917,918,734],{},"Worker nodes join by specifying the ",[15,919,922],{"href":920,"rel":921},"https:\u002F\u002Fdocs.k3s.io\u002Fcli\u002Fagent",[19],"K3S_URL environment variable",[231,924,926],{"className":233,"code":925,"language":235,"meta":236,"style":236},"# Run on each worker node\ncurl -sfL https:\u002F\u002Fget.k3s.io | K3S_URL=https:\u002F\u002F192.168.1.101:6443 \\\n  K3S_TOKEN=\u003Csecure-token> sh -\n",[238,927,928,933,954],{"__ignoreMap":236},[241,929,930],{"class":243,"line":244},[241,931,932],{"class":247},"# Run on each worker node\n",[241,934,935,937,939,941,943,946,949,952],{"class":243,"line":251},[241,936,749],{"class":260},[241,938,752],{"class":294},[241,940,755],{"class":264},[241,942,758],{"class":313},[241,944,945],{"class":260}," K3S_URL",[241,947,948],{"class":313},"=",[241,950,951],{"class":264},"https:\u002F\u002F192.168.1.101:6443",[241,953,314],{"class":260},[241,955,956,959,962,965,968,970,972],{"class":243,"line":257},[241,957,958],{"class":264},"  K3S_TOKEN=",[241,960,961],{"class":313},"\u003C",[241,963,964],{"class":264},"secure-toke",[241,966,967],{"class":456},"n",[241,969,770],{"class":313},[241,971,773],{"class":264},[241,973,974],{"class":264}," -\n",[11,976,977,978,981],{},"The server token can be retrieved from ",[238,979,980],{},"\u002Fvar\u002Flib\u002Francher\u002Fk3s\u002Fserver\u002Fnode-token"," on any server node.",[46,983,985],{"id":984},"configuring-kubeconfig","Configuring kubeconfig",[11,987,988],{},"Copy the kubeconfig to your local machine for kubectl access:",[231,990,992],{"className":233,"code":991,"language":235,"meta":236,"style":236},"# Retrieve kubeconfig from server node\nscp ubuntu@192.168.1.101:\u002Fetc\u002Francher\u002Fk3s\u002Fk3s.yaml ~\u002F.kube\u002Fconfig\n\n# Update server address to external IP\nsed -i 's\u002F127.0.0.1\u002F192.168.1.101\u002F' ~\u002F.kube\u002Fconfig\n\n# Verify node list\nkubectl get nodes -o wide\n",[238,993,994,999,1010,1014,1019,1038,1042,1047],{"__ignoreMap":236},[241,995,996],{"class":243,"line":244},[241,997,998],{"class":247},"# Retrieve kubeconfig from server node\n",[241,1000,1001,1004,1007],{"class":243,"line":251},[241,1002,1003],{"class":260},"scp",[241,1005,1006],{"class":264}," ubuntu@192.168.1.101:\u002Fetc\u002Francher\u002Fk3s\u002Fk3s.yaml",[241,1008,1009],{"class":264}," ~\u002F.kube\u002Fconfig\n",[241,1011,1012],{"class":243,"line":257},[241,1013,272],{"emptyLinePlaceholder":271},[241,1015,1016],{"class":243,"line":268},[241,1017,1018],{"class":247},"# Update server address to external IP\n",[241,1020,1021,1024,1027,1030,1033,1036],{"class":243,"line":275},[241,1022,1023],{"class":260},"sed",[241,1025,1026],{"class":294}," -i",[241,1028,1029],{"class":313}," '",[241,1031,1032],{"class":264},"s\u002F127.0.0.1\u002F192.168.1.101\u002F",[241,1034,1035],{"class":313},"'",[241,1037,1009],{"class":264},[241,1039,1040],{"class":243,"line":281},[241,1041,272],{"emptyLinePlaceholder":271},[241,1043,1044],{"class":243,"line":317},[241,1045,1046],{"class":247},"# Verify node list\n",[241,1048,1049,1052,1055,1058,1061],{"class":243,"line":332},[241,1050,1051],{"class":260},"kubectl",[241,1053,1054],{"class":264}," get",[241,1056,1057],{"class":264}," nodes",[241,1059,1060],{"class":294}," -o",[241,1062,1063],{"class":264}," wide\n",[32,1065,1067],{"id":1066},"network-and-storage-configuration","Network and Storage Configuration",[46,1069,1071],{"id":1070},"metallb-load-balancer","MetalLB Load Balancer",[11,1073,1074,1075,1080],{},"In bare-metal environments, ",[15,1076,1079],{"href":1077,"rel":1078},"https:\u002F\u002Fmetallb.universe.tf\u002F",[19],"MetalLB"," assigns external IPs to LoadBalancer-type Services:",[231,1082,1084],{"className":233,"code":1083,"language":235,"meta":236,"style":236},"# Install MetalLB\nkubectl apply -f https:\u002F\u002Fraw.githubusercontent.com\u002Fmetallb\u002Fmetallb\u002Fv0.14.9\u002Fconfig\u002Fmanifests\u002Fmetallb-native.yaml\n\n# Configure IP address pool\ncat \u003C\u003CEOF | kubectl apply -f -\napiVersion: metallb.io\u002Fv1beta1\nkind: IPAddressPool\nmetadata:\n  name: default-pool\n  namespace: metallb-system\nspec:\n  addresses:\n  - 192.168.1.200-192.168.1.250\n---\napiVersion: metallb.io\u002Fv1beta1\nkind: L2Advertisement\nmetadata:\n  name: default\n  namespace: metallb-system\nEOF\n",[238,1085,1086,1091,1104,1108,1113,1135,1140,1145,1150,1155,1160,1165,1170,1175,1180,1184,1189,1193,1198,1202],{"__ignoreMap":236},[241,1087,1088],{"class":243,"line":244},[241,1089,1090],{"class":247},"# Install MetalLB\n",[241,1092,1093,1095,1098,1101],{"class":243,"line":251},[241,1094,1051],{"class":260},[241,1096,1097],{"class":264}," apply",[241,1099,1100],{"class":294}," -f",[241,1102,1103],{"class":264}," https:\u002F\u002Fraw.githubusercontent.com\u002Fmetallb\u002Fmetallb\u002Fv0.14.9\u002Fconfig\u002Fmanifests\u002Fmetallb-native.yaml\n",[241,1105,1106],{"class":243,"line":257},[241,1107,272],{"emptyLinePlaceholder":271},[241,1109,1110],{"class":243,"line":268},[241,1111,1112],{"class":247},"# Configure IP address pool\n",[241,1114,1115,1118,1121,1124,1126,1129,1131,1133],{"class":243,"line":275},[241,1116,1117],{"class":260},"cat",[241,1119,1120],{"class":313}," \u003C\u003C",[241,1122,1123],{"class":313},"EOF",[241,1125,758],{"class":313},[241,1127,1128],{"class":260}," kubectl",[241,1130,1097],{"class":264},[241,1132,1100],{"class":294},[241,1134,974],{"class":264},[241,1136,1137],{"class":243,"line":281},[241,1138,1139],{"class":264},"apiVersion: metallb.io\u002Fv1beta1\n",[241,1141,1142],{"class":243,"line":317},[241,1143,1144],{"class":264},"kind: IPAddressPool\n",[241,1146,1147],{"class":243,"line":332},[241,1148,1149],{"class":264},"metadata:\n",[241,1151,1152],{"class":243,"line":337},[241,1153,1154],{"class":264},"  name: default-pool\n",[241,1156,1157],{"class":243,"line":343},[241,1158,1159],{"class":264},"  namespace: metallb-system\n",[241,1161,1162],{"class":243,"line":359},[241,1163,1164],{"class":264},"spec:\n",[241,1166,1167],{"class":243,"line":364},[241,1168,1169],{"class":264},"  addresses:\n",[241,1171,1172],{"class":243,"line":370},[241,1173,1174],{"class":264},"  - 192.168.1.200-192.168.1.250\n",[241,1176,1177],{"class":243,"line":385},[241,1178,1179],{"class":264},"---\n",[241,1181,1182],{"class":243,"line":400},[241,1183,1139],{"class":264},[241,1185,1186],{"class":243,"line":421},[241,1187,1188],{"class":264},"kind: L2Advertisement\n",[241,1190,1191],{"class":243,"line":426},[241,1192,1149],{"class":264},[241,1194,1195],{"class":243,"line":432},[241,1196,1197],{"class":264},"  name: default\n",[241,1199,1200],{"class":243,"line":463},[241,1201,1159],{"class":264},[241,1203,1204],{"class":243,"line":478},[241,1205,1206],{"class":313},"EOF\n",[46,1208,1210],{"id":1209},"nginx-ingress-controller","NGINX Ingress Controller",[11,1212,1213,1214,734],{},"Route HTTP\u002FHTTPS traffic with the ",[15,1215,1210],{"href":1216,"rel":1217},"https:\u002F\u002Fkubernetes.github.io\u002Fingress-nginx\u002F",[19],[231,1219,1221],{"className":233,"code":1220,"language":235,"meta":236,"style":236},"kubectl apply -f https:\u002F\u002Fraw.githubusercontent.com\u002Fkubernetes\u002Fingress-nginx\u002Fcontroller-v1.12.0\u002Fdeploy\u002Fstatic\u002Fprovider\u002Fbaremetal\u002Fdeploy.yaml\n",[238,1222,1223],{"__ignoreMap":236},[241,1224,1225,1227,1229,1231],{"class":243,"line":244},[241,1226,1051],{"class":260},[241,1228,1097],{"class":264},[241,1230,1100],{"class":294},[241,1232,1233],{"class":264}," https:\u002F\u002Fraw.githubusercontent.com\u002Fkubernetes\u002Fingress-nginx\u002Fcontroller-v1.12.0\u002Fdeploy\u002Fstatic\u002Fprovider\u002Fbaremetal\u002Fdeploy.yaml\n",[46,1235,1237],{"id":1236},"longhorn-distributed-storage","Longhorn Distributed Storage",[11,1239,1240,1245],{},[15,1241,1244],{"href":1242,"rel":1243},"https:\u002F\u002Flonghorn.io\u002F",[19],"Longhorn"," is a Kubernetes-native distributed block storage system with excellent K3s integration:",[231,1247,1249],{"className":233,"code":1248,"language":235,"meta":236,"style":236},"# Install Longhorn\nkubectl apply -f https:\u002F\u002Fraw.githubusercontent.com\u002Flonghorn\u002Flonghorn\u002Fv1.7.2\u002Fdeploy\u002Flonghorn.yaml\n\n# Set as default StorageClass\nkubectl patch storageclass longhorn -p '{\"metadata\":{\"annotations\":{\"storageclass.kubernetes.io\u002Fis-default-class\":\"true\"}}}'\n",[238,1250,1251,1256,1267,1271,1276],{"__ignoreMap":236},[241,1252,1253],{"class":243,"line":244},[241,1254,1255],{"class":247},"# Install Longhorn\n",[241,1257,1258,1260,1262,1264],{"class":243,"line":251},[241,1259,1051],{"class":260},[241,1261,1097],{"class":264},[241,1263,1100],{"class":294},[241,1265,1266],{"class":264}," https:\u002F\u002Fraw.githubusercontent.com\u002Flonghorn\u002Flonghorn\u002Fv1.7.2\u002Fdeploy\u002Flonghorn.yaml\n",[241,1268,1269],{"class":243,"line":257},[241,1270,272],{"emptyLinePlaceholder":271},[241,1272,1273],{"class":243,"line":268},[241,1274,1275],{"class":247},"# Set as default StorageClass\n",[241,1277,1278,1280,1283,1286,1289,1292,1294,1297],{"class":243,"line":275},[241,1279,1051],{"class":260},[241,1281,1282],{"class":264}," patch",[241,1284,1285],{"class":264}," storageclass",[241,1287,1288],{"class":264}," longhorn",[241,1290,1291],{"class":294}," -p",[241,1293,1029],{"class":313},[241,1295,1296],{"class":264},"{\"metadata\":{\"annotations\":{\"storageclass.kubernetes.io\u002Fis-default-class\":\"true\"}}}",[241,1298,1299],{"class":313},"'\n",[32,1301,1303],{"id":1302},"operations-and-monitoring","Operations and Monitoring",[46,1305,1307],{"id":1306},"cluster-health-checks","Cluster Health Checks",[231,1309,1311],{"className":233,"code":1310,"language":235,"meta":236,"style":236},"# Node status\nkubectl get nodes -o wide\n\n# System pod verification\nkubectl get pods -A\n\n# K3s service status\nsystemctl status k3s       # Server nodes\nsystemctl status k3s-agent # Worker nodes\n",[238,1312,1313,1318,1330,1334,1339,1351,1355,1360,1374],{"__ignoreMap":236},[241,1314,1315],{"class":243,"line":244},[241,1316,1317],{"class":247},"# Node status\n",[241,1319,1320,1322,1324,1326,1328],{"class":243,"line":251},[241,1321,1051],{"class":260},[241,1323,1054],{"class":264},[241,1325,1057],{"class":264},[241,1327,1060],{"class":294},[241,1329,1063],{"class":264},[241,1331,1332],{"class":243,"line":257},[241,1333,272],{"emptyLinePlaceholder":271},[241,1335,1336],{"class":243,"line":268},[241,1337,1338],{"class":247},"# System pod verification\n",[241,1340,1341,1343,1345,1348],{"class":243,"line":275},[241,1342,1051],{"class":260},[241,1344,1054],{"class":264},[241,1346,1347],{"class":264}," pods",[241,1349,1350],{"class":294}," -A\n",[241,1352,1353],{"class":243,"line":281},[241,1354,272],{"emptyLinePlaceholder":271},[241,1356,1357],{"class":243,"line":317},[241,1358,1359],{"class":247},"# K3s service status\n",[241,1361,1362,1365,1368,1371],{"class":243,"line":332},[241,1363,1364],{"class":260},"systemctl",[241,1366,1367],{"class":264}," status",[241,1369,1370],{"class":264}," k3s",[241,1372,1373],{"class":247},"       # Server nodes\n",[241,1375,1376,1378,1380,1383],{"class":243,"line":337},[241,1377,1364],{"class":260},[241,1379,1367],{"class":264},[241,1381,1382],{"class":264}," k3s-agent",[241,1384,1385],{"class":247}," # Worker nodes\n",[46,1387,1389],{"id":1388},"backup-and-recovery","Backup and Recovery",[11,1391,1392],{},"K3s automatically takes etcd snapshots, but manual backups are also important:",[231,1394,1396],{"className":233,"code":1395,"language":235,"meta":236,"style":236},"# Manual etcd snapshot\nk3s etcd-snapshot save --name manual-backup-$(date +%Y%m%d)\n\n# List snapshots\nk3s etcd-snapshot ls\n",[238,1397,1398,1403,1431,1435,1440],{"__ignoreMap":236},[241,1399,1400],{"class":243,"line":244},[241,1401,1402],{"class":247},"# Manual etcd snapshot\n",[241,1404,1405,1408,1411,1414,1416,1419,1422,1425,1428],{"class":243,"line":251},[241,1406,1407],{"class":260},"k3s",[241,1409,1410],{"class":264}," etcd-snapshot",[241,1412,1413],{"class":264}," save",[241,1415,295],{"class":294},[241,1417,1418],{"class":264}," manual-backup-",[241,1420,1421],{"class":313},"$(",[241,1423,1424],{"class":260},"date",[241,1426,1427],{"class":264}," +%Y%m%d",[241,1429,1430],{"class":313},")\n",[241,1432,1433],{"class":243,"line":257},[241,1434,272],{"emptyLinePlaceholder":271},[241,1436,1437],{"class":243,"line":268},[241,1438,1439],{"class":247},"# List snapshots\n",[241,1441,1442,1444,1446],{"class":243,"line":275},[241,1443,1407],{"class":260},[241,1445,1410],{"class":264},[241,1447,1448],{"class":264}," ls\n",[11,1450,1451,1452,1455],{},"To automate K3s cluster operations and achieve enterprise-grade reliability, ",[15,1453,29],{"href":27,"rel":1454},[19]," is the ideal solution.",[32,1457,1459],{"id":1458},"conclusion","Conclusion",[11,1461,1462],{},"Building a K3s cluster on Proxmox VE delivers a flexible, cost-effective Kubernetes environment. This guide covered efficient provisioning with VM templates, high availability configuration, distributed storage with Longhorn, and everything needed for production operations.",[11,1464,1465,1466,1469],{},"For advanced management capabilities and enterprise support, consider adopting ",[15,1467,716],{"href":714,"rel":1468},[19],". Even on Proxmox, Kubo On-Premise operates as fully managed K8s, handling cluster lifecycle management, auto-scaling, and security patching in a single integrated solution.",[11,1471,1472,1473,1478],{},"For more details, ",[15,1474,1477],{"href":1475,"rel":1476},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[19],"contact us"," to discuss your requirements.",[11,1480,1481],{},[820,1482,1483],{},"Related Links:",[824,1485,1486,1492,1499,1506,1512,1518],{},[827,1487,1488],{},[15,1489,1491],{"href":41,"rel":1490},[19],"K3s Official Documentation",[827,1493,1494],{},[15,1495,1498],{"href":1496,"rel":1497},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s",[19],"K3s GitHub Repository",[827,1500,1501],{},[15,1502,1505],{"href":1503,"rel":1504},"https:\u002F\u002Fpve.proxmox.com\u002Fpve-docs\u002F",[19],"Proxmox VE Documentation",[827,1507,1508],{},[15,1509,1511],{"href":1077,"rel":1510},[19],"MetalLB Official Site",[827,1513,1514],{},[15,1515,1517],{"href":1242,"rel":1516},[19],"Longhorn Storage",[827,1519,1520],{},[15,1521,1524],{"href":1522,"rel":1523},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002F",[19],"Kubernetes Official Documentation",[1526,1527,1528],"style",{},"html pre.shiki code .sbD-w, html code.shiki .sbD-w{--shiki-default:#51597D;--shiki-default-font-style:italic}html pre.shiki code .sE3pS, html code.shiki .sE3pS{--shiki-default:#C0CAF5}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sOJ5S, html code.shiki .sOJ5S{--shiki-default:#FF9E64}html pre.shiki code .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sGX4V, html code.shiki .sGX4V{--shiki-default:#A9B1D6}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":236,"searchDepth":251,"depth":251,"links":1530},[1531,1535,1539,1545,1550,1554],{"id":34,"depth":251,"text":35,"children":1532},[1533,1534],{"id":48,"depth":257,"text":49},{"id":122,"depth":257,"text":123},{"id":221,"depth":251,"text":222,"children":1536},[1537,1538],{"id":228,"depth":257,"text":229},{"id":515,"depth":257,"text":516},{"id":720,"depth":251,"text":721,"children":1540},[1541,1542,1543,1544],{"id":724,"depth":257,"text":725},{"id":853,"depth":257,"text":854},{"id":913,"depth":257,"text":914},{"id":984,"depth":257,"text":985},{"id":1066,"depth":251,"text":1067,"children":1546},[1547,1548,1549],{"id":1070,"depth":257,"text":1071},{"id":1209,"depth":257,"text":1210},{"id":1236,"depth":257,"text":1237},{"id":1302,"depth":251,"text":1303,"children":1551},[1552,1553],{"id":1306,"depth":257,"text":1307},{"id":1388,"depth":257,"text":1389},{"id":1458,"depth":251,"text":1459},"2026-05-27","Complete guide to deploying a lightweight K3s Kubernetes cluster on Proxmox VE, covering VM templates, HA configuration, storage, and Ingress setup.","md","en",{},"\u002Fblog\u002Fen\u002Fk3s-on-proxmox-cluster",{"title":5,"description":1556},"blog\u002Fen\u002Fk3s-on-proxmox-cluster",[20,1564,1565,1566,1567,1568,1569],"Kubernetes","Proxmox","Self-Hosting","Containers","Cluster","DevOps","1b9orG89avPthxNiw9f--BR1C-vA_GXWWrGAgwG0eyY",1780391431946]