Deploy Kubernetes Cluster on Linux With k0s

Have you ever wondered if there is any simple way to setup a Kubernetes cluster? Yes there is. K0s is a simple, solid and certified Kubernetes distribution that can be deployed on any infrastructure. This means that K0s can run on any private or public cloud environment.

K0s is bundled into a binary with all the minimal required dependencies for installation deployed with a single command. This drastically reduces the complexity of installing and configuring your Kubernetes cluster. This also means that engineers with no skills on Kubernetes can still be able to setup a Kubernetes cluster.

K0s is also as secure as the normal K8s as the vulnerability issues can easily be fixed directly in the k0s distribution. K0s is also open source!

K0s is a fully featured Kubernetes deployment and ships with all the features of Kubernetes. Some of these features include:

  1. Container Runtime — ContainerD
  2. Support for all Linux OS and Windows 2019
  3. Support for x86–64, ARM64 and ARMv7
  4. Built-in security and conformance for CIS
  5. Supported CNI providers: Kube-Router(Default), Calico, custom.
  6. Supported storage & CSI providers — Kubernetes-in-Three storage providers, custom.

There are more features to k0s which are discussed on their official website.

This article will cover the simple steps required to setup a k0s cluster on Linux. The steps are highlighted below:

  1. Setup K0s control plane
  2. Join worker node to K0s cluster
  3. Add more controller nodes to the k0s cluster
  4. Deploy sample application on k0s
  5. Manage k0s cluster remotely

As we had highlighted before, K0s is simple to setup. Run the command below to download and install K0s on the node you intend to use as the control plane:

curl -sSLf | sudo sh

The command above downloads and saves the k0s binary file to /usr/local/bin. Please make sure that the path /usr/local/bin has been declared as an binary path. You can verify that by running the command echo $PATH. If the path above is not listed, you will have to add the path using the command below:

echo "export PATH=\$PATH:/usr/local/bin" | sudo tee -a /etc/profile

source /etc/profile

Switch to root user:

sudo su -

Install the k0s controller and enable worker.

# k0s install controller --enable-worker

INFO[2021-07-13 11:03:26] no config file given, using defaults

INFO[2021-07-13 11:03:26] creating user: etcd

INFO[2021-07-13 11:03:26] creating user: kube-apiserver

INFO[2021-07-13 11:03:27] creating user: konnectivity-server

INFO[2021-07-13 11:03:28] creating user: kube-scheduler

INFO[2021-07-13 11:03:28] Installing k0s service

Wait for the installation to complete then start the controller.

systemctl start k0scontroller

Check the status of the controller to see if it has started successfully.

# systemctl status k0scontroller

● k0scontroller.service - k0s - Zero Friction Kubernetes

Loaded: loaded (/etc/systemd/system/k0scontroller.service; enabled; vendor preset: disabled)

Active: active (running) since Tue 2022-04-17 15:55:02 EAT; 58s ago


Main PID: 76539 (k0s)

Tasks: 158

Memory: 293.6M

CGroup: /system.slice/k0scontroller.service

├─ 5095 /var/lib/k0s/bin/containerd-shim-runc-v2 -namespace -id aeb8cd09ada8cdf6abb1750558573cfe401ea5803a6358efb85be5cf76aea88e -address /run/k0s/containerd.sock

├─ 5113 /var/lib/k0s/bin/containerd-shim-runc-v2 -namespace -id 7aee6f50d8b084bf75fa5224420b6d24f101d547eea7c093e43c6d0d85e9a0cb -address /run/k0s/containerd.sock

├─ 6757 /var/lib/k0s/bin/containerd-shim-runc-v2 -namespace -id 3c1f1327416489fa53386bb01bf6aad7ab2b0c732191eb04104f8338d6c78ddc -address /run/k0s/containerd.sock

├─ 6858 /var/lib/k0s/bin/containerd-shim-runc-v2 -namespace -id d0300d503aa4048f0c766b739084f5deba145ac0a0b6297689dff6d2f81d7c12 -address /run/k0s/containerd.sock

├─ 6964 /var/lib/k0s/bin/containerd-shim-runc-v2 -namespace -id cefba75a46f0731605ed16bacb7a15431425a1a55d6c62972bbe1447761555c2 -address /run/k0s/containerd.sock

├─39473 /var/lib/k0s/bin/containerd-shim-runc-v2 -namespace -id aa36e5a1504b238c886da9eb24cc39d62b69a5758c835dd43d055d4d70ec13bb -address /run/k0s/containerd.sock

├─76539 /usr/local/bin/k0s controller --enable-worker=true

