{"id":169205,"date":"2026-06-19T08:30:48","date_gmt":"2026-06-19T05:30:48","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=169205"},"modified":"2026-06-19T08:30:48","modified_gmt":"2026-06-19T05:30:48","slug":"install-k3s-opensuse-leap","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/install-k3s-opensuse-leap\/","title":{"rendered":"Install K3s Lightweight Kubernetes on openSUSE Leap 16"},"content":{"rendered":"<p>K3s is Kubernetes packaged as a single binary. It strips out the legacy and cloud-provider code, bundles containerd, and runs the whole control plane and a worker in one process, which makes it the fastest way to get a real cluster on a single openSUSE Leap 16 box. This guide installs K3s on openSUSE Leap 16, gets you a working <code>kubectl<\/code>, and deploys a real app you can reach over HTTP. Everything below was run on openSUSE Leap 16.0 in June 2026 with K3s v1.35.5.<\/p>\n\n<h2>Install K3s<\/h2>\n\n<p>The official installer detects the distribution and does the right thing. One command pulls the binary, creates a systemd service, and starts it:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>curl -sfL https:\/\/get.k3s.io | sudo sh -<\/code><\/pre>\n\n\n<p>On Leap 16 this does something worth calling out. Because SELinux runs in enforcing mode, the installer detects it and pulls in the <code>k3s-selinux<\/code> policy package automatically, so the host policy is in place with no manual policy work:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>(1\/1) Installing: k3s-selinux-1.6-1.sle.noarch\n[INFO]  systemd: Enabling k3s unit\n[INFO]  systemd: Starting k3s<\/code><\/pre>\n\n\n<p>Confirm the service is running:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>sudo systemctl is-active k3s<\/code><\/pre>\n\n\n<p>It returns <code>active<\/code> within a few seconds. Installing the policy package puts the SELinux rules on disk, but it does not by itself run the cluster confined. To actually enforce the policy on containerd, reinstall or start the service with the <code>--selinux<\/code> flag; the default install leaves K3s running unconfined.<\/p>\n\n<h2>Access the cluster<\/h2>\n\n<p>The installer creates a <code>kubectl<\/code> symlink in <code>\/usr\/local\/bin<\/code>, but that directory is not on sudo&#8217;s secure PATH, so <code>sudo kubectl<\/code> fails with command not found. Use the full path for a first check:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>sudo \/usr\/local\/bin\/k3s kubectl get nodes -o wide<\/code><\/pre>\n\n\n<p>The single node reports Ready as a control-plane, running containerd rather than Docker:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>NAME                    STATUS   ROLES           AGE   VERSION        OS-IMAGE             CONTAINER-RUNTIME\nlocalhost.localdomain   Ready    control-plane   22s   v1.35.5+k3s1   openSUSE Leap 16.0   containerd:\/\/2.2.3-k3s1<\/code><\/pre>\n\n\n<p>Running everything through sudo gets old fast. K3s writes its admin kubeconfig to <code>\/etc\/rancher\/k3s\/k3s.yaml<\/code>, readable only by root, so copy it into your user&#8217;s home and take ownership. After that, plain <code>kubectl<\/code> works:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>mkdir -p ~\/.kube\nsudo cp \/etc\/rancher\/k3s\/k3s.yaml ~\/.kube\/config\nsudo chown $(id -u):$(id -g) ~\/.kube\/config\nexport KUBECONFIG=~\/.kube\/config<\/code><\/pre>\n\n\n<p>Add the <code>KUBECONFIG<\/code> export to your <code>~\/.bashrc<\/code> so it survives new shells. Now confirm the same node without sudo:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>kubectl get nodes<\/code><\/pre>\n\n\n<p>K3s ships a working cluster, not only the API server. CoreDNS, the Traefik ingress controller, the ServiceLB load balancer, a local-path storage provisioner, and metrics-server all come up in <code>kube-system<\/code> on first boot, which is why a fresh install is immediately usable.<\/p>\n\n<h2>Deploy an app<\/h2>\n\n<p>Run a real workload to prove the cluster works end to end. Create a deployment and expose it on a NodePort:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>kubectl create deployment web --image=nginx:alpine\nkubectl expose deployment web --type=NodePort --port=80<\/code><\/pre>\n\n\n<p>Wait for the rollout to finish, then look at what you got:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>kubectl get pods,svc -l app=web<\/code><\/pre>\n\n\n<p>The pod is Running and the service has a NodePort in the 30000 to 32767 range, here 30100:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>NAME                       READY   STATUS    RESTARTS   AGE\npod\/web-5d4f7c4d94-hk7lp   1\/1     Running   0          20s\n\nNAME          TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE\nservice\/web   NodePort   10.43.222.47   &lt;none&gt;        80:30100\/TCP   20s<\/code><\/pre>\n\n\n<p>Hit the NodePort on localhost and you get the nginx welcome page back:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>curl -s -o \/dev\/null -w \"HTTP %{http_code}\\n\" http:\/\/localhost:30100\/<\/code><\/pre>\n\n\n<p>The request returns <code>HTTP 200<\/code>. The cluster is routing traffic to the pod.<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1020\" height=\"520\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/06\/wm-k3s-cluster-deploy-opensuse-leap.png\" alt=\"k3s kubectl get nodes deploy nginx and curl NodePort on openSUSE Leap 16\" class=\"wp-image-169204\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/06\/wm-k3s-cluster-deploy-opensuse-leap.png 1020w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/06\/wm-k3s-cluster-deploy-opensuse-leap-300x153.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/06\/wm-k3s-cluster-deploy-opensuse-leap-768x392.png 768w\" sizes=\"auto, (max-width: 1020px) 100vw, 1020px\" \/><\/figure>\n\n\n<p>Reaching that same port from another machine takes one more step, because firewalld is in the way.<\/p>\n\n<h2>Open the firewall for external access<\/h2>\n\n<p>The curl above worked because it came from the host itself. Open the single port this service uses so other machines can reach it:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --add-port=30100\/tcp\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n<p>If you plan to use the bundled Traefik ingress instead of NodePorts, open the standard web ports and let Traefik route by hostname:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --add-service=http --add-service=https\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n<p>With access sorted, a few defaults are worth tightening before this carries anything real.<\/p>\n\n<h2>Production notes and cleanup<\/h2>\n\n<p>A single-node K3s is perfect for a CI runner, a homelab, or a staging box, but a few defaults matter once it carries real load. The kubeconfig you copied has cluster-admin rights, so keep <code>~\/.kube\/config<\/code> at mode 600 and do not commit it. In production you&#8217;ll want more than one server node with an embedded etcd datastore so the control plane survives a reboot of any single machine. And if you bring your own ingress or load balancer, disable the bundled Traefik and ServiceLB at install time with <code>--disable=traefik --disable=servicelb<\/code> rather than fighting them later. Note that once ServiceLB is gone, <code>type=LoadBalancer<\/code> services sit at <code>EXTERNAL-IP: &lt;pending&gt;<\/code> until your own load balancer fills them, so keep using NodePort or ingress until that is in place.<\/p>\n\n<p>Removing K3s is a single script the installer left behind, which tears down the service, the containers, and the data:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>sudo \/usr\/local\/bin\/k3s-uninstall.sh<\/code><\/pre>\n\n\n<p>From here you have a real Kubernetes API to build on. The bundled containerd runtime means you do not need a separate <a href=\"https:\/\/computingforgeeks.com\/install-docker-podman-opensuse-leap\/\">Docker or Podman install<\/a> for the cluster, and if you would rather manage the host from a browser, <a href=\"https:\/\/computingforgeeks.com\/cockpit-web-console-opensuse-leap\/\">Cockpit<\/a> sits alongside K3s on the same machine.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>K3s is Kubernetes packaged as a single binary. It strips out the legacy and cloud-provider code, bundles containerd, and runs the whole control plane and a worker in one process, which makes it the fastest way to get a real cluster on a single openSUSE Leap 16 box. This guide installs K3s on openSUSE Leap &#8230; <a title=\"Install K3s Lightweight Kubernetes on openSUSE Leap 16\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/install-k3s-opensuse-leap\/\" aria-label=\"Read more about Install K3s Lightweight Kubernetes on openSUSE Leap 16\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":169206,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[316,299,317,47],"tags":[318,282,9986],"cfg_series":[39887],"class_list":["post-169205","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-containers","category-how-to","category-kubernetes","category-linux","tag-kubernetes","tag-linux","tag-opensuse","cfg_series-opensuse-leap-16"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/169205","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=169205"}],"version-history":[{"count":1,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/169205\/revisions"}],"predecessor-version":[{"id":169225,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/169205\/revisions\/169225"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/169206"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=169205"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=169205"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=169205"},{"taxonomy":"cfg_series","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/cfg_series?post=169205"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}