How to Deploy RKE2 Kubernetes on Rocky Linux 9
Learn how to deploy a production-ready RKE2 Kubernetes cluster on Rocky Linux 9. This comprehensive guide covers everything from firewall configuration to multi-node cluster setup, making it perfect for system administrators deploying Kubernetes on RHEL-based systems.
What is RKE2?
RKE2 (RKE Government) is Rancher's next-generation Kubernetes distribution designed for security and compliance. It's ideal for environments requiring FIPS 140-2 compliance and is the preferred Kubernetes distribution for U.S. Federal Government deployments. RKE2 combines the best of RKE1 and K3s, providing enterprise-grade Kubernetes with minimal configuration.
- Security-focused: Built with security as the primary focus
- FIPS 140-2 compliant: Required for government and regulated industries
- Minimal dependencies: Fewer components mean reduced attack surface
- Easy upgrades: Simplified upgrade process compared to other distributions
Prerequisites
Before deploying RKE2, ensure you have:
- Operating System: Rocky Linux 9 or other RHEL-based distribution (AlmaLinux, RHEL 9)
- System Access: Root or sudo privileges
- Resources (per node):
- Control Plane: 4GB RAM, 2 CPUs minimum
- Worker Nodes: 2GB RAM, 2 CPUs minimum
- Network: Connectivity between all cluster nodes
- Hostnames: Unique hostname for each node
- Time Sync: NTP configured on all nodes
Step 1: Configure Firewall Rules
Proper firewall configuration is critical for RKE2 cluster communication. Configure these rules before installing RKE2.
Control Plane Firewall Configuration
For nodes that will run the Kubernetes control plane and etcd:
sudo firewall-cmd --permanent --add-port={6443,9345,10250,2379,2380,2381,30000-32767,179,5473,9098,9099}/tcp
sudo firewall-cmd --add-port=4789/udp --permanent
sudo firewall-cmd --reload
Worker Node Firewall Configuration
For worker nodes that will run application workloads:
sudo firewall-cmd --permanent --add-port={6443,9345,10250,30000-32767,179,5473,9098,9099}/tcp
sudo firewall-cmd --add-port=4789/udp --permanent
sudo firewall-cmd --reload
Understanding the Required Ports
Click to view detailed port reference
Core Kubernetes Ports
| Port | Protocol | Purpose | Required On |
|---|---|---|---|
| 6443 | TCP | Kubernetes API Server | Control Plane |
| 9345 | TCP | RKE2 Supervisor API (node registration) | Control Plane |
| 10250 | TCP | Kubelet metrics API | All Nodes |
| 2379 | TCP | etcd client requests | Control Plane |
| 2380 | TCP | etcd peer communication | Control Plane |
| 2381 | TCP | etcd metrics | Control Plane |
| 30000-32767 | TCP | NodePort Services (default range) | All Nodes |
Calico CNI Network Ports
RKE2 uses Calico as the default Container Network Interface (CNI). These ports are required for pod networking:
| Port | Protocol | Purpose | Notes |
|---|---|---|---|
| 179 | TCP | BGP routing protocol | For Calico networking |
| 4789 | UDP | VXLAN overlay network | Encapsulates pod traffic |
| 5473 | TCP | Calico Typha communication | Typha is Calico's scaling daemon |
| 9098 | TCP | Typha health checks | Monitoring endpoint |
| 9099 | TCP | Felix health checks | Monitoring endpoint |
Port 9345 is used by new nodes to register with the cluster. The standard Kubernetes API on port 6443 is used for all kubectl commands and application API calls.
Step 2: Configure NetworkManager
NetworkManager can interfere with Kubernetes CNI plugins by manipulating routing tables. Configure it to ignore Calico network interfaces.
Create NetworkManager Configuration
sudo tee /etc/NetworkManager/conf.d/rke2-canal.conf > /dev/null <<'EOF'
[keyfile]
unmanaged-devices=interface-name:flannel*;interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico;interface-name:wireguard.cali;interface-name:wg-v6.cali
EOF
Apply NetworkManager Changes
# If RKE2 is NOT yet installed:
sudo systemctl reload NetworkManager
# If RKE2 is already running:
sudo reboot
If you apply NetworkManager configuration after RKE2 is already installed, you must reboot the node. A simple service reload won't properly apply the network interface changes.
Step 3: Install RKE2 Control Plane
The control plane node runs the Kubernetes API server, scheduler, controller manager, and etcd database.
Download and Install RKE2 Server
curl -sfL https://get.rke2.io | sh -
This installation script:
- Downloads the latest stable RKE2 release
- Installs the
rke2-serversystemd service - Places utilities in
/var/lib/rancher/rke2/bin/ - Must run as root or with sudo
Enable RKE2 Server Service
Configure the service to start automatically on boot:
sudo systemctl enable rke2-server.service
Start RKE2 Server
sudo systemctl start rke2-server.service
Monitor the Installation
You can watch the logs to verify successful startup:
sudo journalctl -u rke2-server -f
Post-Installation Files and Locations
After successful installation, you'll find:
- Kubeconfig:
/etc/rancher/rke2/rke2.yaml- Admin credentials for kubectl - Node Token:
/var/lib/rancher/rke2/server/node-token- Required for adding nodes - Binaries:
/var/lib/rancher/rke2/bin/- kubectl, crictl, ctr utilities - Cleanup Scripts:
/usr/local/bin/- rke2-killall.sh, rke2-uninstall.sh
You'll need the node token to add worker nodes. Retrieve it with:
sudo cat /var/lib/rancher/rke2/server/node-token
Step 4: Add Worker Nodes
Worker nodes run your application workloads. You can add as many worker nodes as needed.
Install RKE2 Agent
On each worker node, run:
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -
The INSTALL_RKE2_TYPE="agent" environment variable tells the installer to set up this node as a worker rather than a control plane.
Enable RKE2 Agent Service
sudo systemctl enable rke2-agent.service
Configure Agent to Connect to Control Plane
Create the configuration directory and file:
sudo mkdir -p /etc/rancher/rke2/
sudo vim /etc/rancher/rke2/config.yaml
Add this configuration (replace the placeholders):
server: https://<CONTROL_PLANE_IP>:9345
token: <NODE_TOKEN>
Replace these values:
<CONTROL_PLANE_IP>: IP address of your control plane node<NODE_TOKEN>: Token from/var/lib/rancher/rke2/server/node-tokenon control plane
Example configuration:
server: https://192.168.1.100:9345
token: K10abc123def456::server:xyz789abc123def
The node token provides full cluster access. Protect it like a password and consider rotating it regularly in production environments.
Start the Agent Service
sudo systemctl start rke2-agent.service
Verify Worker Node Connection
Monitor the agent logs:
sudo journalctl -u rke2-agent -f
Look for successful connection messages like:
level=info msg="Starting RKE2 agent"
level=info msg="Successfully registered node with cluster"
Handle Duplicate Hostname Errors
If you see hostname conflicts:
# Add unique node name to config.yaml
sudo vim /etc/rancher/rke2/config.yaml
Add this line:
node-name: worker-node-01
Then restart the service:
sudo systemctl restart rke2-agent.service
Step 5: Configure Cluster Access
Set Up kubectl for Regular Users
Configure kubectl access for your standard user account:
mkdir -p $HOME/.kube
sudo cp -i /etc/rancher/rke2/rke2.yaml $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Root User Configuration
If working as root, export the kubeconfig path:
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
To make this permanent for root:
echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> /root/.bashrc
Add RKE2 Binaries to PATH
Make kubectl and other utilities accessible system-wide:
echo 'export PATH=$PATH:/var/lib/rancher/rke2/bin' | sudo tee /etc/profile.d/rke2-path.sh
source /etc/profile.d/rke2-path.sh
Enable kubectl Bash Completion
For improved command-line experience:
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
source /etc/bash_completion.d/kubectl
Now you can use tab completion with kubectl commands.
Step 6: Verify Your Cluster
Check Node Status
kubectl get nodes
Expected output:
NAME STATUS ROLES AGE VERSION
control-plane-01 Ready control-plane,etcd,master 10m v1.28.4+rke2r1
worker-node-01 Ready <none> 5m v1.28.4+rke2r1
worker-node-02 Ready <none> 3m v1.28.4+rke2r1
Check System Pods
Verify all core Kubernetes components are running:
kubectl get pods -n kube-system
All pods should show Running status.
Test Pod Networking
Deploy a test pod to verify networking:
kubectl run test-pod --image=nginx --port=80
kubectl get pods
Once the pod is running, your cluster is ready for workload deployment.
Troubleshooting Common Issues
RKE2 service fails to start
Check the logs:
sudo journalctl -u rke2-server -n 100 --no-pager
Common causes:
- Port 6443 already in use
- Insufficient system resources
- SELinux blocking operations (check with
sudo ausearch -m avc -ts recent) - Firewall blocking required ports
Solution:
# Check port usage
sudo ss -tulpn | grep 6443
# Check SELinux denials
sudo ausearch -m avc -ts recent | grep rke2
Worker node fails to join cluster
Verify configuration:
sudo cat /etc/rancher/rke2/config.yaml
Check connectivity:
# Test control plane connectivity
curl -k https://<CONTROL_PLANE_IP>:9345/ping
# Verify token matches
sudo cat /var/lib/rancher/rke2/server/node-token # On control plane
Common issues:
- Incorrect control plane IP address
- Wrong or expired node token
- Firewall blocking port 9345
- NetworkManager not configured
Pods stuck in Pending or ContainerCreating
Check pod events:
kubectl describe pod <pod-name>
Check CNI pod status:
kubectl get pods -n kube-system | grep calico
Common causes:
- Calico CNI not running properly
- NetworkManager interfering with interfaces
- Firewall blocking CNI ports (179, 4789)
Solution:
# Restart NetworkManager
sudo systemctl restart NetworkManager
# Restart RKE2 server
sudo systemctl restart rke2-server
Kubectl command not found
Issue: PATH doesn't include RKE2 binaries
Solution:
# Temporary fix
export PATH=$PATH:/var/lib/rancher/rke2/bin
# Permanent fix
echo 'export PATH=$PATH:/var/lib/rancher/rke2/bin' | sudo tee /etc/profile.d/rke2-path.sh
source /etc/profile.d/rke2-path.sh
NetworkManager keeps resetting routes
Issue: NetworkManager configuration not properly applied
Solution:
# Verify configuration exists
cat /etc/NetworkManager/conf.d/rke2-canal.conf
# If RKE2 is installed, reboot is required
sudo reboot
# After reboot, verify interfaces are unmanaged
nmcli device status | grep unmanaged
Frequently Asked Questions
Q: How do I upgrade RKE2 to a newer version?
A: Use the installation script with the desired version:
curl -sfL https://get.rke2.io | INSTALL_RKE2_VERSION=v1.28.5+rke2r1 sh -
sudo systemctl restart rke2-server
Q: Can I use RKE2 on other RHEL-based distributions?
A: Yes! This guide works on RHEL 9, AlmaLinux 9, CentOS Stream 9, and Oracle Linux 9 with minimal or no modifications.
Q: What's the difference between RKE2 and K3s?
A: RKE2 is designed for security and compliance (FIPS 140-2), while K3s is optimized for edge computing and IoT. RKE2 includes more security features but has slightly higher resource requirements.
Q: How do I remove RKE2 completely?
A: Run the uninstall scripts:
# Stop all pods and services
/usr/local/bin/rke2-killall.sh
# Uninstall RKE2
/usr/local/bin/rke2-uninstall.sh
Q: Should I use RKE2 or standard Kubernetes?
A: Choose RKE2 if you need FIPS compliance, simplified installation, or built-in security features. Use upstream Kubernetes for maximum flexibility and cutting-edge features.
Q: Do I need to configure SELinux?
A: RKE2 is designed to work with SELinux in enforcing mode by default. If you encounter issues, check audit logs with sudo ausearch -m avc -ts recent | grep rke2 rather than disabling SELinux.
Q: Can I use a different CNI instead of Calico?
A: Yes, RKE2 supports multiple CNI options including Cilium, Flannel, and Calico. You can specify the CNI in the RKE2 configuration file before starting the service.
Additional Resources
- RKE2 Official Documentation - Comprehensive RKE2 reference
- Rocky Linux Documentation - Rocky Linux guides and references
- Rancher Documentation - Manage multiple Kubernetes clusters
- Kubernetes Official Docs - Learn Kubernetes concepts
- CNCF Landscape - Explore cloud-native tools
Last Updated: October 2025 | Tested on: Rocky Linux 9.6 (Blue Onyx) | RKE2 Version: v1.33.5+rke2r1
*Have questions or suggestions? Join our community forum