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