Kubernetes 也有局限性吗?
作者 |?Draveness
來(lái)源?|?真沒(méi)什么邏輯
頭圖?| 下載于視覺(jué)中國(guó)
2014 年發(fā)布的 Kubernetes 在今天儼然已成為容器編排領(lǐng)域的事實(shí)標(biāo)準(zhǔn),相信談到 Kubernetes 的開發(fā)者都會(huì)一再?gòu)?fù)述上述現(xiàn)象。如下圖所示,今天的大多數(shù)個(gè)人或者團(tuán)隊(duì)都會(huì)選擇 Kubernetes 管理容器,而也有 75% 的人會(huì)在生產(chǎn)環(huán)境中使用 Kubernetes。
圖 1 - Kubernetes 容器編排[^1]
在這種全民學(xué)習(xí)和使用 Kubernetes 的大背景下,我們也應(yīng)該非常清晰地知道 Kubernetes 有哪些局限性。雖然 Kubernetes 能夠解決容器編排領(lǐng)域的大多數(shù)問(wèn)題,但是仍然有一些場(chǎng)景是它很難處理、甚至無(wú)法處理的,只有對(duì)這些潛在的風(fēng)險(xiǎn)有清晰的認(rèn)識(shí),才能更好地駕馭這項(xiàng)技術(shù),這篇文章將從集群管理和應(yīng)用場(chǎng)景兩個(gè)部分談?wù)?Kubernetes 社區(qū)目前的發(fā)展和一些局限性。
集群管理
集群是一組能夠在一起協(xié)同工作的計(jì)算機(jī),我們可以將集群中的所有計(jì)算機(jī)看成一個(gè)整體,所有資源調(diào)度系統(tǒng)都是以集群為維度進(jìn)行管理的,集群中的所有機(jī)器構(gòu)成了資源池,這個(gè)巨大的資源池會(huì)為待運(yùn)行的容器提供資源執(zhí)行計(jì)算任務(wù),這里簡(jiǎn)單談一談 Kubernetes 集群管理面對(duì)的幾個(gè)復(fù)雜問(wèn)題。
水平擴(kuò)展性
集群大小是我們?cè)谠u(píng)估資源管理系統(tǒng)時(shí)需要關(guān)注的重要指標(biāo)之一,然而 Kubernetes 能夠管理的集群規(guī)模遠(yuǎn)遠(yuǎn)小于業(yè)界的其他資源管理系統(tǒng)。集群大小為什么重要呢,我們先來(lái)看另一個(gè)同樣重要的指標(biāo) — 資源利用率,很多工程師可能沒(méi)有在公有云平臺(tái)上申請(qǐng)過(guò)資源,這些資源都相當(dāng)昂貴,在 AWS 上申請(qǐng)一個(gè)與主機(jī)差不多配置的虛擬機(jī)實(shí)例(8 CPU、16 GB)每個(gè)月大概需要 150 美金,約為 1000 人民幣[^2]。
圖 2 - AWS EC2 價(jià)格大多數(shù)的集群都會(huì)使用 48 CPU 或者 64 CPU 的物理機(jī)或者虛擬機(jī)作為集群中的節(jié)點(diǎn),如果我們的集群中需要包含 5,000 個(gè)節(jié)點(diǎn),那么這些節(jié)點(diǎn)每個(gè)月大概要 8,000,000 美元,約為 50,000,000 人民幣,在這樣的集群中提升 1% 的資源利用率就相當(dāng)于每個(gè)月節(jié)省了 500,000 的成本。
多數(shù)在線任務(wù)的資源利用率都很低,更大的集群意味著能夠運(yùn)行更多的工作負(fù)載,而多種高峰和低谷期不同的負(fù)載部署在一起可以實(shí)現(xiàn)超售,這樣能夠顯著地提高集群的資源利用率,如果單個(gè)集群的節(jié)點(diǎn)數(shù)足夠多,我們?cè)诓渴鸩煌愋偷娜蝿?wù)時(shí)會(huì)有更合理的組合,可以完美錯(cuò)開不同服務(wù)的高峰期。
Kubernetes 社區(qū)對(duì)外宣傳的是單個(gè)集群最多支持 5,000 節(jié)點(diǎn),Pod 總數(shù)不超過(guò) 150,000,容器總數(shù)不超過(guò) 300,000 以及單節(jié)點(diǎn) Pod 數(shù)量不超過(guò) 100 個(gè)[^3],與幾萬(wàn)節(jié)點(diǎn)的 Apache Mesos 集群、50,000 節(jié)點(diǎn)的微軟 YARN 集群[^4]相比,Kubernetes 的集群規(guī)模整整差了一個(gè)數(shù)量級(jí)。雖然阿里云的工程師也通過(guò)優(yōu)化 Kubernetes 的各個(gè)組件實(shí)現(xiàn)了 5 位數(shù)的集群規(guī)模,但是與其他的資源管理方式相比卻有比較大的差距[^5]。
圖 3 - Apache Mesos 與 Hadoop YARN需要注意的是 Kubernetes 社區(qū)雖然對(duì)外宣稱單集群可以支持 5,000 節(jié)點(diǎn),同時(shí)社區(qū)也有各種各樣的集成測(cè)試保證每個(gè)改動(dòng)都不會(huì)影響它的伸縮性[^6],但是 Kubernetes 真的非常復(fù)雜,我們沒(méi)有辦法保證你使用的每個(gè)功能在擴(kuò)容的過(guò)程中都不出問(wèn)題。而在生產(chǎn)環(huán)境中,我們甚至可能在集群擴(kuò)容到 1000 ~ 1500 節(jié)點(diǎn)時(shí)遇到瓶頸。
每個(gè)稍具規(guī)模的大公司都想要實(shí)現(xiàn)更大規(guī)模的 Kubernetes 集群,但是這不是一個(gè)改幾行代碼就能解決的簡(jiǎn)單問(wèn)題,它可能需要我們限制 Kubernetes 中一些功能的使用,在擴(kuò)容的過(guò)程中,etcd、API 服務(wù)器、調(diào)度器以及控制器都有可能出現(xiàn)問(wèn)題。社區(qū)中已經(jīng)有一些開發(fā)者注意到了其中的一些問(wèn)題,例如在節(jié)點(diǎn)上增加緩存降低 API 服務(wù)器的負(fù)載[^7],但是要推動(dòng)類似的改變還是很困難的,有志之士可以嘗試在社區(qū)推動(dòng)類似的項(xiàng)目。
多集群管理
單個(gè)集群的容量再大也無(wú)法解決企業(yè)面對(duì)的問(wèn)題,哪怕有一天 Kubernetes 集群可以達(dá)到 50,000 節(jié)點(diǎn)的規(guī)模,我們?nèi)匀恍枰芾矶鄠€(gè)集群,多集群管理也是 Kubernetes 社區(qū)目前正在探索的方向,社區(qū)中的多集群興趣小組(SIG Multi-Cluster)目前就在完成相關(guān)的工作[^8]。在作者看來(lái),Kubernetes 的多集群會(huì)帶來(lái)資源不平衡、跨集群訪問(wèn)困難以及提高運(yùn)維和管理成本三大問(wèn)題,我們?cè)谶@里談一談目前在開源社區(qū)和業(yè)界幾種可供參考和選擇的解決方案。
kubefed
首先要介紹的是 kubefed,該項(xiàng)目是 Kubernetes 社區(qū)給出的解決方案,它同時(shí)提供了跨集群的資源和網(wǎng)絡(luò)管理的功能,社區(qū)的多集群興趣小組(SIG Multi-Cluster)負(fù)責(zé)了該項(xiàng)目的開發(fā)工作:
圖 4 - Kubernetes 聯(lián)邦kubefed 通過(guò)一個(gè)中心化的聯(lián)邦控制面板管理多集群中的元數(shù)據(jù),上層的控制面板會(huì)為管理器群中的資源創(chuàng)建對(duì)應(yīng)的聯(lián)邦對(duì)象,例如:FederatedDeployment:
kind:?FederatedDeployment ... spec:...overrides:#?Apply?overrides?to?cluster1-?clusterName:?cluster1clusterOverrides:#?Set?the?replicas?field?to?5-?path:?"/spec/replicas"value:?5#?Set?the?image?of?the?first?container-?path:?"/spec/template/spec/containers/0/image"value:?"nginx:1.17.0-alpine"#?Ensure?the?annotation?"foo:?bar"?exists-?path:?"/metadata/annotations"op:?"add"value:foo:?bar#?Ensure?an?annotation?with?key?"foo"?does?not?exist-?path:?"/metadata/annotations/foo"op:?"remove"#?Adds?an?argument?`-q`?at?index?0?of?the?args?list#?this?will?obviously?shift?the?existing?arguments,?if?any-?path:?"/spec/template/spec/containers/0/args/0"op:?"add"value:?"-q"上層的控制面板會(huì)根據(jù)聯(lián)邦對(duì)象 FederatedDeployment 的規(guī)格文件生成對(duì)應(yīng)的 Deployment 并推送到下層的集群,下層集群可以正常根據(jù) Deployment 中的定義創(chuàng)建特定數(shù)量的副本。
圖 5 - 從聯(lián)邦對(duì)象到普通對(duì)象FederatedDeployment 只是一種最簡(jiǎn)單的分發(fā)策略,在生產(chǎn)環(huán)境中我們希望通過(guò)聯(lián)邦的集群實(shí)現(xiàn)容災(zāi)等復(fù)雜功能,這時(shí)可以利用 ReplicaSchedulingPreference 在不同集群中實(shí)現(xiàn)更加智能的分發(fā)策略:
apiVersion:?scheduling.kubefed.io/v1alpha1 kind:?ReplicaSchedulingPreference metadata:name:?test-deploymentnamespace:?test-ns spec:targetKind:?FederatedDeploymenttotalReplicas:?9clusters:A:minReplicas:?4maxReplicas:?6weight:?1B:minReplicas:?4maxReplicas:?8weight:?2上述調(diào)度的策略可以實(shí)現(xiàn)工作負(fù)載在不同集群之間的權(quán)重,在集群資源不足甚至出現(xiàn)問(wèn)題時(shí)將實(shí)例遷移到其他集群,這樣既能夠提高服務(wù)部署的靈活性和可用性,基礎(chǔ)架構(gòu)工程師也可以更好地平衡多個(gè)集群的負(fù)載。
我們可以認(rèn)為 kubefed 的主要作用是將多個(gè)松散的集群組成強(qiáng)耦合的聯(lián)邦集群,并提供更加高級(jí)的網(wǎng)絡(luò)和部署功能,這樣我們可以更容易地解決集群之間資源不平衡和連通性的一些問(wèn)題,然而該項(xiàng)目的關(guān)注點(diǎn)不包含集群生命周期的管理。
集群接口
Cluster API 也是 Kubernetes 社區(qū)中與多集群管理相關(guān)的項(xiàng)目,該項(xiàng)目由集群生命周期小組(SIG Cluster-Lifecycle)負(fù)責(zé)開發(fā),其主要目標(biāo)是通過(guò)聲明式的 API 簡(jiǎn)化多集群的準(zhǔn)備、更新和運(yùn)維工作,你在該項(xiàng)目的 設(shè)計(jì)提案 中能夠找到它的職責(zé)范圍[^9]。
圖 6 - Cluster API 概念在該項(xiàng)目中最重要的資源就是 Machine,它表示一個(gè) Kubernetes 集群中的節(jié)點(diǎn)。當(dāng)該資源被創(chuàng)建時(shí),特定提供商的控制器會(huì)根據(jù)機(jī)器的定義初始化并將新的節(jié)點(diǎn)注冊(cè)到集群中,在該資源被更新或者刪除時(shí),也會(huì)執(zhí)行操作達(dá)到用戶的狀態(tài)。
這種策略與阿里的多集群管理的方式有一些相似,它們都使用聲明式的 API 定義機(jī)器和集群的狀態(tài),然后使用 Kubernetes 原生的 Operator 模型在更高一層的集群中管理下層集群,這能夠極大降低集群的運(yùn)維成本并提高集群的運(yùn)行效率[^10],不過(guò)類似的項(xiàng)目都沒(méi)有考慮跨集群的資源管理和網(wǎng)絡(luò)管理。
應(yīng)用場(chǎng)景
我們?cè)谶@一節(jié)將談?wù)?Kubernetes 中一些有趣的應(yīng)用場(chǎng)景,其中包括應(yīng)用分發(fā)方式的現(xiàn)狀、批處理調(diào)度任務(wù)以及硬多租戶在集群中的支持,這些是社區(qū)中比較關(guān)注的問(wèn)題,也是 Kubernetes 目前的盲點(diǎn)。
應(yīng)用分發(fā)
Kubernetes 主項(xiàng)目提供了幾種部署應(yīng)用的最基本方式,分別是 Deployment、StatefulSet 和 DaemonSet,這些資源分別適用于無(wú)狀態(tài)服務(wù)、有狀態(tài)服務(wù)和節(jié)點(diǎn)上的守護(hù)進(jìn)程,這些資源能夠提供最基本的策略,但是它們無(wú)法處理更加復(fù)雜的應(yīng)用。
圖 7 - Kubernetes 應(yīng)用管理隨著 CRD 的引入,目前社區(qū)的應(yīng)用管理小組(SIG Apps)基本不會(huì)向 Kubernetes 主倉(cāng)庫(kù)引入較大的改動(dòng),大多數(shù)的改動(dòng)都是在現(xiàn)有資源上進(jìn)行的修補(bǔ),很多常見(jiàn)的場(chǎng)景,例如只運(yùn)行一次的 DaemonSet[^11] 以及金絲雀和藍(lán)綠部署等功能,現(xiàn)在的資源也存在很多問(wèn)題,例如 StatefulSet 在初始化容器中卡住無(wú)法回滾和更新[^12]。
我們可以理解社區(qū)不想在 Kubernetes 中維護(hù)更多的基本資源,通過(guò)幾個(gè)基本的資源可以覆蓋 90% 的場(chǎng)景,剩下的各種復(fù)雜場(chǎng)景可以讓其他社區(qū)通過(guò) CRD 的方式實(shí)現(xiàn)。不過(guò)作者認(rèn)為如果社區(qū)能夠在上游實(shí)現(xiàn)更多高質(zhì)量的組件,這對(duì)于整個(gè)生態(tài)都是很有價(jià)值并且很重要的工作,需要注意的是假如各位讀者想要在 Kubernetes 項(xiàng)目中成為貢獻(xiàn)者,SIG Apps 可能不是一個(gè)很好的選擇。
批處理調(diào)度
機(jī)器學(xué)習(xí)、批處理任務(wù)和流式任務(wù)等工作負(fù)載的運(yùn)行從 Kubernetes 誕生第一天起到今天都不是它的強(qiáng)項(xiàng),大多數(shù)的公司都會(huì)使用 Kubernetes 運(yùn)行在線服務(wù)處理用戶請(qǐng)求,用 Yarn 管理的集群運(yùn)行批處理的負(fù)載。
hadoop-yarn圖 8 - Hadoop Yarn
在線任務(wù)和離線任務(wù)往往是兩種截然不同的作業(yè),大多數(shù)的在線任務(wù)都是無(wú)狀態(tài)的服務(wù),它們可以在不同機(jī)器上進(jìn)行遷移,彼此很難有極強(qiáng)的依賴關(guān)系;但是很多離線任務(wù)的拓?fù)浣Y(jié)構(gòu)都很復(fù)雜,有些任務(wù)需要多個(gè)作業(yè)一同執(zhí)行,而有些任務(wù)需要按照依賴關(guān)系先后執(zhí)行,這種復(fù)雜的調(diào)度場(chǎng)景在 Kubernetes 中比較難以處理。
在 Kubernetes 調(diào)度器引入調(diào)度框架之前,所有的 Pod 在調(diào)度器看來(lái)是沒(méi)有任何關(guān)聯(lián)的,不過(guò)有了調(diào)度框架,我們可以在調(diào)度系統(tǒng)中實(shí)現(xiàn)更加復(fù)雜的調(diào)度策略,例如保證一組 Pod 同時(shí)調(diào)度的 PodGroup[^13],這對(duì)于 Spark 和 TensorFlow 任務(wù)非常有用。
#?PodGroup?CRD?spec apiVersion:?scheduling.sigs.k8s.io/v1alpha1 kind:?PodGroup metadata:name:?nginx spec:scheduleTimeoutSeconds:?10minMember:?3 --- #?Add?a?label?`pod-group.scheduling.sigs.k8s.io`?to?mark?the?pod?belongs?to?a?group labels:pod-group.scheduling.sigs.k8s.io:?nginxVolcano 也是在 Kubernetes 上構(gòu)建的批處理任務(wù)管理系統(tǒng)[^14],它能夠處理機(jī)器學(xué)習(xí)、深度學(xué)習(xí)以及其他大數(shù)據(jù)應(yīng)用,可以支持包括 TensorFlow、Spark、PyTorch 和 MPI 在內(nèi)的多個(gè)框架。
圖 9 - Volcano雖然 Kubernetes 能夠運(yùn)行一些批處理任務(wù),但是距離在這個(gè)領(lǐng)域上取代 Yarn 等老牌資源管理系統(tǒng)上還有非常大的差距,相信在較長(zhǎng)的一段時(shí)間內(nèi),大多數(shù)公司都會(huì)同時(shí)維護(hù) Kubernetes 和 Yarn 兩種技術(shù)棧,分別管理和運(yùn)行不同類型的工作負(fù)載。
硬多租戶
多租戶是指同一個(gè)軟件實(shí)例可以為不同的用戶組提供服務(wù),Kubernetes 的多租戶是指多個(gè)用戶或者用戶組使用同一個(gè) Kubernetes 集群,今天的 Kubernetes 還很難做到硬多租戶支持,也就是同一個(gè)集群的多個(gè)租戶不會(huì)相互影響,也感知不到彼此的存在。
硬多租戶在 Kubernetes 中是一個(gè)很重要、也很困難的課題,合租公寓就是一個(gè)典型的多租戶場(chǎng)景,多個(gè)租客共享房屋內(nèi)的基礎(chǔ)設(shè)施,硬多租戶要求多個(gè)訪客之間不會(huì)相互影響,你可以想象這有多么困難,Kubernetes 社區(qū)甚至有一個(gè)工作小組專門討論和研究相關(guān)的問(wèn)題[^15],然而雖然感興趣的工程師很多,但是成果卻非常有限。
圖 10 - 多租戶盡管 Kubernetes 使用命名空間來(lái)劃分虛擬機(jī)群,然而這也很難實(shí)現(xiàn)真正的多租戶。多租戶的支持到底有哪些作用呢,這里簡(jiǎn)單列幾個(gè)多租戶帶來(lái)的好處:
Kubernetes 帶來(lái)的額外部署成本對(duì)于小集群來(lái)說(shuō)非常高昂,穩(wěn)定的 Kubernetes 集群一般都需要至少三個(gè)運(yùn)行 etcd 的主節(jié)點(diǎn),如果大多數(shù)的集群都是小集群,這些額外的機(jī)器會(huì)帶來(lái)很高的額外開銷;
Kubernetes 中運(yùn)行的容器可能需要共享物理機(jī)和虛擬機(jī),一些開發(fā)者可能在公司內(nèi)部遇到過(guò)自己的服務(wù)被其他業(yè)務(wù)影響,因?yàn)橹鳈C(jī)上容器可能隔離了 CPU 和內(nèi)存資源,但是沒(méi)有隔離 I/O、網(wǎng)絡(luò) 和 CPU 緩存等資源,這些資源的隔離是相對(duì)困難的;
如果 Kubernetes 能夠?qū)崿F(xiàn)硬多租戶,這不僅對(duì)云服務(wù)商和小集群的使用者來(lái)說(shuō)都是個(gè)福音,它還能夠隔離不同容器之間的影響并防止?jié)撛诎踩珕?wèn)題的發(fā)生,不過(guò)這在現(xiàn)階段還是比較難實(shí)現(xiàn)的。
總結(jié)
每個(gè)技術(shù)都有自己的生命周期,越底層的技術(shù)生命周期會(huì)越長(zhǎng),而越上層的技術(shù)生命周期也就越短,雖然 Kubernetes 是當(dāng)今容器界的扛把子,但是未來(lái)的事情沒(méi)有人可以說(shuō)的準(zhǔn)。我們要時(shí)刻清楚手中工具的優(yōu)點(diǎn)和缺點(diǎn),花一些時(shí)間學(xué)習(xí) Kubernetes 中設(shè)計(jì)的精髓,不過(guò)如果在未來(lái)的某一天 Kubernetes 也成為了過(guò)去,我們也應(yīng)該感到喜悅,因?yàn)闀?huì)有更好的工具取代它。
[^1]: Kubernetes and Container Security and Adoption Trends https://www.stackrox.com/kubernetes-adoption-security-and-market-share-for-containers/
[^2]: AWS Pricing Calculator https://calculator.aws/#/createCalculator/EC2
[^3]: Considerations for large clusters https://kubernetes.io/docs/setup/best-practices/cluster-large/
[^4]: How Microsoft drives exabyte analytics on the world’s largest YARN cluster https://azure.microsoft.com/en-us/blog/how-microsoft-drives-exabyte-analytics-on-the-world-s-largest-yarn-cluster/
[^5]: 備戰(zhàn)雙 11!螞蟻金服萬(wàn)級(jí)規(guī)模 K8s 集群管理系統(tǒng)如何設(shè)計(jì)?https://www.sofastack.tech/blog/ant-financial-managing-large-scale-kubernetes-clusters/
[^6]: sig-scalability-kubemark dashboard https://testgrid.k8s.io/sig-scalability-kubemark#kubemark-5000
[^7]: Node-local API cache #84248 https://github.com/kubernetes/kubernetes/issues/84248
[^8]: Multicluster Special Interest Group https://github.com/kubernetes/community/tree/master/sig-multicluster
[^9]: Cluster API Scope and Objectives https://github.com/kubernetes-sigs/cluster-api/blob/master/docs/scope-and-objectives.md
[^10]: Demystifying Kubernetes as a service – How Alibaba cloud manages 10,000s of Kubernetes clusters https://www.cncf.io/blog/2019/12/12/demystifying-kubernetes-as-a-service-how-does-alibaba-cloud-manage-10000s-of-kubernetes-clusters/
[^11]: Run job on each node once to help with setup #64623 https://github.com/kubernetes/kubernetes/issues/64623
[^12]: StatefulSet does not upgrade to a newer version of manifests #78007 https://github.com/kubernetes/kubernetes/issues/78007
[^13]: Coscheduling based on PodGroup CRD https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/kep/42-podgroup-coscheduling
[^14]: Volcano · A Kubernetes Native Batch System https://github.com/volcano-sh/volcano
[^15]: Kubernetes Working Group for Multi-Tenancy https://github.com/kubernetes-sigs/multi-tenancy
何為“邊緣計(jì)算”?編程祖師爺尼古拉斯?威茨:算法+數(shù)據(jù)結(jié)構(gòu)=程序“一學(xué)就會(huì)”的微服務(wù)架構(gòu)模式除了 k8s,留給 k 和 s 中間的數(shù)字不多了!到底是誰(shuí)發(fā)明了物聯(lián)網(wǎng)?再見(jiàn) Nacos,我要玩 Service Mesh?了!點(diǎn)分享點(diǎn)收藏點(diǎn)點(diǎn)贊點(diǎn)在看總結(jié)
以上是生活随笔為你收集整理的Kubernetes 也有局限性吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2020 年最厉害的 10 门编程语言
- 下一篇: 学会这10大高性能开发技术,轻松躲过裁员