---
# System prepended metadata

title: RKE2安裝

---

# RKE2安裝
用RKE2安裝一台master、一台worker的k8s叢集。測試過兩種組合
* 兩台都是ubuntu 20.04.5-live-server版(minimal install)。
* 兩台都是RHEL 8.4版
  - 已知issue
      - RHEL 8.4版需要將firewalld停掉
      - 若將預設的資料目錄搬移，service rke似乎會起不來，懷疑跟selinux有關，下次安裝會測試關掉selinux看看

## 準備事項
* 確定所有node的hostname都不同(也可以另外指定node在k8s中的名稱)。
* 若要用[Longhorn](https://staging--longhornio.netlify.app)作為叢集的儲存，相關的磁碟需為EXT4或是XFS格式(longhorn安裝時，可以指定使用的path)。
* 網路需求 https://docs.rke2.io/install/requirements/#networking
* For RHEL 8.4：
  - 目前rke2預設的CNI canal跟Firewalld不合，需將firewalld停掉(`systemctl stop firewalld; systemctl disable firewalld`)，參考[Known issues and limitations](https://docs.rke2.io/known_issues/#firewalld-conflicts-with-default-networking)
  - `vi /etc/selinux/config`: change to `SELINUX=disabled`, then reboot


## 安裝的版本
* Rancher 2.6.8
* K8S 1.22.x (2022 Oct時為v1.22.15)
參考 https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-6-7/

## 主要參考
* https://docs.rke2.io/install/quickstart/
* https://docs.ranchermanager.rancher.io/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke2-for-rancher

## 網路需求
若有firewall，需開放的ports (server指的是k8s master nodes, agent指的是k8s worker nodes)
* server (port/protocol, source, description)
    * 9345/tcp, agent, kubernetes api
    * 6443/tcp, agent, kubernetes api
    * 10250/tcp, server and agent, kubelet
    * 2379/tcp, server, etcd client port
    * 2380/tcp, server, etcd peer port
    * 30000-32767/tcp, server and agent (or all?), nodeport port range
    * 8472/udp, server and agent, Canal CNI with VXLAN
    * 9099/tcp, server and agent, Canal CNI Health checks
* client端不需再開port


# Add master node
在master上操作。

1. config file

建立config檔範例
```
mkdir -p /etc/rancher/rke2
cat <<EOF > /etc/rancher/rke2/config.yaml
token: tsti-token
tls-san:
  - api.test.com
EOF
```

建立config檔範例(開啟selinux、設定max-pods)：
```
mkdir -p /etc/rancher/rke2
cat <<EOF > /etc/rancher/rke2/config.yaml
token: tsti-token
tls-san:
  - api.test.com
selinux: false
kubelet-arg:
  - "max-pods=220"
EOF
```

* `token`：要自己取，等一下其他worker加入到此master時會用到。
* `tls-san`：要將server要聽的hostname(s)加入。
* `selinux`: 安裝rke的script偵測到是RHEL/CentOS系統時，預設會將此選項設為true
* `max-pods=220`：在每台node上，pods數量預設上限為110個，若機器資源夠，可將此上限調高


2. rke2 server
```
curl -sfL https://get.rke2.io | INSTALL_RKE2_CHANNEL=v1.22 sh -
```

3. enable and start
```
systemctl enable rke2-server.service
systemctl start rke2-server.service
```
start要等一陣子，可能要十分鐘以上。

4. cluster access
在`~/.bashrc`中增加以下幾行：

```
export PATH=$PATH:/var/lib/rancher/rke2/bin  # for ubuntu
export PATH=$PATH:/usr/local/bin:/var/lib/rancher/rke2/bin  # for RHEL 8.4
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
export CRI_CONFIG_FILE=/var/lib/rancher/rke2/agent/etc/crictl.yaml

source <(kubectl completion bash)
```

然後重新登入。

5. 用以下指令看安裝狀態
```
tail -f /var/lib/rancher/rke2/agent/containerd/containerd.log
crictl ps -a
kubectl get node
kubectl get pods -A
```


第一個指令是去看containerd的log、第二個是看container的狀態，第三、第四是看k8s叢集內，node跟pod的狀態

然後等node跟pod都Ready。

> Note: 如果沒有設定bashrc，要打一大段如下：
> /var/lib/rancher/rke2/bin/crictl --runtime-endpoint unix:///run/k3s/containerd/containerd.sock ps -a
> /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes
> /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get pods -A



## 改預設目錄(optional)
> Note: 以下步驟在ubuntu測試時沒有問題，但是在RHEL 8.4測試就有問題(k8s可安裝完成，但是安裝cert-manager時會遇到問題)，猜想跟開啟了selinux有關係
 
預設放到`/var/lib/rancher/rke2`，若該磁碟分區空間過小，可以等start好了之後這樣做(比如放到`/data`的掛載點)
```
systemctl stop rke2-server
#sh /usr/local/bin/rke2-killall.sh  # ubuntu 20.04
rke2-killall.sh  # RHEL 8.4
mkdir -p /data/lib/rancher
mv /var/lib/rancher/rke2 /data/lib/rancher
ln -s /data/lib/rancher/rke2  /var/lib/rancher/rke2
systemctl start rke2-server
```

todo: 先建好目錄`/data/lib/rancher`，將`/var/lib/rancher` link過去，然後`systemctl start rke2-server`，這樣就不用停掉再啟動了，不過不知道安裝script會不會先把目錄清空，得要測試才知道。

# Add agent (worker)
以下在Worker機上操作。
1. config file
```
mkdir -p /etc/rancher/rke2
cat <<EOF > /etc/rancher/rke2/config.yaml
token: tsti-token
server: https://10.15.22.57:9345
tls-san:
  - api.test.com
EOF
```
這邊的`token`要跟master的一樣；`server`要設定成master的ip；`tls-san`跟master一樣。

2. rke2
```
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" INSTALL_RKE2_CHANNEL=v1.22 sh 
```
若安裝master時用了不同的版本的話，這邊也要改變。

3. enable and start
```
systemctl enable rke2-agent.service
systemctl start rke2-agent.service
```

4. wait and check nodes/pods are added
到master上，用`kubectl get node`確認新節點已經加入並且Ready。

# cluster access
剛剛在add master的過程中，已經在master機上面將kubectl設定好了。

若要在其他台安裝的話(比如bastion機)，要在其他台也安裝kubectl(可以直接copy `/var/lib/rancher/rke2/bin/kubectl`到其他台上)，然後copy kubeconfig過去(`/etc/rancher/rke2/rke2.yaml`)。要注意：該kubeconfig是cluster admin用的，有最高權限，使用者的可以另外從Rancher介面生出他可以用的kubeconfig。

另外，登入Rancher後也可以從介面上進入到console，在介面的右上角有個圖示是`Kubectl Shell`



# Helm安裝
在master上面執行：
```
curl -LO https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
tar zxvf helm-v3.9.4-linux-amd64.tar.gz
install linux-amd64/helm /usr/local/bin/helm
rm -rf linux-amd64
```

# Rancher安裝
在master上執行。先裝CertManager，[參考官網](https://docs.ranchermanager.rancher.io/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#4-install-cert-manager)
```
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.7.1/cert-manager.crds.yaml

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

# Update your local Helm chart repository cache
helm repo update

# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.7.1
```

> Note: 前面步驟若有改預設的目錄的話，這邊用helm安裝cert-manager時會遇到`failed post-install: timed out waiting for the condition`，猜測是`SELinux`造成的，因為不去搬預設的RKE2目錄就可以了。用[kubectl的安裝方式](https://cert-manager.io/docs/installation/kubectl/)雖然可以安裝，但是應該是沒有解決問題。

Wait until pods are ready (`kubectl -n cert-manager get pods`).

Install Rancher
```
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
#helm fetch rancher-stable/rancher --version=2.6.8
helm install rancher rancher-stable/rancher \
  --namespace cattle-system \
  --set hostname=rancher.my.org \
  --create-namespace \
  --set bootstrapPassword=admin
kubectl -n cattle-system rollout status deploy/rancher
```

`helm install`的`hostname`跟`bootstrapPassword`要自行設定。

> Note: 我用的vm所在的主機剛好loading比較重，要等半小時以上才會好，會看到一些`helm`開頭的pod一直沒有Ready，但是放著等一陣子就好了，那些pod會消失。

好了之後，設定dns或是hosts file連到該`hostname`，用瀏覽器連到 rancher.my.org (或其它自己設定的名稱)：
* Bootstrap Password在helm install時設定的(範例設為`admin`)
* 設定password
* 匿名資料收集不用勾
* Agree to terms and conditions打勾

# Longhorn
參考：https://staging--longhornio.netlify.app/docs/1.0.2/deploy/install/install-with-rancher/

ubuntu 20.04 server預設已經有需要的套件；RHEL 8.4少了`open-iscsi`，每一台都要安裝：
```
# ubuntu
apt-get install open-iscsi

# RHEL 8.4
yum install iscsi-initiator-utils
```

官網有環境檢查的script，執行方法
```
curl -sSfL https://raw.githubusercontent.com/longhorn/longhorn/master/scripts/environment_check.sh | bash
```

進入rancher, 點local cluster，左邊選單選`Apps` -> `Charts`，找到`Longhorn`，點`Install`
* 選`Default` project，點`Next`
* 參數
  - `Edit yaml`，在`DefaultSettings`下找到`default-data-path`，輸入適當的值，例如`/data/lib/longhorn`
  - note: 若之後再到longhorn的UI去改的話，似乎只有新的node可以套用設定
* 選`Install`

下面會出現console，等訊息中有`SUCCESS`字串，以及`kubectl -n longhorn-system get po`都`Ready`就安裝成功；接著可以從另一個console確定`StorageClass`已經有設定，例如：
```
# kubectl get sc
NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
longhorn (default)   driver.longhorn.io   Delete          Immediate           true                   98s
```

然後可以從Rancher進到longhorn的網頁介面
![](https://i.imgur.com/Egcy9WR.png)


> note: 若不想透過Rancher進入longhorn管理介面，需自行設定loadbalancer或nodeport。安裝時設定(也可以後來再update)：
> * `Service and Load Balancing`：選`Expose app using Layer 7 Load Balancer`，填入`Hostname`，如`longhorn.my.org`，然後將DNS或是hostfile中加入這個host
> * 或是用nodeport，之後用`http://ip:port`的方式連


## uninstall rke2 from a node
先在master上`kubectl drain nodename`，其中`nodename`是worker node的名字(`kubectl get node`)，然後進到該節點上：
```
# ubuntu 20.04 install these scripts in /usr/local/bin
# RHEL 8.4 install these scripts in /usr/bin
rke2-killall.sh
rke2-uninstall.sh
```
如果叢集不保留的話，應該可以直接所有node上依序執行上面兩個指令。

* (optional)反安裝helm `rm /usr/local/bin/helm`
* (optional)longhorn資料處理
* (optional)`.bashrc`裡面自行修改的部分可以刪除


# TODO
有些要測試的
* RHEL 8.4
  - 改預設目錄的方法(比如直接mount disk到/var/lib/rancher或是SELinux另外設定?)
  - 用其他的CNI，然後啟用fireawlld
* longhorn各種測試
  - snapshot、備份、還原
  - 加節點
  - ...
* etcd備份還原測試
* 啟用logging
* 啟用auditing



# 其他暫存筆記
## logs
```
journalctl -f -u rke2-server
journalctl -f -u rke2-agent
/var/lib/rancher/rke2/agent/containerd/containerd.log
/var/lib/rancher/rke2/agent/logs/kubelet.log
```

## etcd
etcdctl endpoint status
```
for etcdpod in $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name); do kubectl -n kube-system exec $etcdpod -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl endpoint status"; done
```

## 開啟audit log
https://docs.rke2.io/security/hardening_guide/#api-server-audit-configuration
讓apiserver紀錄更多審核request的過程，若開啟audit，會讓apiserver耗費更多cpu、記憶體，而且log量可以到相當多，audit policy要好好設定
note:
* 內部元件也會常常丟request到apiserver，這些log也占了很大一部份
* 在一個1.18版的k8s叢集中(非RKE/RKE2)，總共三個node、100個pod、幾十個服務，兩天下來有1.1GB的audit log，約八成的verb是`GET`、`WATCH`、`LIST`，兩成是`CREATE`、`DELETE`、`PATCH`、`UPDATE`，不過不同叢集的audit log很難直接比對，跟太多因素相關，如選用了那些k8s元件、k8s元件的版本、啟用的元件(例如，更新服務時，ingress controller會自動去更新configmap將新的endpoint放進來)、服務更新頻率等等都有關
