Skip to content

Instantly share code, notes, and snippets.

@Andygol
Created December 12, 2025 09:32
Show Gist options
  • Select an option

  • Save Andygol/37d1397423e535bd0f7fabb593e81c41 to your computer and use it in GitHub Desktop.

Select an option

Save Andygol/37d1397423e535bd0f7fabb593e81c41 to your computer and use it in GitHub Desktop.
Deploying a K8s cluster using kubeadm

Deploying a K8s cluster using kubeadm

  1. The nodes-bootstrap.sh script will help you create three multipass virtual machines named k8s-control, k8s-worker-1, and k8s-worker-2 for further cluster deployment.

  2. Initialize the control panel on the k8s-control node

    multipass shell k8s-control
    
    CONTROL_IP=$(hostname -I | awk ‘{print $1}’)
    
    sudo kubeadm init \
       --pod-network-cidr=10.244.0.0/16 \
       --apiserver-advertise-address=$CONTROL_IP
  3. Configure kubectl on the control panel node

   mkdir -p ~/.kube
   sudo cp /etc/kubernetes/admin.conf ~/.kube/config
   sudo chown $(id -u):$(id -g) ~/.kube/config
  1. Install Flannel on the control plane (to create a Pod network)
  kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
  1. Join the worker nodes.

    for NODE in k8s-worker-1 k8s-worker-2; do
       multipass exec $NODE -- sudo kubeadm join 192.168.2.26:6443 \
         --token bsw6fd.e7624wl2688fybjx \
         --discovery-token-ca-cert-hash sha256:7850aa1c6181277e284a08b81256979db25698a89982f0885540376a5376e0bd
     done

Warning

In your case, the IP, token, and hash will be different! Use the command you got from kubeadm init.

  1. Log back into the control panel node and check the connection of the worker nodes to the cluster

    multipass shell k8s-control
    kubectl get nodes

    You should see three nodes with the status Ready:

   NAME            STATUS   ROLES           AGE   VERSION
   k8s-control     Ready    control-plane   5m    v1.34.0
   k8s-worker-1    Ready    <none>          2m    v1.34.0
   k8s-worker-2    Ready    <none>          2m    v1.34.0

If the status is NotReady, wait a minute — Flannel is still configuring ⏳

#!/usr/bin/env bash
# List of nodes
NODES=(k8s-control k8s-worker-1 k8s-worker-2)
echo "=== Starting to prepare all Kubernetes nodes ==="
###############################################################################
# 1. SYSTEM UPDATE
###############################################################################
echo "=== [1/7] System update on all nodes ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- bash -c "
sudo apt-get update &&
sudo apt-get upgrade -y
"
done
###############################################################################
# 2. DISABLING THE FIREWALL (simplified configuration)
###############################################################################
echo "=== [2/7] Disabling the firewall on all nodes ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- sudo ufw disable
done
###############################################################################
# 3. LOADING THE NECESSARY KERNEL MODULES
###############################################################################
echo "=== [3/7] Configuring kernel modules ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- bash -c "
echo -e 'overlay\nbr_netfilter' | sudo tee /etc/modules-load.d/k8s.conf
sudo modprobe overlay
sudo modprobe br_netfilter
"
done
###############################################################################
# 4. CONFIGURING Network Settings
###############################################################################
echo "=== [4/7] Configuring sysctl parameters ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- bash -c "
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
"
done
###############################################################################
# 5. INSTALLING containerd
###############################################################################
echo "=== [5/7] Installing containerd ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- sudo apt-get install -y containerd
done
###############################################################################
# 6. CONFIGURATION containerd, SystemdCgroup, and CRICTL
###############################################################################
echo "=== [6/7] Configuring containerd and CRI ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- bash -c "
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# Updating sandbox image
sudo sed -i 's/registry.k8s.io\\/pause:3.8/registry.k8s.io\\/pause:3.10.1/' /etc/containerd/config.toml
# Enabling cgroup mode via systemd
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# Adding config for crictl
sudo tee /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
sudo systemctl restart containerd
sudo systemctl enable containerd
"
done
###############################################################################
# 7. INSTALLATION kubeadm, kubelet, kubectl
###############################################################################
echo "=== [7/7] Встановлення Kubernetes компонентів ==="
for NODE in "${NODES[@]}"; do
multipass exec $NODE -- bash -c "
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/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.34/deb/ /' \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
sudo systemctl enable kubelet
"
done
###############################################################################
# 8. CONFIRMATION OF READINESS
###############################################################################
echo "=== All nodes are ready! ==="
echo “You can proceed to initialize the control plane.”
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment