How to Deploy Kubernetes with Kubeadm and containerd

There’s no easy way to say this, but Kubernetes is challenging. And although at one time it was actually fairly simple to deploy a Kubernetes cluster to bare metal (thanks, in part, to Docker), it’s not quite as simple as it once was. To complicate matters even further, there’s an almost endless amount of paths to getting the platform up and running.
Which one do you choose? The answer to that question depends on what you’re doing with Kubernetes, the platform you plan on deploying it to, and your operating system of choice.
One method of deploying a Kubernetes cluster is with kubeadm (a tool that helps fast-track your deployment) and containerd (a container runtime engine). That’s the method I want to illustrate here. Walk through this process and you’ll wind up with a working Kubernetes cluster. I’m going to limit it to just a master and one node (for simplicity), but you can deploy as many nodes as you need.
To do this, you’ll need at least two machines (one for the master and one for the node). I’m going to be demonstrating on my server of choice, Ubuntu 20.04). Each machine should have at least 2GB of RAM and the master should have at least two CPUs.
Set the Hostnames and Hosts Files
The first thing we’re going to do is set the hostnames for each machine. First, log into your master and issue the command:
sudo hostnamectl set-hostname kubemaster
Next, edit the hosts file with the command:
sudo nano /etc/hosts
In that file, add the following at the bottom:
1 2 |
kubemaster IP_ADDRESS kubenode1 IP_ADDRESS |
Where IP_ADDRESS is the IP address for each machine. Save and close the file.
Log into the node machine and set the hostname with:
sudo hostnamectl set-hostname kubenode1
Edit the /etc/hosts file in the same way you did on the master (using the same settings).
Install the Necessary Software
On both machines, you’ll need to install a few pieces of software. First, log into the master and Run an update/upgrade with the commands:
sudo apt update
sudo apt upgrade -y
If the kernel is upgraded, make sure to reboot the machine.
After the upgrade completes, install the first dependencies with:
sudo apt install curl apt-transport-https -y
Next, add the necessary GPG key with the command:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
Add the Kubernetes repository with:
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Update apt:
sudo apt update
Install the required software with the command:
sudo apt -y install vim git curl wget kubelet kubeadm kubectl
Finally place kubelet, kubeadm, and kubectl on hold with:
sudo apt-mark hold kubelet kubeadm kubectl
Start and enable the kubelet service with:
sudo systemctl enable --now kubelet
Repeat this process on kubenode1.
Disable Swap
Next, we need to disable swap on both kubemaster and kubenode1. Open the fstab file for editing with:
sudo nano /etc/fstab
In that file, comment out the line:
1 |
/swap.img none swap sw 0 0 |
That line should now look like:
1 |
#/swap.img none swap sw 0 0 |
Save and close the file. You can either reboot to disable swap or simply issue the following command to finish up the job:
sudo swapoff -a
Enable Kernel Modules and Change Settings in sysctl
Next, we need to enable two kernel modules and add a few settings to sysctl. First, enable the overlay and br_netflilter modules with:
sudo modprobe overlay
sudo modprobe br_netfilter
Change the sysctl settings by opening the necessary file with the command:
sudo nano /etc/sysctl.d/kubernetes.conf
Look for the following lines and make sure they are set as you see below:
1 2 3 |
net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 |
Save and close the file. Reload sysctl with:
sudo sysctl --system
Make sure to take care of the above on both kubemaster and kubenode1.
Install containerd
We’ll now install the containerd runtime engine. This is done on both machines. The first thing to do is configure the persistent loading of the necessary containerd modules. This is done with the following command (which you should copy and paste as-is):
1 2 3 4 |
sudo tee /etc/modules-load.d/containerd.conf <<EOF overlay br_netfilter EOF |
Once again, we reload the configuration with:
sudo sysctl --system
Install the necessary dependencies with:
sudo apt install curl gnupg2 software-properties-common apt-transport-https ca-certificates -y
Add the GPG key with:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Add the required repository with:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
Install containerd with the commands:+-
sudo apt update
sudo apt install containerd.io -y
Change to the root user with:
sudo su -
Create a new directory for containerd with:
mkdir -p /etc/containerd
Generate the configuration file with:
containerd config default>/etc/containerd/config.toml
Exit from the root user with:
exit
Restart containerd with the command:
sudo systemctl restart containerd
Enable containerd to run at startup with:
sudo systemctl enable containerd
Finally, you need to create a new directory to house a configuration file and give it the proper permissions which is done with the following commands:
mkdir -p $HOME/.kube
sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Initialize the Master Node
Go to kubemaster and pull down the necessary container images with:
sudo kubeadm config images pull
Now, using the kubemaster IP address initialize the master node with:
sudo kubeadm init --pod-network-cidr=IP/16
Where IP is the IP address of kubemaster. When the initialization command, you’ll be presented with something like:
sudo kubeadm join 192.168.1.100:6443 --token 0dt0kt.h4i71m34tbfqup83 --discovery-token-ca-cert-hash sha256:c74be4fd295c172ba0fd6bdae870a834b051327c45fa46cc9d738e74f5de82a0
The above command is what you then run on kubenode1 to join it to the cluster. The join should happen very quickly. Once it completes, go back to kubemaster and issue the command:
kubectl get nodes
You should see both your master and node listed. Congratulations, you’ve just deployed a Kubernetes cluster and can use it for development purposes.
I wouldn’t suggest using this for production because it’s too small to scale and we’ve not taken security into account (such as using SSL certs). But this is a great way to practice deploying the cluster and a viable introduction for Kubernetes development.