Install Kubernetes 1.26 on Ubuntu 20.04 or 22.04 LTS

Akriotis Kyriakos
7 min readAug 29, 2022

Step by step installation of 3 workers node Kubernetes 1.26 Cluster on Ubuntu Focal Fossa & Jammy Jellyfish

❗️ Updated for Kubernetes v1.26 - without dockershim💥

What is the goal ?

  • After completing all the steps below, you will have a 3-node Kubernetes 1.26 Cluster running on Ubuntu Focal Fossa or Jammy Jellyfish.

What do we need ?

  1. Ubuntu Live Server 20.04 or 22.04 images. You can find the images in ISO format here https://ubuntu.com/download/server.
  2. 4 Virtual Machines on the virtualization software of your preference. Setup 4VMs, one as a master node (3072 MB RAM, 1 vCPU), and three as workers (2048 MB RAM, 1 vCPU).
  3. Two distinct networks one NAT Network and one Host-Network (as I said I am using VirtualBox and this part will be based on its capabilities as well)

I am using VirtualBox for all my labs; I setup one base-image and then export it as OVA, which helps me spinning new VMs in seconds. I strongly advise you to do so.

Let’s lay some groundwork for the networks first. Create a dedicated named NAT Network for the lab:

and then a Host Network:

in every single VM assigned the NICs to the respective networks as following:

Configure host names and machine ids

If you have created the virtual machines either with cloning or via an OVA then you have to make sure that its machine have a unique machine id:

sudo rm -rf /etc/machine-id
sudo dbus-uuidgen --ensure=/etc/machine-id

In any other case, you can skip the commands above.

Configure the hostname of every box (master, wrk-0x) with the following command:

sudo hostnamectl set-hostname {{HOST_NAME}}.kubernetes.lab

and update the entries in /etc/hosts in every server accordingly:

sudo cat <<EOF>> /etc/hosts 
10.30.10.3 master.kubernetes.lab
10.30.10.4 wrk-01.kubernetes.lab
10.30.10.5 wrk-02.kubernetes.lab
10.30.10.6 wrk-03.kubernetes.lab
EOF

Obviously you have to replace the hostnames and IP addresses with the ones of yours. Remember that you need to set the static IP addresses that the DHCP server of the named NAT Network assigned to your machines.

restart all the machines:

sudo init 6

Perform the following steps on every node:

Update Ubuntu

sudo apt-get update && apt-get upgrade

Add Kubernetes repositories

sudo apt-get install -y apt-transport-https ca-certificates curl

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

echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" >> ~/kubernetes.list
sudo mv ~/kubernetes.list /etc/apt/sources.list.d

sudo apt-get update

Install Kubernetes tools

Install the following packages — targeting Kubernetes v1.26 — on every machine:

  • kubeadm: the command tool that we are going to use to bootstrap the Kubernetes cluster.
  • kubelet: the component that runs on all of the machines in your cluster responsible for starting pods and containers.
  • kubectl: the command line tool to interact with your cluster.
export VERSION = "1.26.0-00"

sudo apt-get install -y kubelet=$VERSION kubeadm=$VERSION kubectl=$VERSION kubernetes-cni
sudo apt-mark hold kubelet kubeadm kubectl

Configure IPv4 forwarding and iptables

Add the following kernel modules:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

and a) configure our linux boxes to forward IPv4 and b) instruct iptables to see bridged traffic:

sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

reload so changes take effect:

sudo sysctl --system

Install containerd

sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release -y

sudo mkdir -p /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

remove the already installed version of containerd (otherwise you will get the following error):

[ERROR CRI]: container runtime is not running: output: time=”” level=fatal msg=”validate service connection: CRI v1 runtime API is not implemented for endpoint ”unix:///var/run/containerd/containerd.sock\”: rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService”

sudo apt remove containerd 
sudo apt update
sudo apt install containerd.io -y
sudo rm /etc/containerd/config.toml
sudo systemctl restart containerd

Disable swap

sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
sudo swapoff -a

Make sure not to forget the first command, otherwise disabling swap setting will reset after every reboot!

The bootstrapping of our nodes is now completed. We are ready to initialize our cluster with kubeadm. Perform the following actions on the master node:

Initialize the cluster with kubeadm

Make sure kubelet daemon is enabled:

sudo systemctl enable kubelet

and then initialize the cluster:

sudo kubeadm init --v=5 \
--upload-certs \
--control-plane-endpoint master.kubernetes.lab:6443 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=NumCPU

The CIDR 10.244.0.0/16 is the default one that is used from flannel, that we are going to install later as our network. If you wish using another CIDR, don’t forget to amend as well the flannel’s manifest with the new CIDR value of your choice.

The ignore-preflight-errors clause allows us to use only one vCPU in our VMs, otherwise kubeadm demands a minimum of two.

Configure kubectl

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

Get the worker nodes join command

Run this command on the master node:

kubeadm token create --print-join-command

Run the output of this command on every worker node. Output might differ depending your kubeadm init configuration , and of course you will see other hashes:

kubeadm join 192.168.1.210:6443 --token zhdfbx.396793mudqat70dj --discovery-token-ca-cert-hash sha256:63a17b1e628200bb32a9b63d70b605214c1337833cc81e1ce6e30d02d8acd8be

Deploy Pod Network

Back on the master node. Make sure that all worker nodes have successfully joined the cluster:

kubectl get nodes -o wide

As we mentioned during initialisation, in this lab we are going to go with flannel as our network. If you haven’t chosen another CIDR for the POD Network during kubeadm init then you don’t need to amend the manifest of flannel. Run the following command on the master node:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Wait until all pods in namespaces kube-flannel and kube-proxy settle to Running state:

kubectl get pods -A -o wide

If you want to observe the changes happening real time and not reissue the command over and over again, just add the clause -w to the command above.

You cluster is ready to go !

Deploy Kubernetes Metrics Server

Kubernetes Metrics Server measures the usage of CPU and memory across the cluster. It collects metrics in order to provide resource usage statistics for monitoring purposes on cluster, node or pod level and for assisting Horizontal Pod Autoscaler to automatically scale workloads based on quantitates factors.

First install Helm, either on your host or on your master node:


curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null

sudo apt-get install apt-transport-https --yes

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list

sudo apt-get update
sudo apt-get install helm --yes

and then install the charts of metrics-server:


helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo update

helm install metrics-server metrics-server/metrics-server --namespace kube-system

Access your cluster from your host machine

If you remember we created our VMs with two NICs. The second one was a Host Network, and this one places the VMs in the same virtual network with our physical host computer. Add the following entries in the /etc/hosts of your laptop:

sudo cat <<EOF>> /etc/hosts 
192.168.57.3 master.kubernetes.lab
192.168.57.4 wrk-01.kubernetes.lab
192.168.57.5 wrk-02.kubernetes.lab
192.168.57.6 wrk-03.kubernetes.lab
EOF

Obviously you have to replace hostnames and IP addresses with the ones of yours. Remember that you need to set the static IP addresses that the DHCP server of the Host Network assigned to your virtual machines.

Merge the contents of the .kube/config of the newly created cluster with the the .kube/config in your laptop and now you can use kubectl directly from your laptop pointing the Kubernetes cluster in the virtual machines.

In the next article, we will see how to deploy a Load Balancer on an on-prems Kubernetes cluster:

I hope you found this article useful, stay tuned for more Kubernetes content!

Follow up

If you want to automate and streamline the process, check out how you could pack all those steps above using Vagrant:

--

--

Akriotis Kyriakos

talking about: kubernetes, golang, open telekom cloud, aws, openstack, sustainability, software carbon emissions