Skip to main content

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.

Why Choose RKE2?
  • 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

PortProtocolPurposeRequired On
6443TCPKubernetes API ServerControl Plane
9345TCPRKE2 Supervisor API (node registration)Control Plane
10250TCPKubelet metrics APIAll Nodes
2379TCPetcd client requestsControl Plane
2380TCPetcd peer communicationControl Plane
2381TCPetcd metricsControl Plane
30000-32767TCPNodePort 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:

PortProtocolPurposeNotes
179TCPBGP routing protocolFor Calico networking
4789UDPVXLAN overlay networkEncapsulates pod traffic
5473TCPCalico Typha communicationTypha is Calico's scaling daemon
9098TCPTypha health checksMonitoring endpoint
9099TCPFelix health checksMonitoring endpoint
Port 9345 vs 6443

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
Critical: Reboot Required

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-server systemd 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
Retrieve Node Token

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-token on control plane

Example configuration:

server: https://192.168.1.100:9345
token: K10abc123def456::server:xyz789abc123def
Secure Your Node Token

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


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