Set Up Kubernetes Cluster

tags: CraftLab

1. Ubuntu Server Installation Steps

  1. Download ISO: Download the Ubuntu Server LTS version ISO file from the Ubuntu download page.
  2. Create Bootable USB: Use a tool like Rufus (Windows) or dd (Linux) to create a bootable USB drive.
  3. Install Ubuntu Server:
    • Boot from the USB drive and follow the on-screen prompts to install Ubuntu Server.
    • Choose a minimal installation (no graphical user interface) for better performance and simplicity.
    • Set up your network settings (you can opt for DHCP or static IP depending on your preferences).
    • Install OpenSSH server if you want to manage the server remotely via SSH.
  4. Post-Installation: After installation:
    • Update the system: sudo apt update && sudo apt upgrade -y
    • Install Docker and Kubernetes.

2. Disable swap

Run:

sudo swapoff -a

Run:

sudo vi /ect/fstab

File Editor:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/nvme0n1p2 during curtin installation
/dev/disk/by-uuid/fa8dbae5-5a0c-4dea-9cdb-c4e941b15da3 / ext4 defaults 0 1
# /boot/efi was on /dev/nvme0n1p1 during curtin installation
/dev/disk/by-uuid/61E4-E3E4 /boot/efi vfat defaults 0 1
#/swap.img      none    swap    sw      0       0
~
~

3. Install Docker and curl

Run:

sudo apt install docker.io -y

Run:

sudo apt install apt-transport-https curl -y

4. Add Kubernetes repository (v1.29)

Install curl and add apt registries

Run the following:

sudo apt install -y apt-transport-https ca-certificates curl
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/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.29/deb/ /" |
sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null

(optional 1) Removing registries in case of error

To remove repository:

sudo vi /etc/apt/sources.list.d/kubernetes.list

Remove or comment out the problematic entry:

# deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /

Save the file and exit


(optional 2) Alternative to removing registries in case of error

If the error still persists, it's worth checking other places where Kubernetes might be listed.

Check Other Files in /etc/apt/sources.list.d/:

ls /etc/apt/sources.list.d/

Then edit any other relevant files using nano or vi.

Output:

macc@craftlab:~$ ls /etc/apt/sources.list.d/
archive_uri-http_apt_kubernetes_io_-noble.list  kubernetes.list  ubuntu.sources  ubuntu.sources.curtin.orig

Notice the deprecated file: archive_uri-http_apt_kubernetes_io_-noble.list. Remove it or comment out

sudo vi /etc/apt/sources.list.d/archive_uri-http_apt_kubernetes_io_-noble.list

Remove or comment out the problematic entry:

# deb http://apt.kubernetes.io/ kubernetes-xenial main
# deb-src http://apt.kubernetes.io/ kubernetes-xenial main

5. Install kubelet, kubeadm, kubectl

Run the following:

sudo apt update
Err:5 https://packages.cloud.google.com/apt kubernetes-xenial Release
  404  Not Found [IP: 142.250.138.100 443]
...
E: The repository 'http://apt.kubernetes.io kubernetes-xenial Release' does not have a Release file.
sudo apt install -y kubelet kubeadm kubectl

Prevent automatic updates/removals of Kubernetes packages:

sudo apt-mark hold kubelet kubeadm kubectl

6. Initialize Kubernetes Cluster

Run the following command to start the initialization process:

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

Important Note: After running this command, you will see an output that includes a join token. This token will be used for adding worker nodes (if you have any). You don't need it now if you're just working with a single node, but keep it in mind if you expand your cluster later.

7. Set Up kubectl for your user

After the kubeadm init command completes, you'll need to set up kubectl to interact with your cluster as a non-root user. This is done by copying the Kubernetes config file to your user’s home directory.

Run the following commands:

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

This will set up kubectl to point to your newly created cluster and allow you to interact with it.

8. Make sure containerd is configured correctly

  1. Install and configure containerd
sudo apt update
sudo apt install -y containerd
  1. Generate a proper default config for containerd:
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

Kubelet expects containerd to use the systemd cgroup driver (to match kubelet).

Open the containerd config:

sudo vi /etc/containerd/config.toml

Under

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]

add or set:

  SystemdCgroup = true

Restart containerd and kubelet:

sudo systemctl restart containerd
sudo systemctl restart kubelet

9. Install the CNI plugin binaries

Without CNI plugin binaries in /opt/cni/bin, kubelet will refuse to launch any pod (including the API-server).

# create the directory
sudo mkdir -p /opt/cni/bin

# pick a release; here we use v1.1.1
VERSION="v1.1.1"

# download & extract
curl -fsSL \
  https://github.com/containernetworking/plugins/releases/download/$VERSION/cni-plugins-linux-amd64-$VERSION.tgz \
  | sudo tar -C /opt/cni/bin -xz

Also ensure the CNI config dir exists:

sudo mkdir -p /etc/cni/net.d

Then restart again:

sudo systemctl restart containerd
sudo systemctl restart kubelet

10. Verify the control-plane pods are now running

Give kubelet 10–15 seconds, then check with crictl (not docker):

sudo crictl ps --all

You should see the API server, etcd, scheduler, and controller-manager static pods come up.

Alternatively you can grep for kube-apiserver

sudo crictl ps --all | grep kube-apiserver

Output:

32957154139e8       f44c6888a2d24       10 minutes ago      Running             kube-apiserver            22                  2fc4f82238bef       kube-apiserver-craftlab
351e4685c670a       f44c6888a2d24       13 minutes ago      Exited              kube-apiserver            21                  2fc4f82238bef       kube-apiserver-craftlab

11. Confirm node is Ready and apply network plugin

Once the API server is running, kubectl can talk to it:

kubectl get nodes

You should see your single node in a Ready state.

Output:

NAME       STATUS   ROLES           AGE    VERSION
craftlab   Ready    control-plane   102m   v1.29.15>)

Alternatively to see more details about your nodes you can run:

kubectl get nodes -o wide

Now that the control-plane is healthy, install Flannel, run:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Output:

namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

And verify:

kubectl get pods --all-namespaces

Output:

NAMESPACE      NAME                               READY   STATUS    RESTARTS       AGE
kube-flannel   kube-flannel-ds-wbpxw              1/1     Running   0              10m
kube-system    coredns-76f75df574-hrzxl           1/1     Running   0              102m
kube-system    coredns-76f75df574-rf95t           1/1     Running   0              102m
kube-system    etcd-craftlab                      1/1     Running   21 (26m ago)   103m
kube-system    kube-apiserver-craftlab            1/1     Running   22 (25m ago)   103m
kube-system    kube-controller-manager-craftlab   1/1     Running   23 (24m ago)   103m
kube-system    kube-proxy-jzz7f                   1/1     Running   21 (21m ago)   102m
kube-system    kube-scheduler-craftlab            1/1     Running   23 (22m ago)   103m

Next steps: Installing Crafty Controller for Minecraft server management