Deploying Kubernetes on Bare-Metal: A Comprehensive Guide
Kubernetes is the de-facto standard for container orchestration, powering production workloads for companies of all sizes. While many choose managed services like GKE, EKS, or AKS, deploying Kubernetes on bare-metal servers gives you complete control over your infrastructure, improved performance, and potentially lower costs.
This guide walks you through deploying Kubernetes on bare-metal servers using kubeadm, and covers best practices, networking, storage, and more.
Table of Contents
- Prerequisites
- Choosing Your Operating System
- Provisioning Your Machines
- Installing Kubernetes with kubeadm
- Networking Setup
- Storage Options
- Monitoring and Logging
- Security Best Practices
- Useful Resources
Prerequisites
- At least 2 bare-metal servers (1 master, 1+ workers)
- Ubuntu 22.04 or CentOS 8
- SSH access with sudo privileges
- Static IPs or DHCP reservations
- Domain names or /etc/hosts configured
- Container runtime (containerd recommended)
Choosing Your Operating System
Popular choices:
- Ubuntu 22.04 LTS – well-supported and user-friendly
- CentOS Stream / Rocky Linux – Red Hat compatible
- Flatcar Linux – Container-focused OS
We'll use Ubuntu 22.04 for this guide.
Provisioning Your Machines
Make sure each node has:
- A unique hostname
- Static IP or DHCP reservation
- NTP (time sync) enabled
- Swap disabled (
sudo swapoff -aand remove from/etc/fstab)
Example /etc/hosts:
192.168.1.10 master-node
192.168.1.11 worker-node-1
192.168.1.12 worker-node-2
Installing Kubernetes with kubeadm
1. Install container runtime (containerd):
sudo apt update && sudo apt install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
2. Install Kubernetes tools:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
3. Initialize the master node:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
4. Set up kubeconfig:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5. Install a Pod Network (e.g., Flannel):
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
6. Join Worker Nodes:
Run the kubeadm join ... command provided after kubeadm init on each worker node.
Networking Setup
Choose a CNI plugin:
- Flannel – simple, works out of the box
- Calico – powerful, includes network policies
- Cilium – based on eBPF, very performant
For production, consider Calico or Cilium for their security and performance benefits.
Storage Options
Persistent storage in bare-metal setups can be tricky. Consider:
- NFS – shared file system
- Rook + Ceph – distributed block/file storage
- OpenEBS – local and distributed storage
Example: Install NFS provisioner
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/kubernetes/deployment.yaml
Monitoring and Logging
Monitoring:
- Prometheus Operator
- Grafana for dashboards
Logging:
- Loki + Grafana
- Fluentd + Elasticsearch + Kibana (EFK stack)
Security Best Practices
- Use role-based access control (RBAC)
- Regularly patch nodes and Kubernetes versions
- Isolate workloads with namespaces and network policies
- Enable audit logging
Useful Resources
- Kubernetes Official Docs
- Awesome Kubernetes
- Kubespray – Ansible-based deployer
- MetalLB – Load-balancer for bare-metal
Conclusion
Deploying Kubernetes on bare-metal requires more effort than managed solutions, but gives you unmatched flexibility, performance, and insight into your infrastructure. Whether for home labs, cost-effective clusters, or compliance needs, a bare-metal Kubernetes setup is a powerful choice.
Let us know how your deployment goes, or ask if you get stuck!