Kubernetes叢集高可用
Kubernetes具有自愈能力,它跟蹤到某工作節點發生故障時,控制平面可以將離線節點上的Pod物件重新編排至其它可用工作節點執行,因此,更多的工作節點也意味著更好的容錯能力,因為它使得Kubernetes在實現工作節點故障轉移時擁有更加靈活的自由度。而當管理員檢測到叢集負載過重或無法容納其更多的Pod物件時,通常需要手動將節點新增到群集,其過程略繁瑣,Kubernetes cluster-autoscaler還為叢集提供了規模按需自動縮放的能力。
然而,新增更多工作節點並不能使群集適應各種故障,例如,若主API伺服器出現故障(由於其主機出現故障或網路分割槽將其從叢集中隔離),將無法再跟蹤和控制叢集。因此,還需要冗餘控制平面的各元件以實現主節點的服務高可用性。基於冗餘數量的不同,控制平面能容忍一個甚至是幾個節點的故障。一般來說,高可用控制平面至少需要三個Master節點來承受最多一個Master節點的丟失,才能保證等待狀態的Master能保持半數以上以滿足節點選舉時的法定票數。一個最小化的Master節點高可用架構如下圖所示。
最小化Master節點高可用架構
Kubernetes元件中僅etcd需要複雜邏輯完成叢集功能,其它元件間的鬆耦合特性使得能夠通過多種方式實現Master節點的高可用性,上圖是較為常用的一種架構,各架構方式也通常有一些共同的指導方針:
- 利用etcd自身提供的分散式儲存叢集為Kubernetes構建一個可靠的儲存層;
- 將無狀態的API Server執行為多副本,並在其前端使用負載均衡器排程請求;需要注意的是,負載均衡器本身也需要高可用;
- 多副本的控制器管理器,並通過其自帶的leader選舉功能(--leader-election)選舉出主角色,餘下的副本在主角色故障時自動啟動新一輪的選舉操作;
- 多副本的排程器,並通過其自帶的leader選舉功能(--leader-election)選舉出主角色,餘下的副本在主角色故障時自動啟動新一輪的選舉操作;
etcd高可用
分散式服務之間進行可靠、高效協作的關鍵前提是有一個可信的資料儲存和共享機制,etcd專案正是致力於此目的構建的分散式資料儲存系統,它以鍵值格式組織資料,主要用於配置共享和服務發現,也支援實現分散式鎖、叢集監控和leader選舉等功能。
etcd基於Go語言開發,內部採用Raft協議作為共識演算法進行分散式協作,通過將資料同步儲存在多個獨立的服務例項上從而提高資料的可靠性,避免了單點故障導致資料丟失。Raft協議通過選舉出的leader節點實現資料一致性,由leader節點負責所有的寫入請求並同步給叢集中的所有節點,在取決半數以上follower節點的確認後予以持久儲存。這種需要半數以上節點投票的機制要求叢集數量最好是奇數個節點,推薦的數量為3個、5個或7個。etcd叢集的建立有三種方式:
- 靜態叢集:事先規劃並提供所有節點的固定IP地址以組建叢集,僅適合於能夠為節點分配靜態IP地址的網路環境,好處是它不依賴於任何外部服務;
- 基於etcd發現服務構建叢集:通過一個事先存在的etcd叢集進行服務發現來組建新叢集,支援叢集的動態構建,它依賴於一個現存可用的etcd服務;
- 基於DNS的服務資源記錄構建叢集:通過在DNS服務上的某域名下為每個節點建立一條SRV記錄,而後基於此域名進行服務發現來動態組建新叢集,它依賴於DNS服務及事先管理妥當的資源記錄;
一般說來,對於etcd分散式儲存叢集來說,三節點叢集可容錯一個節點,五節點叢集可容錯兩個節點,七節點叢集可容錯三個節點,依次類推,但通常多於七個節點的叢集規模是不必要的,而且對系統性能也會產生負面影響。
Controller Manager和Scheduler高可用
Controller Manager通過監控API Server上的資源狀態變動並按需分別執行相應的操作,於是,多例項執行的kube-controller-manager程序可能會導致同一操作行為被每一個例項分別執行一次,例如某一Pod物件建立的請求被3個控制器例項分別執行一次進而創建出一個Pod物件副本來。因此,在某一時刻,僅能有一個kube-controller-manager例項正常工作狀態,餘下的均處於備用狀態,或稱為等待狀態。
多個kube-controller-manager例項要同時啟用“--leader-elect=true”選項以自動實現leader選舉,選舉過程完成後,僅leader例項處於活動狀態,餘下的其它例項均轉入等待模式,它們會在探測到leader故障時進行新一輪選舉。與etcd叢集基於Raft協議進行leader選舉不同的是,kube-controller-manager叢集各自的選舉操作僅是通過在kube-system名稱空間中建立一個與程式同名的Endpoint資源物件實現。
≈~]$ kubectl get endpoints -n kube-system NAMEENDPOINTSAGE kube-controller-manager<none>13h kube-scheduler<none>13h …
這種leader選舉操作是分散式鎖機制的一種應用,它通過建立和維護Kubernetes資源物件來維護鎖狀態,目前Kubernetes支援ConfigMap和Endpoints兩種型別的資源鎖。初始狀態時,各kube-controller-manager例項通過競爭方式去搶佔指定的Endpoint資源鎖。勝利者將成為leader,它通過更新相應的Endpoint資源的註解control-plane.alpha.kubernetes.io/leader中的“holderIdentity”為其節點名稱從而將自己設定為鎖的持有者,並基於週期性更新同一註解中的“renewTime”以宣告自己對鎖資源的持有狀態以避免等待狀態的例項進行爭搶。於是,一旦某leader不再更新renewTime,等待狀態的各例項將一哄而上進行新一輪競爭。
~]$ kubectl describe endpoints kube-controller-manager -n kube-system Name:kube-controller-manager Namespace:kube-system Labels:<none> Annotations:control-plane.alpha.kubernetes.io/leader={"holderIdentity":"master1.ilinux.io_846a3ce4-b0b2-11e8-9a23-00505628fa03","leaseDurationSeconds":15,"acquireTime":"2018-09-05T02:22:54Z","renewTime":"2018-09-05T02:40:55Z","leaderTransitions":1}' Subsets: Events: TypeReasonAgeFromMessage ------------------------- NormalLeaderElection13hkube-controller-managermaster0.ilinux.io_e8fca6fc-b049-11e8-a247-000c29ab0f5b became leader NormalLeaderElection5mkube-controller-managermaster1.ilinux.io_846a3ce4-b0b2-11e8-9a23-00505628fa03 became leader
kube-scheduler的實現方式與此類似,只不過它使用自己專用的Endpoint資源kube-scheduler。
提示:基於kubeadm部署高可用叢集的方式可參考文件: https://kubernetes.io/docs/set ... lity/ 給出的步驟進行。
本文摘編自《Kubernetes進階實戰》,經出版方授權釋出。