之前我們搭建的 k8s 集群只用了1台 master ,可用性不高,這兩天開始搭建高可用集群,但由於之前用 kubeadm 命令創建集群時沒有使用 --control-plane-endpoint 參數,無法直接升級現有集群,只能重新創建高可用(High-Availability)集群。
高可用集群的原理很簡單,多台 master ,每台都保存集群數據(etcd),所有 nodes 通過專門搭建的負載均衡訪問 api server ,這樣當部分 master 宕機時,對集群正常運行無影響。
我們用了 3 台 master ,但是在第 1 台 master 服務器開始創建高可用的集群時,遇到了一個做夢也沒想到的問題。
kubeadm init \ --kubernetes-version v1.16.3 \ --control-plane-endpoint "k8s-api:6443" --upload-certs \ --image-repository registry.aliyuncs.com/google_containers \ --pod-network-cidr=192.168.0.0/16 --v=6
為了省事,我們沒有自己另外部署負載均衡,而是直接使用了阿里雲內網負載均衡( 四層 tcp 轉發),在 master 的 hosts 中將上面的 k8s-api 解析到阿里雲負載均衡的 IP 。
但是創建集群總是失敗,錯誤信息如下
[kubelet-check] Initial timeout of 40s passed. I1217 08:39:21.852678 20972 round_trippers.go:443] GET https://k8s-api:6443/healthz?timeout=32s in 30000 milliseconds
排查后發現是因為阿里雲四層負載均衡不支持轉發請求給同一台服務器,也就是發請求的服務器與轉發的后端服務器不能是同一台服務器。
后來我們采用了一個變通的方法解決了問題,在 master 服務器上不將 k8s-api 解析到負載均衡的 IP ,而是解析到 master 自己的 IP ,只在 nodes 上解析到負載均衡 IP 。
當我們搭建好高可用集群,還沒來得及享受高上大的豪華郵輪,就遭遇一個奇怪的 dns 解析問題。在容器內解析主機名時速度很慢,有時解析成功,有時解析失敗,不管是 k8s 的 service 名稱,還是手工添加的 dns 解析記錄,還是阿里雲的 redis 服務,都有這個問題。dns 解析服務用的是 coredns ,pod 網絡用的是 calico 。當時集群中有 3 台 maste 與 1 台 node ,開始以為是 k8s 網絡的問題, 搭建這個集群時開始用的是 flannel 網絡,后來改為 calico ,但折騰很長時間都無濟於事,昨天晚上為此精疲力盡,一氣之下在睡覺之前將集群中的所有服務器都關機。
今天開機后,又遇到了一個做夢也沒想到的事情,問題竟然神奇的消失了,本以為這只是升級豪華郵輪過程中的一個小插曲。
今天下班前,又又遇到了一個做夢也沒想到的事情,線上在用的之前搭建的只有 1 台 master 的非高可用集群中部分 nodes 也出現了同樣的 dns 解析問題(用的是 flannel 網絡),根據剛剛學到的經久不衰的絕招,將出現問題的 nodes 重啟,問題立馬消失。
2個不同的集群,使用的是不同的 pod 網絡,而且使用的是不同的網絡地址段(分別是 192.168.0.0/16 與 10.244.0.0/16),竟然出現了同樣的 dns 解析問題,而且都通過重啟可以解決,這個詭異的問題給我們的開船記出了一道難題。
但是由儉入奢易,由奢入儉難,豪華郵輪已經准備好了,我們再也不想開漁船了(docke swarm),不管怎么樣,船還得繼續開。
【更新】
12月19日 22:37:對於 dns 解析問題,根據 TianhengZhou 在評論中的建議部署了 nodelocaldns ,部署所采用的腳本如下。
sed 's/k8s.gcr.io/gcr.azk8s.cn\/google_containers/g s/__PILLAR__DNS__SERVER__/10.96.0.10/g s/__PILLAR__LOCAL__DNS__/169.254.20.10/g s/__PILLAR__DNS__DOMAIN__/cluster.local/g' nodelocaldns.yaml | kubectl apply -f -
參考資料: