Calico 3.28.1 IPPool Issue #9100 - Donwngrade solution

Calico 3.28.1 IPPool Issue #9100 - Donwngrade solution

我們參考 Calico upgrade docs (uses the operator) 升級了 Calico CNI 元件從 3.27.x 到 3.28.1。

$ calicoctl version
Client Version:    v3.28.1
Git commit:        601856343
Cluster Version:   v3.28.1
Cluster Type:      typha,kdd,k8s,operator,bgp,kubeadm,win

升級後發現,原本的 default-ipv4-ippool 被設定回來了。在 3.27.x,因為一開始沒考慮好網段問題,因此我們設定了一組新的 IPPool 來提供給 Pods 使用,來解決一些 IP 網路的問題。在 3.27 依照 migrate-pools 文件,我們為 default-ipv4-ippool 設定了 disabled: true 並且運作良好。但升級至 3.28.1 後,除了 default-ipv4-ippool 被設定回來並且被啟用了。我們還發現,原始按照文件可以設定 disabled: true 無法被正確套用,刪除指令就算執行成功,其實也是無效的。

$ calicoctl get ippool -o wide
NAME                  CIDR             NAT    IPIPMODE   VXLANMODE     DISABLED   DISABLEBGPEXPORT   SELECTOR
default-ipv4-ippool   192.168.0.0/16   true   Never      CrossSubnet   false      false              all()
new-pool              10.244.0.0/16    true   Never      CrossSubnet   false      false              all()

$ calicoctl get ippool -o yaml > pools.yaml
# add disabled: true
$ vim pools.yaml
$ calicoctl apply -f pools.yaml
Successfully applied 2 'IPPool' resource(s)
# DISABLED : false
$ calicoctl get ippool -o wide
NAME                  CIDR             NAT    IPIPMODE   VXLANMODE     DISABLED   DISABLEBGPEXPORT   SELECTOR
default-ipv4-ippool   192.168.0.0/16   true   Never      CrossSubnet   false      false              all()
new-pool              10.244.0.0/16    true   Never      CrossSubnet   false      false              all()

# delete default-ipv4-ippool
$ calicoctl delete pool default-ipv4-ippool
Successfully deleted 1 'IPPool' resource(s)
$ calicoctl get ippool -o wide
NAME                  CIDR             NAT    IPIPMODE   VXLANMODE     DISABLED   DISABLEBGPEXPORT   SELECTOR
default-ipv4-ippool   192.168.0.0/16   true   Never      CrossSubnet   false      false              all()
new-pool              10.x.0.0/16    true   Never      CrossSubnet   false      false              all()

# use patch method
$ calicoctl patch ippool default-ipv4-ippool -p '{"spec": {"disabled": true}}'
$ calicoctl get ippool -o wide
NAME                  CIDR             NAT    IPIPMODE   VXLANMODE     DISABLED   DISABLEBGPEXPORT   SELECTOR
default-ipv4-ippool   192.168.0.0/16   true   Never      CrossSubnet   false      false              all()
new-pool              10.x.0.0/16    true   Never      CrossSubnet   false      false              all()

這對我們造成了困擾。由於 Calico 3.28.1 是目前最新版,不論是網路或 Github Issue 都沒有相關討論。有試了一些網路上的茶包方法也是無效。大概率能確定是新版在 IPPool 方面有蟲,但我們必須盡快修復服務,怎麼辦?

Calico CNI 降級

深思到半夜,突然一個靈感,我能不能做Calico CNI降級處理。官方沒有特別寫怎麼降級或移除重裝,有安裝 Kubernetes 都知道,Pod Network 算是安裝之後啟動 Kubernetes 叢集的最後一步,沒有設定好 Pod Network, Kubernetes 叢集不會進入 Ready 狀態。

能否在已經有大量 Pod 運作的 Kubernetes 叢集上去對 CNI 進行降級處理嗎?答案是:可以。(這是拿命換來的答案!)

由於我們有測試區,設定好快照,立即動手進行 Calico CNI 降級的實驗。花費幾個小時的 PoC,最後得到 Calico CNI 降級步驟如下:

一、找到 Calico 3.28.1 的文件,將原本 apply 換成 delete

kubectl delete -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/custom-resources.yaml
kubectl delete -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/tigera-operator.yaml

注意,先套用 custom-resources.yaml,再套用 tigera-operator.yaml。它會刪除有所 Calico 相關的組態與 Pods。

二、找到 Calico 3.27.x 的文件,重新安裝 Calico CNI

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.4/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.4/manifests/custom-resources.yaml

~$ kubectl get pods -n calico-system
NAME                                       READY   STATUS    RESTARTS      AGE
calico-kube-controllers-6b76d5b4df-nt85h   1/1     Running   0             26h
calico-node-bqqcw                          1/1     Running   1 (27h ago)   27h
calico-node-vmjhf                          1/1     Running   1 (27h ago)   27h
calico-node-z5gdg                          1/1     Running   1 (26h ago)   27h
calico-typha-7979657545-scfkb              1/1     Running   0             26h
csi-node-driver-7w84r                      2/2     Running   2 (26h ago)   27h
csi-node-driver-c956c                      2/2     Running   2 (27h ago)   27h
csi-node-driver-dj9wn                      2/2     Running   2 (27h ago)   27h

$ kubectl get pods -n tigera-operator
NAME                               READY   STATUS    RESTARTS      AGE
tigera-operator-7fdd699b8c-n46kf   1/1     Running   3 (26h ago)   26h

確定所有 calico-systemtigera-operator 都正常在 Running 後,重新設定所需要的 IPPool 組態之後,依照 Kubernetes 維護流程(drain ...)重開機相關的 Worker Node 及 Control Plane,讓整個 Kubernetes 叢集去套用新的 Calico 3.27.x 的設定。

這裡還好有快照的幫忙,讓我能放心去做這樣的 PoC,不然說真的,我還真沒膽做這樣的事。我很怕搞壞了,要重建整個 Kubernetes 叢集,這樣事情就大條了。

這次事件也能看出來, Kubernetes 本身這種 CNI 外掛方式是可以在已正式運轉環境去做切換的。我能移除,代表我就能安裝其他 CNI 外掛。當然,這會影響服務本身的 SLA。但能這樣修復有問題的 CNI 經驗,也不是壞事一件。

Issue 回報:Calico issues #9100

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。