Kubernetes Cluster (1.19.14) on Ubuntu Server 18.04

This guide will show you how to set up a small Kubernetes cluster with 1 master node and 2 worker nodes on Ubuntu 18.04.

Please install followed packaged on all nodes:

Install Docker #

Prepare packages

$ apt-get update
$ apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \


Add GPG keys:

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg


Add docker.io repo:

$ echo \
“deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable” | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install docker and docker-compose:

$ apt-get update
$ apt-get install docker-ce docker-ce-cli containerd.io docker-compose

Start docker.io:

$ service docker start

Now you need to check docker cgroup:

$ docker info | grep -i cgroup

If it’s not systemd, we need to change it. Please creating file /etc/docker/daemon.json and paste following content:

“exec-opts”: [“native.cgroupdriver=systemd”]

Now restart docker:

$ systemctl restart docker

Kubernetes #

Add GPG keys:

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add

Add Kubernetes repo:

$ apt-add-repository “deb http://apt.kubernetes.io/ kubernetes-xenial main”

Install kubeadm (1.19)

$ apt install kubeadm=1.19.14-00 kubelet=1.19.14-00 kubectl=1.19.14-00 kubernetes-cni

Prevent Kubernetes updates

$ apt-mark hold kubelet kubeadm kubectl


On a master node:

Initialize your Kubernetes master node:

$ kubeadm init

Before you start joining to the master node on worker nodes, you need to copy kube config into your /root/.kube directory:

$ mkdir -p $HOME/.kube
$ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ chown $(id -u):$(id -g) $HOME/.kube/config


Network installation

Now install network driver (Weave Net):

$ kubectl apply -f “https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d ‘\n’)”


On worker nodes:

Before you use kubeadm join command on your worker nodes, please edit /etc/hosts file and provide on all nodes IP address and hostname of all existing nodes.
Now use kubeadm join command on worker nodes and wait for deployment.

On a master node:

Now check your nodes:

$ kubectl get nodes -A


LoadBalancer Metallb installation

If your nodes are ready, you can now install LoadBalancer inside your cluster:

$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml


Ingress Nginx installation

Now we need to install an ingress controller:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml


(Optional) Kubernetes Dashboard #

If you would like to visualize your Kubernetes Cluster, you can install the official dashboard:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml

You can reach it from your web browser, however, it needs a few steps:

Service account – please create file service-account.yaml

apiVersion: v1
kind: ServiceAccount
name: service-account
namespace: kube-system

Service role – please create file service-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
name: service-account
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
– kind: ServiceAccount
name: service-account
namespace: kube-system

Now apply both files:

$ kubectl apply -f service-account.yaml
$ kubectl apply -f service-role.yaml

Now you need to get your auth token:

$ kubectl -n kube-system get secrets | grep service-account

Copy your service account name and type:

$ kubectl -n kube-system describe secret service-account-{random}

Copy TOKEN and save it. You will use it to authorize inside Kubernetes Dashboard.
Now re-login to master node with SSH tunneling:

$ ssh root@k8s-master -L 8001:localhost:8001

Now run kubectl proxy:

$ kubectl proxy &

Open now your web browser and paste the following URL:



Your Kubernetes cluster is ready!