Rancher made RKE2 straightforward to install. Here is an example configuration. For details, refer to docs.rke2.io
The LAB description
Hostname
IP Address
vCPU
RAM (GB)
proxy.home.pivert.org
192.168.66.20
1
1
rke21.home.pivert.org
192.168.66.21
2
4
rke22.home.pivert.org
192.168.66.22
2
4
rke23.home.pivert.org
192.168.66.23
2
4
Lab description table
Sanity checks
Before going further, let’s make sure you successfully run the below tests from your workstation. (Adapt IPs)
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for x in192.168.66.2{0..3}; do ping -W1 -c1 $x > /dev/null&& echo "$x : OK"|| echo "$x : Not OK"; done;
for x in proxy rke2{1..3}; do ping -W1 -c1 $x > /dev/null&& echo "$x : OK"|| echo "$x : Not OK"; done;
for x in 192.168.66.2{0..3}; do ping -W1 -c1 $x > /dev/null && echo "$x : OK" || echo "$x : Not OK"; done;
for x in proxy rke2{1..3}; do ping -W1 -c1 $x > /dev/null && echo "$x : OK" || echo "$x : Not OK"; done;
for x in 192.168.66.2{0..3}; do ping -W1 -c1 $x > /dev/null && echo "$x : OK" || echo "$x : Not OK"; done;
for x in proxy rke2{1..3}; do ping -W1 -c1 $x > /dev/null && echo "$x : OK" || echo "$x : Not OK"; done;
It will also install keepalived on the masters to maintain a virtual IP address (proxy) between the nodes, so you do not need any external haproxy nor external keepalived. Make sure the virtual IP for proxy (192.168.66.20 in the example) is free.
Start a seashell
seashell container offers a Bash and Neovim environment with all the common kubernetes tools (kubectl, oc, k9s, helm, …) and Ansible.
seashell will mount the current folder for persistence (your config files). Also, if you need ssh-agent, run it before starting seashell or eval $(ssh-agent -s) As user, create a new folder and cd into it.
Create a ./group_vars/ subfolder with 3 files, and provide the rke2_token and rke2_argent_token. The rke2_token for the workers must be equal to the rke2_agent_token for the masters. This is an additional security feature to ensure the workers do not need the token reserved for masters joining.
First set your global variables in all.yml
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
---
ansible_user: pivert
rke2_token:""
---
ansible_user: pivert
rke2_token: ""
---
ansible_user: pivert
rke2_token: ""
Generate 2 tokens, and place them in a masters.yml file.
If the cluster does not come up 30 minutes after everything has been downloaded (monitor your internet download usage), you can use crictl to ensure all your pods are running.
ansible k8s_cluster -m shell -a "rm -f crictl-$VERSION-linux-amd64.tar.gz"
ansible k8s_cluster -m copy -a "dest=/etc/crictl.yaml content='runtime-endpoint: unix:///run/k3s/containerd/containerd.sock\n'" -b
VERSION="v1.28.0"
ansible k8s_cluster -m shell -a "wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz"
ansible k8s_cluster -m shell -a "tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin" -b
ansible k8s_cluster -m shell -a "rm -f crictl-$VERSION-linux-amd64.tar.gz"
ansible k8s_cluster -m copy -a "dest=/etc/crictl.yaml content='runtime-endpoint: unix:///run/k3s/containerd/containerd.sock\n'" -b
VERSION="v1.28.0"
ansible k8s_cluster -m shell -a "wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz"
ansible k8s_cluster -m shell -a "tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin" -b
ansible k8s_cluster -m shell -a "rm -f crictl-$VERSION-linux-amd64.tar.gz"
crictl uses a syntax very close to docker. So command like this will show you all the Pods:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ansible k8s_cluster -a 'crictl ps'
ansible k8s_cluster -a 'crictl ps'
ansible k8s_cluster -a 'crictl ps'
Feel free to check logs with crictl if the cluster did not initialize and you did not get the /tmp/rke2.yaml file.
Scratch the cluster
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ansible k8s_cluster -a /usr/local/bin/rke2-killall.sh
ansible k8s_cluster -a /usr/local/bin/rke2-uninstall.sh
ansible k8s_cluster -a 'rm /etc/systemd/system/rke2-server.service'
ansible k8s_cluster -a 'systemctl daemon-reload'
ansible k8s_cluster -a /usr/local/bin/rke2-killall.sh
ansible k8s_cluster -a /usr/local/bin/rke2-uninstall.sh
ansible k8s_cluster -a 'rm /etc/systemd/system/rke2-server.service'
ansible k8s_cluster -a 'systemctl daemon-reload'
ansible k8s_cluster -a /usr/local/bin/rke2-killall.sh
ansible k8s_cluster -a /usr/local/bin/rke2-uninstall.sh
ansible k8s_cluster -a 'rm /etc/systemd/system/rke2-server.service'
ansible k8s_cluster -a 'systemctl daemon-reload'
The 2 last steps above to remove the service are important, since there is a bug
Second option: Manual
This option is described in the docs.rke2.io documentation.
Setup your haproxy or loadbalancer
This option does not describe how to run keepalived on the hosts, so you need an external loadbalancer. Feel free to use any loadbalancer, or DNS round . Here is an example for haproxy:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
global
log 127.0.0.1 local2
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
defaults
mode http
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# RKE2
listen rke2-api-server-6443
bind 192.168.66.20:6443
mode tcp
option httpchk HEAD /readyz
http-check expect status 200
option ssl-hello-chk
server rke21 192.168.66.21:6443 check inter 1s
server rke22 192.168.66.22:6443 check inter 1s
server rke23 192.168.66.23:6443 check inter 1s
listen rke2-machine-config-server-9345
bind 192.168.66.20:9345
mode tcp
server rke21 192.168.66.21:9345 check inter 1s
server rke22 192.168.66.22:9345 check inter 1s
server rke23 192.168.66.23:9345 check inter 1s
listen rke2-ingress-router-80
bind 192.168.66.20:80
mode tcp
balance source
server rke21 192.168.66.21:80 check inter 1s
server rke22 192.168.66.22:80 check inter 1s
server rke23 192.168.66.23:80 check inter 1s
listen rke2-ingress-router-443
bind 192.168.66.20:443
mode tcp
balance source
server rke21 192.168.66.21:443 check inter 1s
server rke22 192.168.66.22:443 check inter 1s
server rke23 192.168.66.23:443 check inter 1s
global
log 127.0.0.1 local2
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
defaults
mode http
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# RKE2
listen rke2-api-server-6443
bind 192.168.66.20:6443
mode tcp
option httpchk HEAD /readyz
http-check expect status 200
option ssl-hello-chk
server rke21 192.168.66.21:6443 check inter 1s
server rke22 192.168.66.22:6443 check inter 1s
server rke23 192.168.66.23:6443 check inter 1s
listen rke2-machine-config-server-9345
bind 192.168.66.20:9345
mode tcp
server rke21 192.168.66.21:9345 check inter 1s
server rke22 192.168.66.22:9345 check inter 1s
server rke23 192.168.66.23:9345 check inter 1s
listen rke2-ingress-router-80
bind 192.168.66.20:80
mode tcp
balance source
server rke21 192.168.66.21:80 check inter 1s
server rke22 192.168.66.22:80 check inter 1s
server rke23 192.168.66.23:80 check inter 1s
listen rke2-ingress-router-443
bind 192.168.66.20:443
mode tcp
balance source
server rke21 192.168.66.21:443 check inter 1s
server rke22 192.168.66.22:443 check inter 1s
server rke23 192.168.66.23:443 check inter 1s
global
log 127.0.0.1 local2
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
defaults
mode http
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# RKE2
listen rke2-api-server-6443
bind 192.168.66.20:6443
mode tcp
option httpchk HEAD /readyz
http-check expect status 200
option ssl-hello-chk
server rke21 192.168.66.21:6443 check inter 1s
server rke22 192.168.66.22:6443 check inter 1s
server rke23 192.168.66.23:6443 check inter 1s
listen rke2-machine-config-server-9345
bind 192.168.66.20:9345
mode tcp
server rke21 192.168.66.21:9345 check inter 1s
server rke22 192.168.66.22:9345 check inter 1s
server rke23 192.168.66.23:9345 check inter 1s
listen rke2-ingress-router-80
bind 192.168.66.20:80
mode tcp
balance source
server rke21 192.168.66.21:80 check inter 1s
server rke22 192.168.66.22:80 check inter 1s
server rke23 192.168.66.23:80 check inter 1s
listen rke2-ingress-router-443
bind 192.168.66.20:443
mode tcp
balance source
server rke21 192.168.66.21:443 check inter 1s
server rke22 192.168.66.22:443 check inter 1s
server rke23 192.168.66.23:443 check inter 1s
This might be the most important part. Also make sure you do not have any firewall in the way or carefully watch for DROP or REJECTS.
This is not mandatory for this tutorial, but if you’re using haproxy, configure 2 in HA with Keepalived.
Ignore CNI-managed interfaces (NetworkManager)
Configure NetworkManager to ignore calico/flannel related network interfaces on the 3 nodes
Activation should take 3-10 minutes since it will download container images. Watch the log
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
journalctl -u rke2-server.service -f
journalctl -u rke2-server.service -f
journalctl -u rke2-server.service -f
Check
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get pods -A
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get pods -A
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get pods -A
Install and start other nodes
Proceed one node at a time. Don’t go to the next node as long as you do not see the second node in “Ready” state with
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
Copy the config.yaml and add the server line
Copy the above file to other nodes, and add the server on the first line. Make sure the token is the same on all nodes. The file should look like this:
cp /etc/rancher/rke2/config.yaml /root # Save your config.yaml since it will be deleted by the uninstall below
# You must delete the node from the cluster to be able to re-join
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml drain $HOSTNAME --delete-emptydir-data --force --ignore-daemonsets
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml delete node $HOSTNAME
systemctl disable rke2-server.service --now
rke2-killall.sh
rke2-uninstall.sh
mkdir -p /etc/rancher/rke2/
cp /root/config.yaml /etc/rancher/rke2/
curl -sfL https://get.rke2.io | sh -
systemctl enable rke2-server.service --now
journalctl -u rke2-server.service -f
cp /etc/rancher/rke2/config.yaml /root # Save your config.yaml since it will be deleted by the uninstall below
# You must delete the node from the cluster to be able to re-join
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml drain $HOSTNAME --delete-emptydir-data --force --ignore-daemonsets
kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml delete node $HOSTNAME
systemctl disable rke2-server.service --now
rke2-killall.sh
rke2-uninstall.sh
mkdir -p /etc/rancher/rke2/
cp /root/config.yaml /etc/rancher/rke2/
curl -sfL https://get.rke2.io | sh -
systemctl enable rke2-server.service --now
journalctl -u rke2-server.service -f
The kubectl delete might hang, just <ctrl>+c once. The node delete/creation takes about 3-5 minutes.
What’s next ?
Install Rancher to get a GUI
Make sure you’re in the above-mentioned seashell, and have proper KUBECONFIG environment variable. For instance: export KUBECONFIG=~/rke2.yaml Or add or copy the rke2.yaml content to your ~/.kube/config From the seashell, you should be able to run aliases such as kgpoall (800 aliases starting by k…)
echo https://proxy.home.pivert.org/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}') # =>Click on the link after 5-10 minutes
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.11.0
helm install rancher rancher-latest/rancher --namespace cattle-system --set hostname=proxy.home.pivert.org --set bootstrapPassword=admin --values values.yaml --set global.cattle.psp.enabled=false
echo https://proxy.home.pivert.org/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}') # =>Click on the link after 5-10 minutes
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.11.0
helm install rancher rancher-latest/rancher --namespace cattle-system --set hostname=proxy.home.pivert.org --set bootstrapPassword=admin --values values.yaml --set global.cattle.psp.enabled=false
echo https://proxy.home.pivert.org/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}') # =>Click on the link after 5-10 minutes
Also make sure you have enough RAM & vCPU to run your workloads. Think about minimum 16 GB RAM & 4vCPU.
Conclusion
RKE2 is very easy to set up, and the documentation is great. Both options allows you to install a cluster in minutes. Check the documentation for more.
Like it ?
Get notified on new posts (max 1 / month) Soyez informés lors des prochains articles
Of course, you can always install both server and agent (or master and worker) on a single server. You’ll need 3 servers instead of 6. The reason to split servers and agent is to prevent a high workload on an agent to impact the controlplane and/or etcd.
2 responses to “RKE2 cluster on Ubuntu 22.04 in minutes – Ansible Galaxy and Manual options (2 ways)”
How about installing onto a single server which acts as server and agent?
The officiat documentations doesnt explain it well!
Of course, you can always install both server and agent (or master and worker) on a single server. You’ll need 3 servers instead of 6. The reason to split servers and agent is to prevent a high workload on an agent to impact the controlplane and/or etcd.