自定义Kubernetes调度程序来编排高可用性应用程序
自定義Kubernetes調度程序來編排高可用性應用程序
只要愿意遵守規則,在Kubernetes上進行部署和乘飛機旅行就可以很愉快。通常,事情會“正常工作”。但是,如果有興趣與必須生存的鱷魚一起旅行,或對必須保持可用狀態的數據庫進行擴展,則情況可能會變得更加復雜。為此,甚至可能更容易構建自己的飛機或數據庫。除了爬行動物之外,擴展高可用性的有狀態系統也不是一件容易的事。
擴展任何系統都有兩個主要組成部分:
- 添加或刪除系統將在其上運行的基礎結構,以及
- 確保系統知道如何處理自己添加和刪除的其它實例。
大多數無狀態系統(例如Web服務器),在創建時不需要知道對等對象的。有狀態的系統(包括CockroachDB之類的數據庫)必須與對等實例進行協調,并在數據周圍進行重新整理。幸運的是,CockroachDB能處理數據的重新分發和復制。棘手的部分是通過確保數據和實例分布在許多故障域(可用性區域)中,能夠容忍這些操作中的故障。
Kubernetes的職責之一是將“資源”(例如磁盤或容器)放入群集中,并滿足所要求的約束。例如:“必須在可用區域A中”,或“不能將我與另一個Pod放置在同一節點上”。
除了這些約束之外,Kubernetes還提供Statefulsets(狀態集),該狀態集為Pod提供身份,以及“跟隨”這些已標識Pod的持久性存儲。StatefulSet中的身份由Pod名稱末尾的遞增整數處理。該整數必須始終是連續的:在StatefulSet中,如果容器1和3存在,則容器2也必須存在。
CockroachCloud將CockroachDB的每個區域作為StatefulSet,部署在其Kubernetes集群中。在本文中,將研究一個單獨的區域,一個StatefulSet和一個Kubernetes集群,該集群分布在至少三個可用性區域中。
一個三節點的CockroachCloud集群如下所示:
向集群添加資源時,將它們分布在區域之間。為了獲得最快的用戶體驗,同時添加了所有Kubernetes節點,然后擴展了StatefulSet。
無論Pod分配給Kubernetes節點的順序如何,都滿足反親和性anti-affinity。此示例中,分別將Pod 0、1和2分配給區域A,B和C,分別以不同的順序將Pod 3和4分配給區域B和A。由于吊艙仍放置在不同的區域中,因此仍然可以滿足抗親和力anti-affinity要求。
從集群中刪除資源,逆序執行這些操作。
首先縮小StatefulSet,然后從群集中刪除缺少CockroachDB pod的所有節點。
小為n的StatefulSet中的pod的id必須在range內[0,n)。將StatefulSet按m縮小,Kubernetes會從最高序數開始,向最低序數移動m吊艙,倒序添加。考慮下面的群集拓撲:
當從該群集中刪除序號5到3時,狀態集statefulset將在所有3個可用性區域中繼續存在。
Kubernetes的調度程序并不能像最初預期的那樣,保證上面的位置。
以下方面的綜合了解,導致這種錯誤的原因。
? Kubernetes能夠自動將Pod分布到整個區域
? 具有n個副本的StatefulSet的行為,在部署Pod時,按順序開始創建它們{0…n-1}。
考慮以下拓撲:
這些窗格是按順序創建的,分布在集群中的所有可用性區域中。當序數5到3終止時,此群集將失去在C區的存在!
自動化將刪除節點A-2,B-2和C-2。使CRDB-1處于非計劃狀態,持久卷積僅在最初創建區域中可用。
為了更正后一個問題,現在采用“狩獵和啄食hunt and peck”的方法從群集中刪除計算機。不會從群集中盲目刪除Kubernetes節點,而只會刪除沒有CockroachDB pod的節點。更艱巨的任務是糾纏Kubernetes調度程序。
頭腦風暴會議為我們提供了3個選擇:
1.升級到kubernetes 1.18并利用Pod拓撲擴展約束
雖然這似乎是一個完美的解決方案,公共云中的兩個最常見的托管Kubernetes服務(EKS和GKE)尚無法使用Kubernetes 1.18。此外,pod拓撲擴展約束仍然是1.18中的beta功能,這意味著即使v1.18可用,也不能保證在托管群集中也可以使用它。整個過程讓人想起了Internet Explorer 8仍然存在時檢查caniuse.com的過程。
2.為每個區域部署一個有狀態集。
與其在所有可用區域上分布一個StatefulSet,不如在每個區域具有節點親和力的單個StatefulSet,將允許對區域拓撲進行手動控制。一直認為這是一種選擇,這使其特別具有吸引力。最終,決定放棄此選項,因為這將需要對代碼庫進行大修,在現有客戶集群上執行遷移,將是一項同樣艱巨的任務。
3.編寫一個自定義的Kubernetes調度程序。
編寫自己的自定義Kubernetes調度程序。部署并運行了概念驗證后, Kubernetes的調度程序,負責將持久卷映射到其調度的Pod。輸出kubectl get events,還有另一個系統在起作用。在尋找負責存儲聲明映射的組件的過程中,發現了kube-scheduler插件系統。下一個POC是一個Filter插件,按Pod順序確定合適的可用性區域,并且可以完美地工作!
自定義調度程序插件是開源的,可在所有CockroachCloud集群中運行。控制StatefulSet Pod的調度方式,充滿信心地進行擴展。一旦GKE和EKS中提供了Pod拓撲擴展約束,可能會考慮淘汰插件,但是維護開銷卻出乎意料的低。更妙的是:該插件的實現與業務邏輯正交。部署或撤消它,就像更改schedulerName的StatefulSet定義中的字段一樣簡單。
總結
以上是生活随笔為你收集整理的自定义Kubernetes调度程序来编排高可用性应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux实现ffmpeg H.265视
- 下一篇: 将TVM集成到PyTorch上