Setting Up a Kubernetes Cluster with Kubeadm and CRI-O

Prerequisites

Before setting up a Kubernetes cluster using Kubeadm and CRI-O, ensure that you meet the following requirements:

Hardware Requirements

  • At least 2 GB of RAM per node (4 GB recommended for the master node)
  • At least 2 CPUs per node
  • 20 GB of free disk space
  • A stable internet connection
  • All nodes should be able to communicate with each other

Software Requirements

  • A supported Linux distribution (Ubuntu 20.04+ or Debian 10+ recommended)
  • User access with sudo privileges
  • Basic understanding of Linux command-line interface (CLI)
  • Knowledge of networking concepts

Step 1: Configure Kernel Parameters

Kubernetes requires some kernel parameters to be set to allow IPtables to see bridged traffic.

Load Required Kernel Modules

Run the following commands on all nodes:

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

sudo modprobe overlay
sudo modprobe br_netfilter

Set Kernel Parameters for Kubernetes

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

Apply the changes:

sudo sysctl --system

Step 2: Disable Swap

Kubernetes does not work well with swap enabled. Disable it using:

swapoff -a

To make this change persistent, remove any swap entries from /etc/fstab:

sudo nano /etc/fstab

Step 3: Install CRI-O (Container Runtime Interface - Open)

Add CRI-O Repository and Install

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

curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key | \
    gpg --dearmor | sudo tee /etc/apt/keyrings/cri-o-apt-keyring.gpg >/dev/null
echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /" | \
    sudo tee /etc/apt/sources.list.d/cri-o.list

sudo apt-get update -y
sudo apt-get install -y cri-o

Enable and Start CRI-O Service

sudo systemctl daemon-reload
sudo systemctl enable crio --now
sudo systemctl start crio.service

Step 4: Install Kubernetes Components

Add Kubernetes Repository

KUBERNETES_VERSION=1.30
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v$KUBERNETES_VERSION/deb/Release.key | \
    gpg --dearmor | sudo tee /etc/apt/keyrings/kubernetes-apt-keyring.gpg > /dev/null

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$KUBERNETES_VERSION/deb/ /" | \
    sudo tee /etc/apt/sources.list.d/kubernetes.list

Install Kubeadm, Kubelet, and Kubectl

sudo apt-get update -y
sudo apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1 kubeadm=1.30.0-1.1

Configure Kubelet Node IP

sudo apt-get install -y jq
local_ip="$(ip --json addr show eno1 | jq -r '.[0].addr_info[] | select(.family == "inet") | .local')"

sudo tee /etc/default/kubelet > /dev/null << EOF
KUBELET_EXTRA_ARGS=--node-ip=$local_ip
EOF

Note: eno1 and enp85s0 are network interface names that may vary depending on the system. You can check your network interfaces using:

ifconfig -a

or

ip a

Adjust the interface name accordingly based on the output of these commands.

Step 5: Initialize Kubernetes on the Master Node

Set the master node IP and hostname:

IPADDR="$(ip --json addr show enp85s0 | jq -r '.[0].addr_info[] | select(.family == "inet") | .local')"
NODENAME=$(hostname -s)
POD_CIDR="192.168.0.0/16"

Initialize Kubernetes:

sudo kubeadm init --apiserver-advertise-address=$IPADDR --apiserver-cert-extra-sans=$IPADDR --pod-network-cidr=$POD_CIDR --node-name $NODENAME --ignore-preflight-errors Swap --cri-socket unix:///var/run/crio/crio.sock 

Set up kubeconfig for the root user:

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

Step 6: Deploy Network and Monitoring Components

Install Calico Network Plugin

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

Install Metrics Server

kubectl apply -f https://raw.githubusercontent.com/techiescamp/kubeadm-scripts/main/manifests/metrics-server.yaml

Install Ingress Controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.49.0/deploy/static/provider/baremetal/deploy.yaml

Step 7: Join Worker Nodes to the Cluster

Generate a join command on the master node:

kubeadm token create --print-join-command

Run the output command on worker nodes to join them to the cluster.

Step 8: Verify Cluster Status

Check Nodes

kubectl get nodes

Check All Pods in a Specific Node

kubectl get pods --all-namespaces --field-selector spec.nodeName=<NODE_NAME>

Troubleshooting Tips

  • Always check system logs: journalctl -u kubelet
  • Verify node status: kubectl get nodes
  • Check pod status: kubectl get pods --all-namespaces

Security Considerations

  • Regularly update Kubernetes and CRI-O
  • Implement RBAC (Role-Based Access Control)
  • Use network policies
  • Regularly scan containers for vulnerabilities

Note: Always refer to the official Kubernetes and CRI-O documentation for the most up-to-date information and best practices.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Découvrez la puissance de la commande Linux Screen pour une gestion efficace des sessions
  • Setting Up a K3s Cluster with a Hello-World Deployment