Skip to content

Create a Kubernetes cluster with RKE2 , Rancher, and RHEL 7.9 #286

Description

@qingquan-li

Prerequisites

  • Four on-prem RHEL 7.9 servers, reachable over the private network:

    • Control-planes:

      • node1: 10.129.37.219

      • node2: 10.129.37.141 (firewalld is active -> inactive)

      • node3: 10.129.36.49

    • Workers:

      • node4: 10.129.37.221 (not available yet)
  • SSH as sudo-enabled user.

  • RKE2 Version: v1.23

  • Rancher Manager: v2.7.18


1. Prepare All Nodes

1.1 SELinux setup

# Step 1: Check current SELinux status.

# Runtime mode:
getenforce  # Returns Enforcing, Permissive, or Disabled
# Configuration on disk:
grep '^SELINUX=' /etc/selinux/config  # Shows whether the default is SELINUX=enforcing, permissive, or disabled.

# Step 2: Disable SELinux enforcement if `SELINUX=enforcing` rather than `SELINUX=permissive`.

# RKE2 ships an RPM (rke2-selinux) that provides the necessary policies, and on RPM-based distros the installer will pull it in automatically: https://ranchermanager.docs.rancher.com/reference-guides/rancher-security/selinux-rpm/about-rke2-selinux
# Tell the running kernel to switch SELinux from Enforcing mode into Permissive mod:
sudo setenforce 0
# Edit the SELinux config file so that, on reboot, SELinux will come up in Permissive rather than Enforcing:
sudo sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

1.2 swap setup

# Step 1: check current swap status.

# Active swap devices/files:
swapon --show  # If it prints nothing, swap is already off.
# Memory summary:
free -h  # Under the “Swap:” line you’ll see 0B if swap is disabled.
# fstab entries:
grep -E '^\s*[^#].*swap' /etc/fstab  # Lists any uncommented swap lines that would be re-enabled on reboot.


# Step 2: Disable swap (required by K8s) if it was enabled.

# Turn off all swap partitions/files defined in /etc/fstab:
sudo swapoff -a
# Comment out any lines in your /etc/fstab that mention “swap”, so that after a reboot swap will remain disabled.
sudo sed -i '/ swap / s/^/#/' /etc/fstab

1.3 Firewall setup

# Step 1: Check if firewalld is running
sudo systemctl is-active firewalld  # returns “active” or “inactive”

# If firewalld is inactive/disabled, you do not need to enable it if your network edge (physical firewall or VLAN rules) already opens 6443, 9345, 10250, 80 and 443 to these nodes.

# Step 2: If firewalld is inactive, update the firewall rules

# List all rules in that zone
sudo firewall-cmd --zone=$(firewall-cmd --get-default-zone) --list-all  # shows services, ports, masquerade, etc.
# Or just list open ports globally
sudo firewall-cmd --list-ports

# Add your rules
sudo firewall-cmd --permanent \
  --add-port=6443/tcp \
  --add-port=9345/tcp \
  --add-port=10250/tcp \
  --add-service=http \
  --add-service=https

# Open the etcd ports
sudo firewall-cmd --permanent \
  --add-port=2379/tcp \
  --add-port=2380/tcp \
  --add-port=2381/tcp

# when you use --permanent, the rule is saved to disk but not applied at runtime until you reload:
sudo firewall-cmd --reload

1.4 Install essentials

sudo yum install -y curl vim

2. Install RKE2 on all nodes

Reference:

2.1 Run installer script

The script will check your system for rpm, yum, or dnf and if any of those exist, it determines that the system is Redhat based and starts the RPM install process.

curl -sfL https://get.rke2.io | sudo INSTALL_RKE2_CHANNEL=v1.23 sh -
[INFO]  using stable RPM repositories
[INFO]  using 1.23 series from channel stable
Loaded plugins: product-id, search-disabled-repos, subscription-manager
https://rpm.rancher.io/rke2/stable/1.23/centos/7/x86_64/repodata/repomd.xml.asc: [Errno 14] HTTPS Error 404 - Not Found
Trying other mirror.
To address this issue please refer to the below knowledge base article

https://access.redhat.com/articles/1320623

If above article doesn't help to resolve this issue please open a ticket with Red Hat Support.
...

