問題
今天嘗試將 CRI 從預設的 dockershim 替換至 CRI-O,網路上的教學都是教你更換完畢之後使用 kubeadm 重新起一個 Cluster。但我的情境需要對現有的 Cluster 做替換,於是自己研究了一下如何不停機替換 CRI。
替換 CRI
首先將你需要替換的節點先設 drain
kubectl drain worker-node-1 --ignore-daemonsets
之後進入節點,將原本的 CRI dockershim 關閉
systemctl stop docker
我打算替換成 CRI-O,所以請先確定你想要替換的 CRI 已經安裝完畢,並且已經啟動:
systemctl status crio
1 | ● crio.service - Container Runtime Interface for OCI (CRI-O) |
接著照著網路上的教學,修改 /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
並且增加
1 | Environment="KUBELET_EXTRA_ARGS=--feature-gates='AllAlpha=false,RunAsGroup=true' --container-runtime=remote --cgroup-driver=systemd --container-runtime-endpoint='unix:///var/run/crio/crio.sock' --runtime-request-timeout=5m" |
但是重啟 kubelet 之後會發現毫無作用(用 systemctl status kubelet
可以檢查啟動參數)
為何會毫無作用,是因為該檔案是 kubeadm 啟動時讀取的,但是我打算不停機所以不考慮使用 kubeadm 重啟,我打算在每一個節點上重啟 kubelet 來替換,所以需要針對 kubelet 來設定啟動參數。
於是我在該檔案找到了 EnvironmentFile 參數,並且值為 /etc/sysconfig/kubelet
於是我在 /etc/sysconfig/kubelet
加入了
1 | KUBELET_EXTRA_ARGS=--feature-gates='AllAlpha=false,RunAsGroup=true' --container-runtime=remote --cgroup-driver=systemd --container-runtime-endpoint='unix:///var/run/crio/crio.sock' --runtime-request-timeout=5m |
之後重啟 kubelet
systemctl daemon-reload
systemctl restart kubelet
可以看到啟動參數已經吃進去了
1 | ● kubelet.service - kubelet: The Kubernetes Node Agent |
使用
kubectl get node -o wide
也可以發現 CRI 已經更換
重新讓該節點可以被使用
kubectl uncordon worker-node-1
注意事項
替換 Control Plane 節點時請一定要把原本的 CRI 關閉,否則系統元件會佔用你節點上的 Port,導致使用新的 CRI 無法順利將系統元件跑起來!
部署完畢後 coredns 報錯
1 | container_linux.go:349: starting container process caused "error adding seccomp rule for syscall socket: requested action matches default action of filter" │ Warning FailedCreatePodSandBox 36m kubelet, worker-node-2 Failed to create pod sandbox: rpc error: code = Unknown desc = container create failed: time="2021-04-17 |
看到這篇:https://github.com/cri-o/cri-o/issues/4491
將 runc 升級為 1.0.0-rc93 後解決
yum update runc -y
- 部署完畢後發現 busybox 不能使用 ping(權限不足),增加 CRI-O 的 capabilities,預設只有
1 | default_capabilities = [ |