├─76589 /var/lib/k0s/bin/etcd --cert-file=/var/lib/k0s/pki/etcd/server.crt --peer-cert-file=/var/lib/k0s/pki/etcd/peer.crt --log-level=info --auth-token=jwt,pub-key=/var/lib/k0s/pki/etcd/,priv>

├─76601 /var/lib/k0s/bin/kube-apiserver --kubelet-client-certificate=/var/lib/k0s/pki/apiserver-kubelet-client.crt --proxy-client-key-file=/var/lib/k0s/pki/front-proxy-client.key --requestheader-clie>

├─76613 /var/lib/k0s/bin/konnectivity-server --agent-service-account=konnectivity-agent --authentication-audience=system:konnectivity-server --logtostderr=true --stderrthreshold=1 --cluster-cert=/var>

├─76621 /var/lib/k0s/bin/kube-scheduler --authorization-kubeconfig=/var/lib/k0s/pki/scheduler.conf --kubeconfig=/var/lib/k0s/pki/scheduler.conf --v=1 --bind-address= --leader-elect=true --pr>

├─76626 /var/lib/k0s/bin/kube-controller-manager --requestheader-client-ca-file=/var/lib/k0s/pki/front-proxy-ca.crt --service-cluster-ip-range= --allocate-node-cidrs=true --profiling=fals>

├─76639 /usr/local/bin/k0s api --config= --data-dir=/var/lib/k0s

└─76650 /var/lib/k0s/bin/containerd --root=/var/lib/k0s/containerd --state=/run/k0s/containerd --address=/run/k0s/containerd.sock --log-level=info --config=/etc/k0s/containerd.toml

Enable the service to start at boot

sudo systemctl enable k0scontroller

You can now access your k0s cluster using the command prefix:

# k0s kubectl

K0s ships with kubeadmin and kubectl. Therefore you don’t have to install anything else to use the cluster.

Check that the pods have started.

k0s kubectl get pod

Sample output:

# k0s kubectl get pods --all-namespaces


kube-system coredns-8565977d9b-pxtf2 1/1 Running 0 85s

kube-system konnectivity-agent-cmtb4 1/1 Running 0 42s

kube-system kube-proxy-5w57n 1/1 Running 0 84s

kube-system kube-router-w8bkr 1/1 Running 0 84s

kube-system metrics-server-74c967d8d4-sxvcp 1/1 Running 0 77s

Note that it takes sometime for the pods to come up.

Check the available nodes

# k0s kubectl get nodes -o wide


rocky-linux-02.novalocal Ready control-plane 98s v1.23.5+k0s Rocky Linux 8.4 (Green Obsidian) 4.18.0-305.7.1.el8_4.x86_64 containerd://1.5.11

The next phase is to add worker nodes to the k0s cluster. To do so, we need to download and install k0s binary file on the server that we intend to use as the worker node.

Before we can start setting up the worker node, we are required to generate the authentication token that we will use to join the node to the cluster.

On the controller node, run the command below to generate the token

k0s token create --role=worker

The above command generates a string of characters that will be used to authenticate the worker node.

Download k0s binary on the worker node

sudo su -

curl -sSLf | sudo sh

When the binary finally downloads successfully, run the command below to authenticate the node to the controller.

k0s worker  &

Replace the with the token generated on the controller node in the previous step. e.g

sudo k0s worker "H4sIAAAAAAAC/2xVUY+bPBZ9n1+RPzCtDcmoRNqHktghZHBqY5vgN8B0IDbEBSZhstr/vpq0lXal7+36nqNzrKure54K18p6GNtLv15c4VNl38epHsb10/PiT71+WiwWi7EervWwXjTT5Mb1168w8L7Al29fIABfPBisX5ZL/0Gs6mFqf7ZVMdXPxfvUXIZ2+njWxVSsF68pmF5TuGFCx7wNt0zGIhUqpgAL9sDAtDE....6n31Hxu/4dFX9z48H6bLyPj9d7Wdt6ei4vl2mchsL9v9r7MNT99PxX6dE0ba/Xi82l/9m+Pbmh/lkPdV/V43rx7/88fao+zP+I/IP8w/jxheli6n69COr6rfW/jFr/fHmf9bJrpzME8Om/AQAA//8V8FiGBwcAAA==" &

Give the node some few moments before it becomes ready. This is because the pods for nework, dns and proxy are being initialized.

You can then check the available nodes to confirm if the node has been added successfully.

# kubectl get nodes -o wide


rocky8 Ready 6h13m v1.23.5+k0s Rocky Linux 8.4 (Green Obsidian) 4.18.0-305.7.1.el8_4.x86_64 containerd://1.4.6

