---
tags:
- Documentation
- Bookstack
- Notes
---
# Kubernetes
# ☸️ Production-Ready Kubernetes Setup Guide (Ubuntu)
This guide walks you through setting up a Kubernetes cluster using `kubeadm` on Ubuntu Server (20.04, 22.04, or 24.04).
## 1. Prerequisites & Resource Allocation
Ensure all machines in your planned cluster meet the following baseline requirements:
- **Operating System:** Clean installation of Ubuntu Server on all nodes.
- **Master Node:** Minimum 2 vCPUs, 4GB RAM, and 50GB storage.
- **Worker Nodes:** Minimum 1 vCPU (2 recommended), 2GB RAM (4GB recommended).
- **Network:** Unique hostnames, MAC addresses, and product\_uuids for every node. Fully static IP addresses are highly recommended.
## 2. Preparation (Execute on ALL Nodes)
Run these steps across every machine (Master and Workers) to prepare the operating system.
### Step 2.1: System Update & Disable Swap
Kubernetes requires swap memory to be completely disabled to ensure kubelet resource scheduling works deterministically.
```
# Update local package lists and upgrade existing software
sudo apt update && sudo apt upgrade -y
# Disable swap immediately
sudo swapoff -a
# Persist the change across reboots by commenting out the swap line in /etc/fstab
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
```
### Step 2.2: Configure Kernel Modules and Networking
Load the necessary kernel modules for container isolation and networking, and configure required `sysctl` network parameters.
```
# Configure modules to load automatically on boot
cat <### Step 2.3: Install and Configure Containerd (CRI)
We will install `containerd`, generate its default configurations, and explicitly enable the `SystemdCgroup` driver so it aligns properly with Kubernetes' cgroup management.
```
# Install the containerd package
sudo apt update && sudo apt install -y containerd
# Generate default configuration directory and file
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
# Configure containerd to use SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/etc/containerd/config.toml
# Restart and enable containerd service
sudo systemctl restart containerd
sudo systemctl enable containerd
```
### Step 2.4: Install Kubernetes CLI/Server Tools (`pkgs.k8s.io`)
This pulls from the modernized community-hosted repositories. *(Note: Adjust `v1.30` in the path if you intend to pin your cluster to a specific minor edition).*
```
# Download dependencies for secure repository signatures
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# Download the public signing key for the modern Kubernetes package repository
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# Add the correct apt repository reference string
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
# Update your lists and install the core binaries
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
# Prevent accidental background package upgrades from breaking cluster state
sudo apt-mark hold kubelet kubeadm kubectl
```
## 3. Control Plane Initialization (Execute on MASTER Node Only)
### Step 3.1: Initialize via Kubeadm
Choose your Pod network CIDR block. If using **Calico**, the default block is `192.168.0.0/16`. If using **Flannel**, the default block is `10.244.0.0/16`.
```
# Initialize the master plane node (Using Calico default networking block)
sudo kubeadm init --pod-network-cidr=192.168.0.0/16
```
*(Once complete, look at the end of your terminal output. Copy and save the unique `kubeadm join` block generated—you will need it for your workers).*
### Step 3.2: Configure local `kubectl` access
To allow your non-root system user account to issue instructions to the API server:
```
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
### Step 3.3: Deploy the Pod CNI (Calico Deployment)
Deploying a single clear network operator ensures network tracking stays clean.
```
# Install the Tigera Calico Operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/tigera-operator.yaml
# Download the custom resource manifest definition
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/custom-resources.yaml
# (Optional modification) If you used a pod-network-cidr other than 192.168.0.0/16,
# edit custom-resources.yaml using nano to alter the "cidr:" line inside to match it.
# Apply the custom network layout manifest
kubectl create -f custom-resources.yaml
```
## 4. Join Worker Nodes (Execute on WORKER Nodes Only)
Move over to your designated worker VMs. Take the output you preserved from Step 3.1 and execute it with administrative flags:
```
sudo kubeadm join :6443 --token \
--discovery-token-ca-cert-hash sha256:
```
### Missing your join token string?
If you ever lose the string or it expires (tokens automatically timeout after 24 hours), generate a brand-new execution block by running this command back on the **Master node**:
```
kubeadm token create --print-join-command
```