2.2 Edit the Rancher RKE2 repo file

After you run the installer script above to set up the repos, it would have created a repo file /etc/yum.repos.d/rancher-rke2.repo.

Edit the Rancher RKE2 repo file to change two repo_gpgcheck=1 to repo_gpgcheck=0

sudo vi /etc/yum.repos.d/rancher-rke2.repo
[rancher-rke2-common-stable]
name=Rancher RKE2 Common (v1.23)
baseurl=https://rpm.rancher.io/rke2/stable/common/centos/7/noarch
enabled=1
gpgcheck=1
#repo_gpgcheck=1
repo_gpgcheck=0
gpgkey=https://rpm.rancher.io/public.key
[rancher-rke2-1.23-stable]
name=Rancher RKE2 1.23 (v1.23)
baseurl=https://rpm.rancher.io/rke2/stable/1.23/centos/7/x86_64
enabled=1
gpgcheck=1
#repo_gpgcheck=1
repo_gpgcheck=0
gpgkey=https://rpm.rancher.io/public.key

2.3 Clean YUM cache

It’s a good idea to clear cached metadata, since YUM might have cached the failure. Run the command below to ensure YUM will re-download fresh metadata from the repo.

sudo yum clean all

2.4 Install RKE2 via YUM

On control-plane nodes:

sudo yum install -y rke2-server

On worker nodes:

sudo yum install -y rke2-agent

3. Bootstrap RKE2

Reference:

3.1. Setup the Primary Control‐Plane (node1)

# Write minimal config (token will appear after start)
sudo mkdir -p /etc/rancher/rke2
cat <<EOF | sudo tee /etc/rancher/rke2/config.yaml
# node1 is the seed; no server and token needed
tls-san:
  - "10.129.37.219"
EOF

# Enable & start
sudo systemctl enable rke2-server.service
sudo systemctl start rke2-server.service

# Check the status
sudo systemctl status rke2-server.service

# Wait for API to come up
sudo journalctl -u rke2-server -f
# look for: level=info msg="Serving API on [::]:6443"
# or run:
sudo ss -tnlp | grep 6443
LISTEN     0      128       [::]:6443                  [::]:*                   users:(("kube-apiserver",pid=7712,fd=7))

# Save the join token
sudo cat /var/lib/rancher/rke2/server/node-token > ~/node-token
# You need to copy this token to other nodes later

3.2. Add the Other Control-Planes (node2, node3)

# Make sure you have finished "2. Install RKE2 on all nodes"

# Use a editor to add the token (from node1) to `~/node-token`
vi ~/node-token
# Or
echo "<token>" >> ~/node-token

sudo mkdir -p /etc/rancher/rke2

cat <<EOF | sudo tee /etc/rancher/rke2/config.yaml
server: https://10.129.37.219:9345
token: $(<~/node-token)
tls-san:
  - "10.129.37.219"
# Optionally add an advertise‐address (current node IP) so the API server binds correctly
# advertise-address: "<CURRENT-NODE-IP>"
EOF

# Enable & start
sudo systemctl enable rke2-server.service
sudo systemctl start rke2-server.service

# Check the status
sudo systemctl status rke2-server.service
sudo journalctl -u rke2-server -f

3.3. Join Worker Nodes (node4)

# Make sure you have finished "2. Install RKE2 on all nodes"

# Use a editor to add the token (from node1) to `~/node-token`
vi ~/node-token
# Or:
echo "<token>" >> ~/node-token

sudo mkdir -p /etc/rancher/rke2

cat <<EOF | sudo tee /etc/rancher/rke2/config.yaml
server: https://10.129.37.219:9345
token: $(<~/node-token)
EOF

# Enable & start the agent service
sudo systemctl enable rke2-agent.service
sudo systemctl start rke2-agent.service

# Check the status
sudo systemctl status rke2-agent.service
sudo journalctl -u rke2-agent -f

4. Verify the Cluster

On any control-plane (e.g., node1):

# Use RKE2’s bundled kubectl
# RKE2 installs kubectl for you under /var/lib/rancher/rke2/bin. Just symlink it into your PATH:
sudo ln -s /var/lib/rancher/rke2/bin/kubectl /usr/local/bin/kubectl
# Verify kubectl
kubectl version --client
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.17+rke2r1", GitCommit:"953be8927218ec8067e1af2641e540238ffd7576", GitTreeState:"clean", BuildDate:"2023-02-28T21:40:04Z", GoVersion:"go1.19.6 X:boringcrypto", Compiler:"gc", Platform:"linux/amd64"}


