Running Kubernetes on Bare Metal: A Step-by-Step Guide



Table of Contents
Introduction
Kubernetes on bare metal means running Kubernetes directly on physical servers without a virtualization layer. In this setup, you have an “empty” server (no hypervisor or cloud VM), giving your containers direct access to hardware. This yields high performance and low latency, ideal for workloads like high-performance computing or large databases. It also offers full control over networking, storage, and compute resources.
In this guide, we’ll walk through setting up a bare-metal Kubernetes cluster step by step, using modern tools and best practices, on both Linux (Ubuntu or Fedora) and optional Windows worker nodes.
Prerequisites and Environment
Before starting, gather the following hardware and software prerequisites.
Hardware
- • Control-plane node: 4+ CPU cores, 16+ GB RAM, 100+ GB disk
- • Worker nodes: 2+ CPU cores, 8+ GB RAM
- • Static IP addresses for all nodes
- • Same network or properly routed subnets
Operating Systems
- • Linux: Ubuntu 22.04+ or Fedora 38/39
- • Windows (optional): Windows Server 2022+
Access and Networking
- • Root or sudo access
- • SSH enabled on Linux nodes
- • Proper hostname resolution using
/etc/hostnameand/etc/hosts
Disable Swap (Linux)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
Container Runtimes: Docker vs. containerd
Kubernetes requires a CRI-compatible container runtime. Popular options include Docker Engine, containerd, and CRI-O. Since Kubernetes v1.24, dockershim has been removed.
Ubuntu: Install containerd
sudo apt update
sudo apt install -y containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl enable --now containerd
Fedora
sudo dnf install -y containerd docker-cli
sudo systemctl enable --now containerd
Installing Kubernetes Components
Add Kubernetes Repository (Ubuntu)
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/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.33/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 --now kubelet
Verify:
kubelet --version kubeadm version kubectl version --client
Initializing the Control Plane
Enable IP forwarding:
sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Initialize the cluster:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Configure kubeconfig:
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Installing a Pod Network Add-on
Flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Check:
kubectl get pods -n kube-system
Joining Linux Worker Nodes
Run on each worker:
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Verify:
kubectl get nodes
Adding a Windows Worker Node (Optional)
On Windows Server 2022 (PowerShell as Admin):
Invoke-WebRequest -Uri https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/Install-Containerd.ps1 -OutFile Install-Containerd.ps1 .\Install-Containerd.ps1 -ContainerDVersion 1.7.22 Invoke-WebRequest -Uri https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/PrepareNode.ps1 -OutFile PrepareNode.ps1 .\PrepareNode.ps1 -KubernetesVersion v1.33.2
Then run kubeadm join with the same token.
Verifying the Cluster and Deploying a Sample App
kubectl get nodes kubectl get pods -n kube-system
Deploy sample app:
kubectl create deployment hello-web --image=nginx
kubectl expose deployment hello-web --port=80 --type=NodePort
kubectl get pods,svc
Tips and Next Steps
- • Use MetalLB or a hardware load balancer
- • Back up etcd regularly
- • Install monitoring with Prometheus and Grafana
- • Upgrade clusters using
kubeadm upgrade
Running Kubernetes on bare metal gives unmatched performance and control, but also full responsibility. With proper planning and maintenance, it becomes a powerful production foundation.