Kubernetes (K8s) is an open-source container orchestration platform that allows you to manage containerized applications across a cluster of nodes efficiently. Setting up a home lab provides a practical way to learn Kubernetes and test deployments in a controlled environment.
This guide walks you through the process of setting up a Kubernetes cluster using Ubuntu Server 24.04 with two nodes: one master (kb1) and one worker (kb2).
System Requirements
Each node should have the following specifications:
- CPU: 2 cores
- Memory: 3GB RAM
- Storage: 20GB
-
Node IP Addresses:
- kb1 (Master):
192.168.0.112
- kb2 (Worker):
192.168.0.113
- kb1 (Master):
Note: Ensure SSH connectivity between both nodes is configured properly.
Steps to Setting Up a Kubernetes (K8s) Cluster Home Lab on Ubuntu Server 24.04
Step 1: Configure Hostnames and Networking
First thing first, modify the hostname (optional) and update the host file to enable network communication.
To assign a hostname to each node, use the following command:
sudo hostnamectl set-hostname \<new-hostname\>
Example for the master node:
sudo hostnamectl set-hostname kb1
Add the IP-to-hostname mapping on each node to update network communication.
Next, modify the /etc/hosts
file on each node to enable network communication:
sudo nano /etc/hosts
Then, include the mapping:
192.168.0.112 kb1192.168.0.113 kb2
Now, you should save and exit the file.
Step 2: Disable Swap and Load Kernel Modules
In this next, the first thing to do is disable the Swap and Load Kernel Modules, using the command:
sudo swapoff \-a && sudo sed \-i '/ swap / s/^\\(.\*\\)$/\#\\1/g' /etc/fstab
To load the kernel modules using modpobe
:
sudo modprobe overlay && sudo modprobe br\_netfilter
To make these changes persistent:
sudo modprobe overlay && sudo modprobe br\_netfilter
Next, add kernel parameters such as IP forwarding. Create a file and apply the parameters using the sysctl
command:
sudo tee /etc/sysctl.d/kubernetes.conf \<\<EOFnet.bridge.bridge-nf-call-ip6tables \= 1net.bridge.bridge-nf-call-iptables \= 1net.ipv4.ip\_forward \= 1EOF
Next step is to load the above kernel parameters using the command below:
sudo sysctl \--system
Step 3: Install Containerd
Containerd is a container runtime that manages the complete container lifecycle on a host system. It's an industry-standard core container runtime that was originally developed by Docker and later donated to the Cloud Native Computing Foundation (CNCF).
To get started with its installation, first, install the required dependencies using the commands below:
sudo apt update && sudo apt install \-y curl gnupg2 software-properties-common apt-transport-https ca-certificates
Next, add the containerd repository:
curl \-fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg \--dearmor \-o /etc/apt/trusted.gpg.d/containerd.gpgsudo add-apt-repository "deb \[arch=amd64\] https://download.docker.com/linux/ubuntu $(lsb\_release \-cs) stable"
Now, its time to install containerd:
sudo apt update && sudo apt install containerd.io \-y
Next, configure containerd to use SystemdCgroup
.
containerd config default | sudo tee /etc/containerd/config.toml \>/dev/nullsudo sed \-i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
Restart containerd to see effect:
sudo systemctl restart containerd
Verify the status:
sudo systemctl status containerd
Output:
● containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-02-17 16:20:34 UTC; 2h 17min ago
Docs: https://containerd.io
Process: 738 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 741 (containerd)
Tasks: 156
Memory: 201.3M (peak: 229.5M)
CPU: 20min 13.594s
CGroup: /system.slice/containerd.service
├─ 741 /usr/bin/containerd
├─ 1138 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 53e05d7bda37772f5869ec026de03b40d4ce532ba0303c42be5184994439b3bf -address /run/containerd/containerd.sock
├─ 1139 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 5398ebda2355cad57be69e19bf098e4202fe259a61270ea9cc274b81f77977ab -address /run/containerd/containerd.sock
├─ 1140 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id e4f1f987a5fb8db03db049b518fdfe6680b8c83617733de91620948c6bc00c95 -address /run/containerd/containerd.sock
├─ 1150 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 24d231aefec7bde2646ae123758907e5d464973705d8c0cd9d8db67756c19ef2 -address /run/containerd/containerd.sock
├─ 1547 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 4d7ddac790ef53cb30823d45ed4b675d54cf66694833158f8d15f0ba93b93e2c -address /run/containerd/containerd.sock
├─ 2267 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 72b50ae3cea036f3b51e18bf9b900ccd46399fed052bf51a41bcea735062f413 -address /run/containerd/containerd.sock
├─ 2377 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 2fcb5f2766fc1ff28a8a020c10eb1aff4b1895eb7ade8af65c72bedd0a634ead -address /run/containerd/containerd.sock
├─ 2434 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id d6f43f441495e4a00387114d5d7462bc54b1a592bd41bc1ee1709d16d507633b -address /run/containerd/containerd.sock
└─27675 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 2b645f1523cda54eb099d35542d77347071c2cdaef648a7e5559ec01779bac29 -address /run/containerd/containerd.sock
Step 4: Add Kubernetes Package Repository
Kubernetes packages are not included in the default package repositories of Ubuntu 24.04. To install them, first, add the Kubernetes repository.
Start by downloading the public signing key for the repository using the curl
command.
curl \-fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg \--dearmor \-o /etc/apt/keyrings/k8s.gpg
Next, add the repository:
echo 'deb \[signed-by=/etc/apt/keyrings/k8s.gpg\] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/k8s.list
Step 5: Install Kubernetes Components
Install essential Kubernetes components such as kubeadm
, kubelet
, and kubectl
to manage the Kubernetes cluster:
sudo apt updatesudo apt install kubelet kubeadm kubectl \-y
Step 6: Initialize the Kubernetes Cluster (Master Node Only)
To initialize the control plane or master node using Kubeadm
, run the command:
sudo kubeadm init \--control\-plane\-endpoint=\<master-node-name\>
Example:
sudo kubeadm init \--control\-plane\-endpoint=kb1
Output:
Set up access to Kubernetes for the current user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Step 7: Join Worker Nodes in the Cluster
Add worker nodes to your Kubernetes cluster using the token generated during initialization.
Example:
sudo kubeadm join 192.168.0.112:6443 \--token \<your-token\> \--discovery-token-ca\-cert-hash sha256:\<your-hash\>
Verify node status on the master node, by running the command below on your terminal:
kubectl get nodes
Output:
NAME STATUS ROLES AGE VERSION
kb1 NotReady control-plane 10d v1.31.5
kb2 NotReady <none> 10d v1.31.5
If nodes appear as NotReady
, proceed to install a networking solution.
Step 8: Deploy the Calico Network Plugin
On the master node, run to install the Calico Network Plugin:
kubectl create \-f https://raw.githubusercontent.com/projectcalico/calico/v3\.28.2/manifests/calico.yaml
Confirm the node status has changed to Ready
:
kubectl get nodes
Output:
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-b8d8894fb-rz6zx 1/1 Running 3 (24h ago) 7d21h
calico-node-4klgg 1/1 Running 0 24h
calico-node-9c9lg 1/1 Running 0 24h
coredns-7c65d6cfc9-8f26s 1/1 Running 3 (24h ago) 7d21h
coredns-7c65d6cfc9-sgsvc 1/1 Running 3 (24h ago) 7d21h
etcd-kb1 1/1 Running 4 (24h ago) 10d
kube-apiserver-kb1 1/1 Running 4 (24h ago) 10d
kube-controller-manager-kb1 1/1 Running 9 (24h ago) 10d
kube-proxy-h5fnm 1/1 Running 2 (25h ago) 10d
kube-proxy-n9zts 1/1 Running 4 (24h ago) 10d
kube-scheduler-kb1 1/1 Running 7 (24h ago) 10d
Now, check the node status using the command:
kubectl get nodes
Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-app NodePort 10.110.254.203 <none> 80:31809/TCP 50s
Step 9: Deploy and Test an Application
In this section, we will first deploy and expose an NGINX instance to verify the setup.
Create a Namespace:
kubectl create ns demo-app
Check if namespace was created or not:
kubectl get namespace
Deploy NGINX replicas:
kubectl create deployment nginx\-app \--image nginx \--replicas 2 \--namespace demo\-app
Check the deployment:
kubectl get deployment \-n demo\-app
Expose the Deployment
kubectl expose deployment nginx-app \-n demo-app \--type NodePort \--port 80
Find the service port:
kubectl get svc \-n demo-app
Access the application using:
curl http://192.168.0.113:\<exposed-port\>
If successful, you should see the default NGINX welcome page.
Output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Conclusion
By following this guide, you've successfully set up a Kubernetes cluster on Ubuntu 24.04, installed essential components, and deployed a test application. This provides a solid foundation for further exploration into Kubernetes features and advanced configurations.
Top comments (0)