Demystifying Kubernetes: A Step-by-Step Guide to Setting Up Your Own Cluster

Whether you’re a budding developer or a seasoned system administrator, understanding how to set up a Kubernetes cluster is a valuable skill. This tutorial aims to demystify the installation process and guide you step by step through the necessary steps to create your own Kubernetes environment.

Get ready to dive into the fascinating world of container orchestration with Kubernetes. Whether you want to deploy large-scale applications in the cloud or create a local development environment, this guide will provide you with the knowledge and skills needed to succeed.

I tested this tutorial on a Minimal Ubuntu 24.04 Server and encountered no issues other than the need to install a text editor like vi or nano.

Prerequisites:

Two physical or virtual servers on the same network with a Linux distribution installed

Attention, at least one worker is required for Kubernetes to be functional. If you wish to deploy this solution on a single server, there are alternatives like MicroK8S.

Preparation to be done on the Master and the Worker

As always, we start by updating our server.

apt update
apt upgrade -y

In order for K8S (Kubernetes) to work, it is necessary to disable swap.

swapoff -a

To make this action persistent in case of a restart, we need to edit the fstab file to comment out the line related to swap.

sed -i '/\/swap.img/ s/^/#/' /etc/fstab

K8S requires a containerization solution. Docker has been deprecated by Kubernetes, so we install containerd. This will require loading some modules.

echo "overlay\nbr_netfilter" | tee /etc/modules-load.d/containerd.conf

Then apply the loading.

modprobe overlay
modprobe br_netfilter

To allow our servers to route traffic, we need to configure sysctl.

echo 'net.bridge.bridge-nf-call-ip6tables = 1' | tee -a /etc/sysctl.d/kubernetes.conf
echo 'net.bridge.bridge-nf-call-iptables = 1' | tee -a /etc/sysctl.d/kubernetes.conf
echo 'net.ipv4.ip_forward = 1' | tee -a /etc/sysctl.d/kubernetes.conf

Then validate it.

sysctl --system

We need to install some utilities necessary for containerd.

apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

Add the Docker repository to install containerd.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee -a /etc/apt/sources.list.d/docker.list > /dev/null

And install containerd.

apt update
apt install -y containerd.io

It is necessary to generate a default configuration for the containerd daemon.

containerd config default | tee /etc/containerd/config.toml >/dev/null 2>&1

Modify this configuration by enabling the use of systemd-based cgroups.

sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

Bonus step, we can replace the Kubernetes pause image used for sandboxes with version 3.9, which can improve the features and security of containers managed by containerd in a Kubernetes cluster.

sed -i 's/sandbox_image = "registry.k8s.io\/pause:3.6"/sandbox_image = "registry.k8s.io\/pause:3.9"/' /etc/containerd/config.toml

And a little refresh + activation of all that.

systemctl restart containerd
systemctl enable containerd

Let’s get down to business, installing Kubernetes! We start by adding the sources.


curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | gpg --dearmour -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb /" | tee /etc/apt/sources.list.d/kubernetes.list

And we install the Kubernetes suite.

apt update
apt install -y kubelet kubeadm kubectl

Attention, it is necessary to block the update of these packages to avoid surprises.

apt-mark hold kubelet kubeadm kubectl

On the Master only

We initialize the master with the following command, defining its IP and the internal network that pods will use.

kubeadm init --apiserver-advertise-address=192.168.1.1 \
                  --node-name=$HOSTNAME \
                  --pod-network-cidr="10.10.0.0/16"

A token will be generated, copy it somewhere as we’ll use it on the Worker to join the cluster.

Finally, we configure the Kubernetes client to apply usage rights to our user.

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

On the Worker only

Join the cluster using the token provided by the Master during initialization.

kubeadm join 192.168.1.1:6443 --token XXXXXXXXX --discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXX

Now you have a functional cluster 🙂

Leave a Comment