In this project, we build, deploy, and manage a Kubernetes cluster using RKE2 (Rancher Kubernetes Engine v2) using Cloud VMs (on Google Cloud Platform), enhance it with Rancher UI for web-based cluster management, and deploy a sample application accessible via browser.
- GCP Linux VMs as Cluster Nodes (1 control plane + 1 worker node)
- GCP Firewall Rules
- RKE v2 (k3s-based kubernetes from Rancher)
- Helm
- Kubectl
- Rancher UI
- Certificate
- Nginx App
- Navigate to Compute Engine -> VM instances (Make sure that Compute Engine API is Enabled)
- Create instance:
- Name: rke
- Region: us-central1
- Zone: Any
- Machine type: E2, Shared-core (e2-medium = 2 vCPU + 4GB RAM)
- Click Change: OS Image to Ubuntu (24.04 LTS)
- Boot disk type: Standard persistent disk
- Size: >=30 GB
- Firewall: Allow HTTP, Allow HTTPS, Add another tag (rke-tag)
- Hostname: master.node
- On the GCP Console, Search & Go to Firewall policies - Create Firewall Rule (Name: allow-port-6443, Network: default, Priority: 1000, Direction of Traffic: Ingress, Action on match: Allow, Targets: Specified target tags, Target tags: rke-tag, Source filter: IPv4 ranges 0.0.0.0/0, Protocols and ports: Specified protocols & ports, check TCP & Ports - 6443, 9345, 10250, 30000-32767 + check UDP & Ports - 8472, 51820, 51821). Click Create.
Port | Protocol | Description |
---|---|---|
9345 |
TCP | RKE2 cluster API (used by agents to register with server) |
6443 |
TCP | Kubernetes API server |
10250 |
TCP | Kubelet metrics |
30000-32767 |
TCP | NodePorts |
8472 |
UDP | Flannel VXLAN (if using default CNI) |
51820,51821 |
UDP | For Canal (optional, used if you're using WireGuard) |
Leave the rest as default. Click Create to create instance.
- Click on the 3 dots next to the created instance
- Create a machine image - Name: rke-machine-image, Source VM instance: rke, Location: Regional (us-central1), Encryption: Google-managed encryption key
- Click Create.
- Once created. Click the 3 dots under Actions, select Create instance, give it a Name: rke-w, Networking (Allow HTTP & HTTPS, Network tags: rke-tag, Hostname: worker.node)
- Click Create to create VM
Look for your created VM and click on SSH and Authorize it on the pop-up window to ssh into the VM
sudo apt update && sudo apt upgrade -y
sudo apt update && sudo apt install -y curl wget gnupg lsb-release apt-transport-https ca-certificates software-properties-common
Install RKE2 on master. Use sudo or Run the commands as root
sudo su
curl -sfL https://get.rke2.io | sh -
systemctl enable rke2-server.service
sudo systemctl start rke2-server.service
journalctl -u rke2-server -f
For any other configurations, add them to the file /etc/rancher/rke2/config.yaml
sudo su
ls /etc/rancher/rke2
vim /etc/rancher/rke2/config.yaml
and add this line and save & exit:
write-kubeconfig-mode: "0644"
By default, kubectl, crictl, and ctr are installed but at a different location: /var/lib/rancher/rke2/bin/
sudo ls /var/lib/rancher/rke2/bin/
Configure the kubectl for RKE2 (Exit out of root user)
exit
mkdir -p ~/.kube
sudo cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
sudo chown $(whoami):$(whoami) ~/.kube/config
But we still need to export kubectl binary to the right place (PATH)
export PATH=$PATH:/var/lib/rancher/rke2/bin/
Check the nodes
kubectl get nodes
kubectl get pods -A
Copy & Save the rke2 Token for Registering Other Nodes
sudo cat /var/lib/rancher/rke2/server/node-token
It looks something like this:
K10685ee9a59c125d6d9cb7b543542cf85cd05d677b036e4664::server:0810b3f5f2f6f07c916dfaf71bb
Run these commands on your worker node VMs
sudo su
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -
systemctl enable rke2-agent.service
mkdir -p /etc/rancher/rke2/
vim /etc/rancher/rke2/config.yaml
Add the following content to the config.yaml file and edit it:
server: https://<server>:9345
token: <token from server node>
where is the IP address of the master VM (external or Public IP): 104.154.22.184, and is the token we copied and saved earlier. Save and exit.
systemctl start rke2-agent.service
If you want to check the logs:
journalctl -u rke2-agent -f
Check your cluster nodes
kubectl get nodes
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get svc
On your browser, open your app using Public or External IP of either Worker or Master Node:
IP:NodePort
Install Helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
Add Helm Repo for Rancher
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
helm repo update
Create cert-manager Namespace
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.14.2 \
--set installCRDs=true
Give it about 30 seconds to get ready.
Check the pods
kubectl get pods -n cert-manager
Create cattle-system namespace
kubectl create namespace cattle-system
Install Rancher with a self-signed cert
helm install rancher rancher-latest/rancher \
--namespace cattle-system \
--set hostname=<CONTROL_PLANE_PUBLIC_IP>.nip.io \
--set replicas=1 \
--set bootstrapPassword=admin
- Replace <CONTROL_PLANE_PUBLIC_IP> with your master node’s external IP.
- When you run the command, you will get 2 important outputs on your terminal (1 echo command: generates Rancher URL + 1 kubectl command: generates Bootstrap Password) like this:
echo https://104.154.22.184.nip.io/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}')
kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}{{ "\n" }}'
- Open the link from the echo command on your browser - Advanced - Accept Risk & Continue. Server URL will look like this:
https://104.154.22.184.nip.io
- You will be asked to change your password - type your new password & confirm it (at least 12 characters)
- Rancher running inside the RKE2 cluster automatically registers it as the local cluster.
Check out your cluster resources, kubectl shell, Tools, Workloads, etc
- Click on Workloads - deployments
- Click on Create
- Name: ui-app
- Namespace: default
- Container Image: nginx
- Networking: Click Add Port or Service
- Service Type: NodePort
- Name: ui-app-svc
- Private Container Port: 80
- Listening: 30080
- Protocol: TCP Click Create
On your browser, open
ExternalIP:30080
You can also check from the Terminal:
kubectl get deploy
On your Control Plane,
kubectl delete deployment nginx
kubectl delete service nginx
kubectl delete deployment ui-app
kubectl delete service ui-app
helm uninstall rancher -n cattle-system
helm uninstall cert-manager -n cert-manager
kubectl delete ns cattle-system
kubectl delete ns cert-manager
On the Master Node:
sudo systemctl stop rke2-server
sudo systemctl disable rke2-server
On the Worker Node:
sudo systemctl stop rke2-agent
sudo systemctl disable rke2-agent
sudo /usr/local/bin/rke2-uninstall.sh || sudo /usr/bin/rke2-uninstall.sh
- Select your GCP VMs & Delete them
- Go to Firewall Rules or Policies, Select the firewall rules you created and delete.
- Go to Compute Engine - Disks: to see that disks are deleted as well.