Kubernetes has become the de facto standard for container orchestration, and RHEL 8 provides a stable, enterprise-grade foundation for running production Kubernetes clusters. In this tutorial you will walk through a complete kubeadm-based installation on RHEL 8, from preparing the host operating system through initialising the control-plane node and connecting worker nodes via a Flannel CNI overlay network. All commands are executed as root or with sudo unless otherwise stated. By the end you will have a functional single-node cluster ready to accept workloads.
Prerequisites
- A RHEL 8 server (or VM) with at least 2 vCPUs and 2 GB RAM
- A valid RHEL subscription or access to a compatible repository (CentOS Stream 8, AlmaLinux 8, Rocky Linux 8)
- Root or sudo access
- A static IP address and a resolvable hostname
- Outbound internet access to reach container and package repositories
Step 1 — Disable Swap
Kubernetes requires swap to be disabled on all nodes. Disable it immediately and remove it from /etc/fstab so it does not re-enable on reboot.
swapoff -a
sed -i '/sswaps/d' /etc/fstab
free -h # Swap line should show 0B
Step 2 — Configure SELinux and Required Kernel Parameters
Set SELinux to permissive mode for the current session and persist the change. Also enable bridge traffic filtering so iptables can see bridged traffic inside containers.
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
cat <<EOF | 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
sysctl --system
Step 3 — Open Firewall Ports
If firewalld is running, open the ports required by the Kubernetes control plane and worker components.
# Control-plane ports
firewall-cmd --permanent --add-port=6443/tcp # API server
firewall-cmd --permanent --add-port=2379-2380/tcp # etcd
firewall-cmd --permanent --add-port=10250/tcp # Kubelet
firewall-cmd --permanent --add-port=10251/tcp # kube-scheduler
firewall-cmd --permanent --add-port=10252/tcp # kube-controller-manager
# Flannel overlay
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --reload
Step 4 — Install containerd and Add the Kubernetes Repository
Kubernetes needs a CRI-compliant container runtime. Install containerd from the Docker repository, then add the official Kubernetes yum repository.
dnf config-manager --add-repo
https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y containerd.io
containerd config default | tee /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/'
/etc/containerd/config.toml
systemctl enable --now containerd
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
Step 5 — Install kubelet, kubeadm, and kubectl
Install the three core Kubernetes tools and enable the kubelet service so it starts automatically after cluster initialisation.
dnf install -y kubelet kubeadm kubectl
--disableexcludes=kubernetes
systemctl enable --now kubelet
Step 6 — Initialise the Control Plane and Install a CNI Plugin
Use kubeadm init to bootstrap the control plane. After the command succeeds, configure kubectl access and deploy the Flannel CNI so pods can communicate across nodes.
kubeadm init --pod-network-cidr=10.244.0.0/16
# Configure kubectl for the current user
mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# Deploy Flannel CNI
kubectl apply -f
https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
# Allow scheduling on the control-plane node (single-node lab only)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
# Verify the node is Ready
kubectl get nodes
Conclusion
You have successfully installed a Kubernetes cluster on RHEL 8 using kubeadm. The cluster is bootstrapped with containerd as the container runtime, iptables bridge filtering enabled, swap disabled, and Flannel providing pod-to-pod networking. The node should report a Ready status within a minute or two of deploying the CNI plugin. From here you can join worker nodes by running the kubeadm join command that was printed at the end of kubeadm init, or start deploying workloads on this single-node setup.
Next steps: Deploy an application to Kubernetes on RHEL 8, Install Helm on RHEL 8, and Configure Kubernetes Persistent Volumes on RHEL 8.