Skip to main content

🚀 Kubernetes Cluster Setup with kubeadm

This guide provides a step-by-step process to set up a Kubernetes cluster using kubeadm on multiple nodes.


🏗️ Cluster Architecture

  • 3 VMs on Cloud
  • Master Nodes: These nodes play a crucial role in managing the control API calls for various components within the Kubernetes cluster. This includes overseeing pods, replication controllers, services, nodes, and more.
  • Worker Nodes: Worker nodes are responsible for providing runtime environments for containers. A group of container pods can extend across multiple worker nodes, ensuring optimal resource allocation and management.

🔄 Cluster Components

  1. API Server: Frontend for Kubernetes that processes API requests.
  2. etcd: A distributed key-value store for cluster data.
  3. Controller Manager: Ensures the desired cluster state.
  4. Scheduler: Assigns workloads to worker nodes.
  5. Kubelet: Agent that runs on each node to ensure container health.
  6. kube-proxy: Handles network communication.
  7. Container Runtime: Runs containerized applications (e.g., containerd).

Network Setup: Open Required Ports 🔓

Control Plane

ProtocolDirectionPort RangePurposeUsed By
TCPInbound6443Kubernetes API serverAll
TCPInbound2379-2380etcd server client APIkube-apiserver, etcd
TCPInbound10250Kubelet APISelf, Control plane
TCPInbound10259kube-schedulerSelf
TCPInbound10257kube-controller-managerSelf

Note: Although etcd ports are included in the control plane section, you can also host your own etcd cluster externally or on custom ports.

Worker Nodes

ProtocolDirectionPort RangePurposeUsed By
TCPInbound10250Kubelet APISelf, Control plane
TCPInbound10256kube-proxySelf, Load balancers
TCPInbound30000-32767NodePort Services†All

🛠️ Master Node Setup

🔹 Run these commands on the master node:

1️⃣ Disable Swap (Required for Kubernetes to work correctly)

swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

2️⃣ Update Kernel Parameters (For network bridging and packet forwarding)

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

sudo modprobe overlay
sudo modprobe br_netfilter

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

sudo sysctl --system

3️⃣ Install Container Runtime (Using containerd)

curl -LO https://github.com/containerd/containerd/releases/download/v1.7.14/containerd-1.7.14-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.7.14-linux-amd64.tar.gz
curl -LO https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo mkdir -p /usr/local/lib/systemd/system/
sudo mv containerd.service /usr/local/lib/systemd/system/
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

Check if containerd is running:

systemctl status containerd

4️⃣ Install runc (OCI Runtime for containers)

curl -LO https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc

5️⃣ Install CNI Plugins (Networking for Kubernetes)

curl -LO https://github.com/containernetworking/plugins/releases/download/v1.5.0/cni-plugins-linux-amd64-v1.5.0.tgz
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.5.0.tgz

6️⃣ Install kubeadm, kubelet, and kubectl

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

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -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/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet=1.30.0-1.1 kubeadm=1.30.0-1.1 kubectl=1.30.0-1.1 --allow-downgrades --allow-change-held-packages
sudo apt-mark hold kubelet kubeadm kubectl

Check installed versions:

kubeadm version
kubelet --version
kubectl version --client

7️⃣ Initialize the Control Plane

sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=$(hostname -I | awk '{print $1}') --node-name $(hostname)

📌 Copy the kubeadm join command displayed after initialization!

8️⃣ Configure kubectl for Master Node

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

9️⃣ Install a CNI Plugin (Calico for Networking)

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/custom-resources.yaml
kubectl apply -f custom-resources.yaml

🛠️ Worker Node Setup

🔹 Run these commands on worker nodes:

1️⃣ Disable Swap

swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

2️⃣ Update Kernel Parameters

(Same as in Master Node, run the same commands here)

3️⃣ Install Container Runtime (Same as Master Node)

4️⃣ Install runc (Same as Master Node)

5️⃣ Install CNI Plugins (Same as Master Node)

6️⃣ Install kubeadm, kubelet, and kubectl (Same as Master Node)

7️⃣ Join Worker Nodes to the Cluster

Run the kubeadm join command copied from the master node. If you forgot it, regenerate it on the master node:

kubeadm token create --print-join-command

Then, execute the command on the worker nodes:

sudo kubeadm join <MASTER_IP>:6443 --token <TOKEN> --discovery-token-ca-cert-hash sha256:<HASH>

🎯 Verify the Cluster

On the master node, check if all nodes have joined successfully:

kubectl get nodes

You should see output similar to:

NAME         STATUS   ROLES    AGE   VERSION
master Ready control-plane 10m v1.30.0
worker-1 Ready <none> 5m v1.30.0
worker-2 Ready <none> 5m v1.30.0

✅ Congratulations! Your Kubernetes cluster is up and running! 🚀🎉