# Copy down kubeconfig
mkdir -p ~/.kube
sudo cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config

# Check nodes & pods
kubectl get nodes
NAME               STATUS   ROLES                       AGE   VERSION
[node1-hostname]   Ready    control-plane,etcd,master   22m   v1.23.17+rke2r1
[node2-hostname]   Ready    control-plane,etcd,master   16m   v1.23.17+rke2r1
[node3-hostname]   Ready    control-plane,etcd,master   40m   v1.23.17+rke2r1
[node4-hostname]   Ready    <none>                      10m   v1.23.17+rke2r1

kubectl get pods -A

You should see 4 Ready nodes and all system pods Running.

5. Install Helm 3

Helm 3 is a static Go binary requiring glibc 2.17+—RHEL 7.9’s glibc 2.17 runtime is sufficient: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/7.0_release_notes/sect-red_hat_enterprise_linux-7.0_release_notes-compiler_and_tools-glibc

References: https://helm.sh/docs/topics/version_skew/#supported-version-skew

On node1 (or an admin host with kubectl access):

Helm Version Supported Kubernetes Versions
3.11.x 1.26.x - 1.23.x
# Download & install Helm client
curl -fsSL https://get.helm.sh/helm-v3.11.0-linux-amd64.tar.gz | tar xz
sudo mv linux-amd64/helm /usr/local/bin/

# Verify
helm version
version.BuildInfo{Version:"v3.11.0", GitCommit:"472c5736ab01133de504a826bd9ee12cbe4e7904", GitTreeState:"clean", GoVersion:"go1.18.10"}

6. Install Cert-Manager

References:

# Install cert-manager (for TLS issuance)

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# cert-manager Chart versions: v1.18.2, Kubernetes version: >= 1.22.0-0
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.18.2 \
  --set crds.enabled=true
  
# If you updated something, you need to run `helm upgrade`
helm upgrade cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v1.18.2 \
  --set crds.enabled=true
  
# Verify
kubectl -n cert-manager get pods

kubectl -n cert-manager rollout status deploy/cert-manager --timeout=2m
deployment "cert-manager" successfully rolled out

Wait until all cert-manager pods are Running.

7. Deploy Rancher

References:

# Install Rancher (pinning chart version 2.7.10: https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-7-10/)

# Add the stable repo and refresh
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
helm repo update

# Verify you see 2.7.10 in the list:
helm search repo rancher-stable/rancher --versions

helm install rancher rancher-stable/rancher \
  --namespace cattle-system \
  --create-namespace \
  --version 2.7.10 \
  --set hostname=10.129.37.219.nip.io \
  --set replicas=3
  
NAME: rancher
LAST DEPLOYED: Sat Jul 12 21:56:56 2025
NAMESPACE: cattle-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Rancher Server has been installed.

NOTE: Rancher may take several minutes to fully initialize. Please standby while Certificates are being issued, Containers are started and the Ingress rule comes up.

Check out our docs at https://rancher.com/docs/

If you provided your own bootstrap password during installation, browse to https://10.129.37.219.nip.io to get started.

If this is the first time you installed Rancher, get started by running this command and clicking the URL it generates:

```
echo https://10.129.37.219.nip.io/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}')
```

To get just the bootstrap password on its own, run:

```
kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}{{ "\n" }}'
```


Happy Containering!
# Wait for Rancher pods to roll out
kubectl -n cattle-system rollout status deploy/rancher --timeout=2m
kubectl get pods -n cattle-system
# Optional: See exactly which taints your nodes have
# Run this on any control-plane node:
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .spec.taints[*]}{.key}{":"}{.effect}{";"}{end}{"\n"}{end}'

8. Rancher UI Login

kubectl -n cattle-system get secret bootstrap-secret \
  -o go-template='{{.data.bootstrapPassword|base64decode}}{{"\n"}}'

Open https://10.129.37.219.nip.io in your browser, log in as admin with that password, , and you’re ready to manage your new RKE2 cluster and deploy workloads via Rancher!

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions