在 RaspberryPi 上建一個比較健康的 k8s cluster
因為最近我購入了一台 Mikrotik hAP ac2 當作 router,我的 RaspberryPi 就從 Wireless AP 退役了。 正好一直想來架設一個 Nextcloud 來當作雲端備份,不過 Ubuntu 的 Nextcloud 是用 snap 安裝,非常難以維護,而且 snap 也是一個不怎麼自由的東東,是個非常不健康的玩意。所以就只好來用 container 了。
本文的作法大量參考了 xdavidwu 的文章:建一個比較健康的 k8s
因為最近我購入了一台 Mikrotik hAP ac2 當作 router,我的 RaspberryPi 就從 Wireless AP 退役了。
正好一直想來架設一個 Nextcloud 來當作雲端備份,不過 Ubuntu 的 Nextcloud 是用 snap 安裝,非常難以維護,而且 snap 也是一個不怎麼自由的東東,是個非常不健康的玩意。所以就只好來用 container 了。
目標
- CRI-O + crun
- 啟用 user namespace
- Container 的 storage 要在外接硬碟上
- Single node cluster 就好
環境
- Raspberry Pi 4 Model B
- Ubuntu 20.04
- 網路:192.168.0.2/24
基本安裝
在這裡會需要安裝 kubelet, kubeadm, cri-o, crun,需要拉 Google & CRI-O 的 Apt source 跟 key
deb https://packages.cloud.google.com/apt kubernetes-xenial main
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.20/xUbuntu_20.04/ /
詳細步驟就請跟官網走
CRI-O 設定
這邊大部分都跟 xdavidwu 的設定差不多,差別是我沒像他一樣 drop capabilities 就是,有需要的再自行服用
除了這個 configuration 之外,要記得刪除 `etc/crio/crio.conf.d/01-crio-runc.conf
不然待會兒 CRI-O 啟動時會抱怨 crio-runc 沒安裝
設定完之後,先不要啟動 CRI-O
目錄權限
為了方便等會兒設定,這邊可以先建立一個使用者對到裡面的 root
sudo useradd -u 100000 -g 100000 -M -s /usr/sbin/nologin kubernetes
接著要建立一些目錄並設定權限:
sudo mkdir /var/lib/kubelet
sudo chown root:kubernetes /var/lib/kubelet
sudo chmod g+rx /var/lib/kubelet
sudo mkdir /var/lib/kubelet/pods
sudo chown root:kubernetes /var/lib/kubelet/pods -R
sudo chmod g+s /var/lib/kubelet/pods
sudo mkdir /var/lib/etcd
sudo chown kubernetes:kubernetes -R /var/lib/etcd
/var/lib/containers
是 CRI-O 存放 images 的地方,mkdir 之後設定 automount 把它掛載到外接硬碟上,之後再啟動 CRI-O 的 service
設定 CNI 網路
這邊需要依照各位的網路設定去調整,我會開一個新的 bridge 並跟 192.168.0.0/24 網段切開,所以會需要開啟 masquerade
啟用 memory cgroup
Raspberry Pi 上的 Ubuntu 預設是沒有 memory cgroup 的,需要手動開啟
修改 /boot/firmware/nobtcmd.txt
,在裡面加入以下 kernel cmdline:
cgroup_enable=memory cgroup_memory=1
修改完後需要重新開機!
kubeadm 設定檔
在這裡先寫好設定檔,方便等一下不用打一長串指令
部屬 kubelet
用剛才的設定檔讓 kubeadm 幫我們初始化 kubelet
sudo kubeadm init --config kubeadm.yml
修正 kube-proxy
由於現在 container 內不具有 kube-proxy 所需要的權限了,因此需要把它拉出來,直接在外面執行。
因此需要把以下東西拉到外面執行:
- 程式本體
- 設定檔
- 憑證
- Token
程式可以考慮從 /var/lib/containers/storage
中找到對應的 CRI-O container 目錄,或是從 Image 中解出來。
然後在 /var/lib/kubelet/pods
裡會有 pod 用的 configmap & secret,一樣從裡面複製出設定檔、憑證、Token,全部放到 /var/lib/kube-proxy
目錄中。記得權限要弄好。
總共應該要有5個檔案
- config.conf
- kubeconfig.conf
- ca.crt
- token
- namespace
最後要把 kubeconfig.conf
裡面的憑證及 token 路徑修正,設定就完成了。
Systemd 設定檔
寫一個 Systemd 的 Service 讓它可以自動啟動:
[Unit]
Description=kube-proxy
Wants=network-online.target
Before=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf
[Install]
WantedBy=multi-user.target
start & enable 測試一下,看該有的 iptables 有沒有長出來
最後把裡面的 daemonset 拔掉就大功告成了
kubectl -n kube-system delete daemonset kube-proxy
Cluster 設定
若要串多個 node 的方式就一模一樣了。
若是 single node 的話要記得把 noderole 拔掉,不然 master 是不會跑 worker 的工作的。
kubectl taint nodes --all node-role.kubernetes.io/master-