node01 Ready 70s v1.23.5+k0s CentOS Linux 7 (Core) 3.10.0-1160.31.1.el7.x86_64 containerd://1.4.6

Just like the worker nodes, we will need to create a token on the existing controller node for an aditional control node.

sudo su -

k0s token create --role=controller

Download the k0s binary on the host that you intend to use as a secondary control node:

sudo su -

curl -sSLf | sudo sh

Join the node to the cluster using the token generated earlier

k0s controller ""


k0s controller "H4sIAAAAAAAC/3RVwXKjOhbd5yv8A+kngZ2OXTWLxpaMcZBbQhJGO0AkYAlQA7GJp+bfp5J+XTWzeLure06do7p1656H3DWyGsam7zaLK3wo7fs4VcO4eXhc/F1vHhaLxWKshms1bBb1NLlx89dfcO19g0/P3yAA3zy43qyXS/+LWFbD1Lw2ZT5Vj/n7VPdDM3086nzKN4uXBEwvCdwyoSPeBDsmI5EIFVGABfvCwLQWFgNScNsRHLgThSyVZaBsFPDo5/32bMDX2jQCYS2X0iSCCR+LrLL7T/18Ni0eVttVkYMD6UfTdV8/Q7Kn7Xv6PiT258sT4b7+Pn65Mz9NZWw2PR99M4Dbn7f8H3Yai66fGP2FfTNJ3eLLZ999q8Pbiheq2GqiurcbP4938ePoW//H+L/IPDl/3XR6beVN1mMS+fvz9X396+L4en9++v93v9alfv7w//DQAA//8NPyCvDQcAAA=="

After a successful authentication, check the status of the new controller node:

# k0s status

Version: v1.23.5+k0s

Process ID: 76539

Parent Process ID: 1

Role: controller

Init System: linux-systemd

Service file: /etc/systemd/system/k0scontroller.service

We can confirm that the new node has joined and is running with the role of a controller. This means that the node won’t be listed on the available nodes when you run the get nodes command.

Be advised that setting up a secondary controller node may cause instability to your k0s cluster and it is advised that you use a single controller node at the moment.

You might want to manage your cluster remotely using the native kubectl. K0s stores the KUBECONFIG file at /var/lib/k0s/pki/admin.conf.

This means that you can easily copy the config file and use it to access your cluster remotely.

Copy the config file to the user home directory.

sudo cp /var/lib/k0s/pki/admin.conf ~/k0s.conf

Download the k0s.conf file form the controller node to your remote server

scp  @:~/k0s.conf .


scp clouduser@ .

Modify the host details in the k0s.conf from localhost to the IP address of the controller node. Then export the config file.

export KUBECONFIG=k0s.conf

You can now manage your cluster remotely using kubectl.

We can test if application deployment is working on the k0s cluster. We will use Nginx application.

kubectl apply -f - <apiVersion: apps/v1

kind: Deployment


name: nginx-deployment




app: nginx

replicas: 2




app: nginx



- name: nginx

image: nginx:latest


- containerPort: 80


Check if the pod is running:

$ kubectl get pods


nginx-deployment-585449566-csvsf 1/1 Running 0 105s

nginx-deployment-585449566-hhx6z 1/1 Running 0 106s

Two pods have started and are in running state. This is because we specified the number or replicas to 2 in our config file.

To expose the service, we will use NodePort service to expose nginx deployment

$ kubectl expose deployment nginx-deployment --type=NodePort --port=80

service/nginx-deployment exposed

Check the port on which the service has been exposed to

$ kubectl get svc


kubernetes ClusterIP 443/TCP 7h23m

nginx-deployment NodePort 80:31710/TCP 94s

The service has been exposed on port 31710 using NodePort. We can access the application on the browser by using the worker-node ip and the port.


To uninstall k0s you need to stop the k0s service then remove the installation on each node.

sudo k0s stop

Remove k0s setup

$ sudo k0s reset

INFO[2021-07-13 11:46:59] no config file given, using defaults

INFO[2021-07-13 11:46:59] * remove k0s users step:

INFO[2021-07-13 11:46:59] no config file given, using defaults

INFO[2021-07-13 11:47:03] * uninstal service step

INFO[2021-07-13 11:47:03] Uninstalling the k0s service

INFO[2021-07-13 11:47:03] * remove directories step

INFO[2021-07-13 11:47:04] * CNI leftovers cleanup step

INFO k0s cleanup operations done. To ensure a full reset, a node reboot is recommended.

That’s it all for deploying k0s cluster. We have discovered that there are very few steps involved in setting up this kind of cluster. Feel free to reach out in case you encounter problems in your setup.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

ComputingPost — Linux Howtos, Tutorials, Guides, News, Tips and Tricks.