一、高可用原理
管理平面
-
apiserver:
apiserver是k8s集群的入口,為了使用方便,kubectl作為其客戶端供用戶使用。為了實現高可用,在3個機器上分別以靜態Pod的方式部署了apiserver並掛載在同一個loadbalancer上,如此,其與其他組件的聯系都經由這個負載均衡器來做轉發(圖中黑色連線),這樣也保證了每一個用戶命令都有且僅有一個apiserver來響應,並且理論上只要還有一個Pod是可用的,該組件的服務就沒有問題,再加上k8s的Pod有自愈能力,apiserver高可用可以說是能夠保證的。 -
controller managers: k8s自愈能力的關鍵所在,
controller managers提供一種reconciliation的功能,簡單來說就是該組件會無限循環地去通過apiserver來查看api資源的狀態,並將其實際狀態轉變為api資源聲明中的狀態。比如,一個deployment設置了replicas為3,而由於某些原因集群中運行了5個這樣的Pod時,controller managers就會觸發工作並且調用api來刪除2個Pod。同樣,在k8s的master節點上,每個節點以靜態Pod部署一個組件以達到高可用的目的。 -
scheduler: 該組件負責集群內部Pod的調度,主要根據集群node資源情況來平衡每個node的任務量,此外,還支持用戶對Pod調度的自定義限制規則,比如NodeSelector、affinity規則等。該組件的高可用部署方案也是在每一個master節點上部署一個靜態Pod。
組件
controller managers和scheduler的選主是通過etcd來實現的:當一個副本不能工作時,其余副本會更新endpoint至etcd,而etcd只會接受其中一個更新請求,從而實現leader election。
執行平面
執行平面針對的就是node/slave節點,這里實際上就沒有高可用一說了,即便如此,還是簡單介紹一下圖中出現的幾個組件吧。
- container runtime: 每個節點都需要一個容器運行時來執行容器,比如Docker。非pod啟動。
- kubelet: 用於執行apiserver下達的命令,也可以重啟啟動失敗的pod。
- kube-proxy: 通過修改
iptables來達到網絡代理、負載均衡的效果,在k8s中以Service作為代表。比如在使用NodePort進行對外提供服務時,所有node/slave節點都會生成特定的iptables,當該服務被刪除或者節點斷網時,iptables也會被清除。
數據平面
etcd
- 對於高可用集群來說,集群的數據至關重要,Kubernetes將
etcd作為數據存儲中心,其存儲了所有集群相關的信息,比如:pod、node、cm… 鑒於底層系統的高可靠性,數據決不能丟。 - 如圖所示,
etcd在每個master節點上部署了一個實例,以保證其高可用性,實踐證明,etcd掛載本地ssd的方式會大幅提高超大規模(節點大於2000)集群性能(參考資料6)。 etcd官方給的部署模式是奇數個(大於等於3)就好了,推薦部署5個節點,這就不得不提etcd的選主協議/邏輯/算法Raft,這里有個非常生動的動畫值得一看。此外,還需要注意的是所謂“腦裂”問題,這里的“腦裂”是指etcd集群出現兩個甚至多個leader,如果你也是這樣理解腦裂的,那就大可放心使用,因為there is no “split-brain” in etcd。- 默認的etcd參數不太適合disk io比較低的場景
