{"id":48,"date":"2025-10-12T15:47:03","date_gmt":"2025-10-12T15:47:03","guid":{"rendered":"https:\/\/ag.yomagnet.com\/index.php\/2025\/10\/12\/configuring-kubernetes-on-raspberry-pi-5-single-node-cluster\/"},"modified":"2025-10-12T15:47:03","modified_gmt":"2025-10-12T15:47:03","slug":"configuring-kubernetes-on-raspberry-pi-5-single-node-cluster","status":"publish","type":"post","link":"https:\/\/ag.yomagnet.com\/index.php\/2025\/10\/12\/configuring-kubernetes-on-raspberry-pi-5-single-node-cluster\/","title":{"rendered":"Configuring Kubernetes on Raspberry Pi 5 &#8211; (Single Node Cluster)"},"content":{"rendered":"<pre>sudo apt update &amp;&amp; sudo apt upgrade -y<\/pre>\n<pre>sudo apt install -y iptables iptables-persistent curl iproute2 dphys-swapfile<\/pre>\n<pre>grep -q '^CONF_SWAPSIZE=' \/etc\/dphys-swapfile &amp;&amp; \r\nsudo sed -i 's\/^CONF_SWAPSIZE=.*\/CONF_SWAPSIZE=2048\/' \/etc\/dphys-swapfile || \r\necho 'CONF_SWAPSIZE=2048' | sudo tee -a \/etc\/dphys-swapfile<\/pre>\n<pre>sudo systemctl restart dphys-swapfile<\/pre>\n<pre><del datetime=\"2025-10-12T16:20:56+00:00\">sudo vi \/boot\/cmdline.txt<\/del><\/pre>\n<pre>sudo vi \/boot\/firmware\/cmdline.txt<\/pre>\n<pre>cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory<\/pre>\n<pre>free -h<\/pre>\n<pre>sudo reboot<\/pre>\n<pre>sudo vi k3s-setup.sh<\/pre>\n<pre>#!\/bin\/bash\r\nset -e\r\n\r\necho \"Detecting IP address...\"\r\nNODE_IP=$(ip -4 addr show eth0 2&gt;\/dev\/null | grep -oP '(?\/dev\/null | grep -oP '(?&lt;=inets)d+(.d+){3}&#039;)\r\nfi\r\nif [ -z &quot;$NODE_IP&quot; ]; then\r\n    echo &quot;Unable to detect IP address on eth0 or wlan0. Exiting.&quot;\r\n    exit 1\r\nfi\r\necho &quot;Detected node IP: $NODE_IP&quot;\r\n\r\necho &quot;Installing K3s with proper kubeconfig permissions...&quot;\r\ncurl -sfL https:\/\/get.k3s.io | INSTALL_K3S_EXEC=&quot;server \r\n  --disable=traefik \r\n  --flannel-backend=host-gw \r\n  --tls-san=$NODE_IP \r\n  --bind-address=$NODE_IP \r\n  --advertise-address=$NODE_IP \r\n  --node-ip=$NODE_IP \r\n  --cluster-init \r\n  --write-kubeconfig-mode=644&quot; sh -\r\n\r\necho &quot;Setting up kubectl access for current user...&quot;\r\nmkdir -p ~\/.kube\r\nsudo cp \/etc\/rancher\/k3s\/k3s.yaml ~\/.kube\/config\r\nsudo chown $(id -u):$(id -g) ~\/.kube\/config\r\nsudo chmod 600 ~\/.kube\/config\r\n\r\nsudo systemctl daemon-reload\r\necho &quot;K3s installed successfully!&quot;\r\necho &quot;Restarting K3s service... (Wait 30 seconds)&quot;\r\nsudo systemctl restart k3s\r\nsleep 10\r\necho &quot;Checking cluster nodes Status...&quot;\r\nsleep 20\r\n\r\n\r\nkubectl get nodes\r\necho &quot;K3s Cluster Ready!!!&quot;<\/pre>\n<pre>sudo chmod +x k3s-setup.sh\r\nsudo .\/k3s-setup.sh<\/pre>\n<pre>kubectl get nodes\r\nkubectl get pods -A<\/pre>\n<pre>NAME          STATUS   ROLES                       AGE     VERSION\r\nraspberrypi   Ready    control-plane,etcd,master   2m   v1.33.5+k3s1<\/pre>\n<pre>sudo reboot<\/pre>\n<pre>kubectl get nodes<\/pre>\n<pre>sudo vi \/usr\/local\/bin\/k3s-dynamic-start.sh<\/pre>\n<pre>#!\/bin\/bash\r\nHOSTNAME=\"raspberrypi.local\"  # or your dynamic DNS\r\nIP=$(hostname -I | awk '{print $1}')\r\n\r\nexec \/usr\/local\/bin\/k3s \r\n  server \r\n  --disable=traefik \r\n  --flannel-backend=host-gw \r\n  --tls-san=$HOSTNAME \r\n  --bind-address=$IP \r\n  --advertise-address=$IP \r\n  --node-ip=$IP \r\n  --cluster-init \r\n  --write-kubeconfig-mode=644\r\n<\/pre>\n<pre>sudo chmod +x \/usr\/local\/bin\/k3s-dynamic-start.sh<\/pre>\n<p>edit k3s.service file <\/p>\n<pre>\/etc\/systemd\/system\/k3s.service<\/pre>\n<p>add following in k3s.service<\/p>\n<pre>ExecStart=\/usr\/local\/bin\/k3s-dynamic-start.sh<\/pre>\n<pre>sudo systemctl daemon-reexec\r\nsudo systemctl daemon-reload\r\nsudo systemctl restart k3s\r\n<\/pre>\n<p>configure k3s service file if required at \/etc\/systemd\/system\/k3s.service<\/p>\n<pre>[Unit]\r\nDescription=Lightweight Kubernetes\r\nDocumentation=https:\/\/k3s.io\r\nWants=network-online.target\r\nAfter=network-online.target\r\n\r\n[Install]\r\nWantedBy=multi-user.target\r\n\r\n[Service]\r\nType=exec\r\nEnvironmentFile=-\/etc\/default\/%N\r\nEnvironmentFile=-\/etc\/sysconfig\/%N\r\nEnvironmentFile=-\/etc\/systemd\/system\/k3s.service.env\r\nKillMode=process\r\nDelegate=yes\r\nUser=root\r\n# Having non-zero Limit*s causes performance problems due to accounting overhead\r\n# in the kernel. We recommend using cgroups to do container-local accounting.\r\nLimitNOFILE=1048576\r\nLimitNPROC=infinity\r\nLimitCORE=infinity\r\nTasksMax=infinity\r\nTimeoutStartSec=0\r\nRestart=always\r\nRestartSec=5s\r\nExecStartPre=-\/sbin\/modprobe br_netfilter\r\nExecStartPre=-\/sbin\/modprobe overlay\r\nExecStart=\/usr\/local\/bin\/k3s-dynamic-start.sh<\/pre>\n","protected":false},"excerpt":{"rendered":"sudo apt update &amp;&amp; sudo apt upgrade -y sudo apt install -y iptables iptables-persistent curl iproute2 dphys-swapfile grep&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_display_header_overlay":false,"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_reading_time":"","csco_page_toc_navigation":"","csco_post_video_location":[],"csco_post_video_location_hash":"","csco_post_video_url":"","csco_post_video_bg_start_time":0,"csco_post_video_bg_end_time":0,"csco_post_video_bg_volume":false,"footnotes":""},"categories":[2,3,4],"tags":[],"class_list":["post-48","post","type-post","status-publish","format-standard","category-docker","category-kubernetes","category-linux","cs-entry","cs-video-wrap"],"_links":{"self":[{"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/posts\/48","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/comments?post=48"}],"version-history":[{"count":0,"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/posts\/48\/revisions"}],"wp:attachment":[{"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/media?parent=48"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/categories?post=48"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ag.yomagnet.com\/index.php\/wp-json\/wp\/v2\/tags?post=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}