There are many tools out there to provision single-node Kubernetes clusters but kubeadm is the way to go for a production-like set-up. Although it is more difficult to create a cluster with kubeadm, with its configuration options you can tweak the cluster to your needs. By following this post you can easily create a Single-node Kubernetes Cluster using kubeadm on Ubuntu 20.04.
This post is for Ubuntu 20.04. Please see the updated version for Ubuntu 22.04.
Install general dependencies
Some packages need to be installed on your system for the commands we will use later.
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates \
curl gnupg lsb-release
Install docker from official repository
Installing docker from the official docker repository as this is the recommended way.
# Remove all other versions of docker from your systemsudo apt-get remove -y docker docker-engine \
docker.io containerd runc
# Add docker GPG keycurl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor \
-o /usr/share/keyrings/docker-archive-keyring.gpg
# Add docker apt repositoryecho \
"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
# Fetch the package lists from docker repositorysudo apt-get update
# Install docker and containerdsudo apt-get install -y docker-ce docker-ce-cli containerd.io
Configure docker for kubeadm
We have to do some configuration changes to docker to make it work with Kubernetes or the kubeadm pre-flight checks will fail.
# Configure docker to use overlay2 storage and systemdsudo mkdir -p /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {"max-size": "100m"},
"storage-driver": "overlay2"
}
EOF
# Restart docker to load new configuration sudo systemctl restart docker # Add docker to start up programs sudo systemctl enable docker # Allow current user access to docker command line sudo usermod -aG docker $USER1 # Download cri-dockerd curl -sSLo cri-dockerd_0.2.3.3-0.ubuntu-focal_amd64.deb \ https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.3/cri-dockerd_0.2.3.3-0.ubuntu-focal_amd64.deb # Install cri-dockerd for Kubernetes 1.24 support sudo dpkg -i cri-dockerd_0.2.3.3-0.ubuntu-focal_amd64.deb
Install kubeadm, kubelet & kubectl
You need to ensure the versions of kubeadm, kubelet and kubectl are compatible.
# Add Kubernetes GPG key sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg \ https://packages.cloud.google.com/apt/doc/apt-key.gpg # Add Kubernetes apt repository echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" \ | sudo tee /etc/apt/sources.list.d/kubernetes.list # Fetch package list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl # Prevent them from being updated automatically sudo apt-mark hold kubelet kubeadm kubectl
Ensure swap is disabled
The swap feature has to be disabled because it is not supported by Kubernetes. See the GitHub issue regarding swap on Kubernetes for details.
# See if swap is enabled
swapon --show
# Turn off swap
sudo swapoff -a
# Disable swap completely
sudo sed -i -e '/swap/d' /etc/fstab
Create the cluster using kubeadm
It’s only a single command to initialise the cluster but it won’t be very functional in single-node environments until we make some changes. Note that we’re providing the “–pod-network-cidr” parameter as required by our CNI plugin (Flannel). We’re also providing the “–cri-socket” parameter too, so kubeadm can use the right container runtime.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket=/var/run/cri-dockerd.sock
Configure kubectl
To be able to access the cluster we have to configure kubectl.
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Untaint node
We have to untaint the node to allow pods to be deployed to our single-node cluster otherwise your pods will be stuck in a pending state.
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
Install a CNI plugin
For networking to function, you must install a Container Network Interface (CNI) plugin. We’re installing flannel.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Install helm
To install our packages, we’re installing helm v3.
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
Install a CSI driver
We need to install a Container Storage Interface (CSI) driver for the storage to work. We’ll install OpenEBS.
# Add openebs repo to helmhelm repo add openebs https://openebs.github.io/charts
kubectl create namespace openebshelm
--namespace=openebs
install openebs openebs/openebs
Install a test application
To test the cluster, you can deploy WordPress. Note that we need to specify the storage class provided by our CSI.
# Add bitnami repo to helm
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install wordpress bitnami/wordpress \
--set=global.storageClass=openebs-hostpath
The end
You have successfully created a single-node Kubernetes Cluster using kubeadm on Ubuntu 20.04, and the cluster has everything you need to install your application.
If you’d like to watch this in a video, see below:
References
- Installing kubeadm | Kubernetes
- Creating a cluster with kubeadm | Kubernetes
- Container runtimes | Kubernetes
- Install Docker Engine on Ubuntu | Docker Documentation
- Disable swap on Ubuntu – Grasping Tech
- Kubernetes: Up and Running – 2nd Edition – Amazon
2 thoughts on “Provisioning Single-node Kubernetes Cluster using kubeadm on Ubuntu 20.04”