新聞中心
談?wù)?Kubernetes 的問題和局限性
作者: Draveness 2021-04-20 08:31:13
云計(jì)算 014 年發(fā)布的 Kubernetes 在今天儼然已成為容器編排領(lǐng)域的事實(shí)標(biāo)準(zhǔn),相信談到 Kubernetes 的開發(fā)者都會一再復(fù)述上述現(xiàn)象。

為灌云等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及灌云網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、灌云網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
2014 年發(fā)布的 Kubernetes 在今天儼然已成為容器編排領(lǐng)域的事實(shí)標(biāo)準(zhǔn),相信談到 Kubernetes 的開發(fā)者都會一再復(fù)述上述現(xiàn)象。如下圖所示,今天的大多數(shù)個人或者團(tuán)隊(duì)都會選擇 Kubernetes 管理容器,而也有 75% 的人會在生產(chǎn)環(huán)境中使用 Kubernetes。
圖 1 - Kubernetes 容器編排[^1]
在這種全民學(xué)習(xí)和使用 Kubernetes 的大背景下,我們也應(yīng)該非常清晰地知道 Kubernetes 有哪些局限性。雖然 Kubernetes 能夠解決容器編排領(lǐng)域的大多數(shù)問題,但是仍然有一些場景是它很難處理、甚至無法處理的,只有對這些潛在的風(fēng)險(xiǎn)有清晰的認(rèn)識,才能更好地駕馭這項(xiàng)技術(shù),這篇文章將從集群管理和應(yīng)用場景兩個部分談?wù)?Kubernetes 社區(qū)目前的發(fā)展和一些局限性。
集群管理
集群是一組能夠在一起協(xié)同工作的計(jì)算機(jī),我們可以將集群中的所有計(jì)算機(jī)看成一個整體,所有資源調(diào)度系統(tǒng)都是以集群為維度進(jìn)行管理的,集群中的所有機(jī)器構(gòu)成了資源池,這個巨大的資源池會為待運(yùn)行的容器提供資源執(zhí)行計(jì)算任務(wù),這里簡單談一談 Kubernetes 集群管理面對的幾個復(fù)雜問題。
水平擴(kuò)展性
集群大小是我們在評估資源管理系統(tǒng)時需要關(guān)注的重要指標(biāo)之一,然而 Kubernetes 能夠管理的集群規(guī)模遠(yuǎn)遠(yuǎn)小于業(yè)界的其他資源管理系統(tǒng)。集群大小為什么重要呢,我們先來看另一個同樣重要的指標(biāo) — 資源利用率,很多工程師可能沒有在公有云平臺上申請過資源,這些資源都相當(dāng)昂貴,在 AWS 上申請一個與主機(jī)差不多配置的虛擬機(jī)實(shí)例(8 CPU、16 GB)每個月大概需要 150 美金,約為 1000 人民幣[^2]。
圖 2 - AWS EC2 價格
大多數(shù)的集群都會使用 48 CPU 或者 64 CPU 的物理機(jī)或者虛擬機(jī)作為集群中的節(jié)點(diǎn),如果我們的集群中需要包含 5,000 個節(jié)點(diǎn),那么這些節(jié)點(diǎn)每個月大概要 8,000,000 美元,約為 50,000,000 人民幣,在這樣的集群中提升 1% 的資源利用率就相當(dāng)于每個月節(jié)省了 500,000 的成本。
多數(shù)在線任務(wù)的資源利用率都很低,更大的集群意味著能夠運(yùn)行更多的工作負(fù)載,而多種高峰和低谷期不同的負(fù)載部署在一起可以實(shí)現(xiàn)超售,這樣能夠顯著地提高集群的資源利用率,如果單個集群的節(jié)點(diǎn)數(shù)足夠多,我們在部署不同類型的任務(wù)時會有更合理的組合,可以完美錯開不同服務(wù)的高峰期。
Kubernetes 社區(qū)對外宣傳的是單個集群最多支持 5,000 節(jié)點(diǎn),Pod 總數(shù)不超過 150,000,容器總數(shù)不超過 300,000 以及單節(jié)點(diǎn) Pod 數(shù)量不超過 100 個[^3],與幾萬節(jié)點(diǎn)的 Apache Mesos 集群、50,000 節(jié)點(diǎn)的微軟 YARN 集群[^4]相比,Kubernetes 的集群規(guī)模整整差了一個數(shù)量級。雖然阿里云的工程師也通過優(yōu)化 Kubernetes 的各個組件實(shí)現(xiàn)了 5 位數(shù)的集群規(guī)模,但是與其他的資源管理方式相比卻有比較大的差距[^5]。
圖 3 - Apache Mesos 與 Hadoop YARN
需要注意的是 Kubernetes 社區(qū)雖然對外宣稱單集群可以支持 5,000 節(jié)點(diǎn),同時社區(qū)也有各種各樣的集成測試保證每個改動都不會影響它的伸縮性[^6],但是 Kubernetes 真的非常復(fù)雜,我們沒有辦法保證你使用的每個功能在擴(kuò)容的過程中都不出問題。而在生產(chǎn)環(huán)境中,我們甚至可能在集群擴(kuò)容到 1000 ~ 1500 節(jié)點(diǎn)時遇到瓶頸。
每個稍具規(guī)模的大公司都想要實(shí)現(xiàn)更大規(guī)模的 Kubernetes 集群,但是這不是一個改幾行代碼就能解決的簡單問題,它可能需要我們限制 Kubernetes 中一些功能的使用,在擴(kuò)容的過程中,etcd、API 服務(wù)器、調(diào)度器以及控制器都有可能出現(xiàn)問題。社區(qū)中已經(jīng)有一些開發(fā)者注意到了其中的一些問題,例如在節(jié)點(diǎn)上增加緩存降低 API 服務(wù)器的負(fù)載[^7],但是要推動類似的改變還是很困難的,有志之士可以嘗試在社區(qū)推動類似的項(xiàng)目。
多集群管理
單個集群的容量再大也無法解決企業(yè)面對的問題,哪怕有一天 Kubernetes 集群可以達(dá)到 50,000 節(jié)點(diǎn)的規(guī)模,我們?nèi)匀恍枰芾矶鄠€集群,多集群管理也是 Kubernetes 社區(qū)目前正在探索的方向,社區(qū)中的多集群興趣小組(SIG Multi-Cluster)目前就在完成相關(guān)的工作[^8]。在作者看來,Kubernetes 的多集群會帶來資源不平衡、跨集群訪問困難以及提高運(yùn)維和管理成本三大問題,我們在這里談一談目前在開源社區(qū)和業(yè)界幾種可供參考和選擇的解決方案。
kubefed
首先要介紹的是 kubefed,該項(xiàng)目是 Kubernetes 社區(qū)給出的解決方案,它同時提供了跨集群的資源和網(wǎng)絡(luò)管理的功能,社區(qū)的多集群興趣小組(SIG Multi-Cluster)負(fù)責(zé)了該項(xiàng)目的開發(fā)工作:
圖 4 - Kubernetes 聯(lián)邦
kubefed 通過一個中心化的聯(lián)邦控制面板管理多集群中的元數(shù)據(jù),上層的控制面板會為管理器群中的資源創(chuàng)建對應(yīng)的聯(lián)邦對象,例如:FederatedDeployment:
- kind: FederatedDeployment
- ...
- spec:
- ...
- overrides:
- # Apply overrides to cluster1
- - clusterName: cluster1
- clusterOverrides:
- # 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"
上層的控制面板會根據(jù)聯(lián)邦對象 FederatedDeployment 的規(guī)格文件生成對應(yīng)的 Deployment 并推送到下層的集群,下層集群可以正常根據(jù) Deployment 中的定義創(chuàng)建特定數(shù)量的副本。
圖 5 - 從聯(lián)邦對象到普通對象
FederatedDeployment 只是一種最簡單的分發(fā)策略,在生產(chǎn)環(huán)境中我們希望通過聯(lián)邦的集群實(shí)現(xiàn)容災(zāi)等復(fù)雜功能,這時可以利用 ReplicaSchedulingPreference 在不同集群中實(shí)現(xiàn)更加智能的分發(fā)策略:
- apiVersion: scheduling.kubefed.io/v1alpha1
- kind: ReplicaSchedulingPreference
- metadata:
- name: test-deployment
- namespace: test-ns
- spec:
- targetKind: FederatedDeployment
- totalReplicas: 9
- clusters:
- A:
- minReplicas: 4
- maxReplicas: 6
- weight: 1
- B:
- minReplicas: 4
- maxReplicas: 8
- weight: 2
上述調(diào)度的策略可以實(shí)現(xiàn)工作負(fù)載在不同集群之間的權(quán)重,在集群資源不足甚至出現(xiàn)問題時將實(shí)例遷移到其他集群,這樣既能夠提高服務(wù)部署的靈活性和可用性,基礎(chǔ)架構(gòu)工程師也可以更好地平衡多個集群的負(fù)載。
我們可以認(rèn)為 kubefed 的主要作用是將多個松散的集群組成強(qiáng)耦合的聯(lián)邦集群,并提供更加高級的網(wǎng)絡(luò)和部署功能,這樣我們可以更容易地解決集群之間資源不平衡和連通性的一些問題,然而該項(xiàng)目的關(guān)注點(diǎn)不包含集群生命周期的管理,
集群接口
Cluster API 也是 Kubernetes 社區(qū)中與多集群管理相關(guān)的項(xiàng)目,該項(xiàng)目由集群生命周期小組(SIG Cluster-Lifecycle)負(fù)責(zé)開發(fā),其主要目標(biāo)是通過聲明式的 API 簡化多集群的準(zhǔn)備、更新和運(yùn)維工作,你在該項(xiàng)目的 設(shè)計(jì)提案 中能夠找到它的職責(zé)范圍[^9]。
圖 6 - Cluster API 概念
在該項(xiàng)目中最重要的資源就是 Machine,它表示一個 Kubernetes 集群中的節(jié)點(diǎn)。當(dāng)該資源被創(chuàng)建時,特定提供商的控制器會根據(jù)機(jī)器的定義初始化并將新的節(jié)點(diǎn)注冊到集群中,在該資源被更新或者刪除時,也會執(zhí)行操作達(dá)到用戶的狀態(tài)。
這種策略與阿里的多集群管理的方式有一些相似,它們都使用聲明式的 API 定義機(jī)器和集群的狀態(tài),然后使用 Kubernetes 原生的 Operator 模型在更高一層的集群中管理下層集群,這能夠極大降低集群的運(yùn)維成本并提高集群的運(yùn)行效率[^10],不過類似的項(xiàng)目都沒有考慮跨集群的資源管理和網(wǎng)絡(luò)管理。
應(yīng)用場景
我們在這一節(jié)將談?wù)?Kubernetes 中一些有趣的應(yīng)用場景,其中包括應(yīng)用分發(fā)方式的現(xiàn)狀、批處理調(diào)度任務(wù)以及硬多租戶在集群中的支持,這些是社區(qū)中比較關(guān)注的問題,也是 Kubernetes 目前的盲點(diǎn)。
應(yīng)用分發(fā)
Kubernetes 主項(xiàng)目提供了幾種部署應(yīng)用的最基本方式,分別是 Deployment、StatefulSet 和 DaemonSet,這些資源分別適用于無狀態(tài)服務(wù)、有狀態(tài)服務(wù)和節(jié)點(diǎn)上的守護(hù)進(jìn)程,這些資源能夠提供最基本的策略,但是它們無法處理更加復(fù)雜的應(yīng)用。
圖 7 - Kubernetes 應(yīng)用管理
隨著 CRD 的引入,目前社區(qū)的應(yīng)用管理小組(SIG Apps)基本不會向 Kubernetes 主倉庫引入較大的改動,大多數(shù)的改動都是在現(xiàn)有資源上進(jìn)行的修補(bǔ),很多常見的場景,例如只運(yùn)行一次的 DaemonSet[^11] 以及金絲雀和藍(lán)綠部署等功能,現(xiàn)在的資源也存在很多問題,例如 StatefulSet 在初始化容器中卡住無法回滾和更新[^12]。
我們可以理解社區(qū)不想在 Kubernetes 中維護(hù)更多的基本資源,通過幾個基本的資源可以覆蓋 90% 的場景,剩下的各種復(fù)雜場景可以讓其他社區(qū)通過 CRD 的方式實(shí)現(xiàn)。不過作者認(rèn)為如果社區(qū)能夠在上游實(shí)現(xiàn)更多高質(zhì)量的組件,這對于整個生態(tài)都是很有價值并且很重要的工作,需要注意的是假如各位讀者想要在 Kubernetes 項(xiàng)目中成為貢獻(xiàn)者,SIG Apps 可能不是一個很好的選擇。
批處理調(diào)度
機(jī)器學(xué)習(xí)、批處理任務(wù)和流式任務(wù)等工作負(fù)載的運(yùn)行從 Kubernetes 誕生第一天起到今天都不是它的強(qiáng)項(xiàng),大多數(shù)的公司都會使用 Kubernetes 運(yùn)行在線服務(wù)處理用戶請求,用 Yarn 管理的集群運(yùn)行批處理的負(fù)載。
hadoop-yarn
圖 8 - Hadoop Yarn
在線任務(wù)和離線任務(wù)往往是兩種截然不同的作業(yè),大多數(shù)的在線任務(wù)都是無狀態(tài)的服務(wù),它們可以在不同機(jī)器上進(jìn)行遷移,彼此很難有極強(qiáng)的依賴關(guān)系;但是很多離線任務(wù)的拓?fù)浣Y(jié)構(gòu)都很復(fù)雜,有些任務(wù)需要多個作業(yè)一同執(zhí)行,而有些任務(wù)需要按照依賴關(guān)系先后執(zhí)行,這種復(fù)雜的調(diào)度場景在 Kubernetes 中比較難以處理。
在 Kubernetes 調(diào)度器引入調(diào)度框架之前,所有的 Pod 在調(diào)度器看來是沒有任何關(guān)聯(lián)的,不過有了調(diào)度框架,我們可以在調(diào)度系統(tǒng)中實(shí)現(xiàn)更加復(fù)雜的調(diào)度策略,例如保證一組 Pod 同時調(diào)度的 PodGroup[^13],這對于 Spark 和 TensorFlow 任務(wù)非常有用。
- # PodGroup CRD spec
- apiVersion: scheduling.sigs.k8s.io/v1alpha1
- kind: PodGroup
- metadata:
- name: nginx
- spec:
- scheduleTimeoutSeconds: 10
- minMember: 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: nginx
Volcano 也是在 Kubernetes 上構(gòu)建的批處理任務(wù)管理系統(tǒng)[^14],它能夠處理機(jī)器學(xué)習(xí)、深度學(xué)習(xí)以及其他大數(shù)據(jù)應(yīng)用,可以支持包括 TensorFlow、Spark、PyTorch 和 MPI 在內(nèi)的多個框架。
圖 9 - Volcano
雖然 Kubernetes 能夠運(yùn)行一些批處理任務(wù),但是距離在這個領(lǐng)域上取代 Yarn 等老牌資源管理系統(tǒng)上還有非常大的差距,相信在較長的一段時間內(nèi),大多數(shù)公司都會同時維護(hù) Kubernetes 和 Yarn 兩種技術(shù)棧,分別管理和運(yùn)行不同類型的工作負(fù)載。
硬多租戶
多租戶是指同一個軟件實(shí)例可以為不同的用戶組提供服務(wù),Kubernetes 的多租戶是指多個用戶或者用戶組使用同一個 Kubernetes 集群,今天的 Kubernetes 還很難做到硬多租戶支持,也就是同一個集群的多個租戶不會相互影響,也感知不到彼此的存在。
硬多租戶在 Kubernetes 中是一個很重要、也很困難的課題,合租公寓就是一個典型的多租戶場景,多個租客共享房屋內(nèi)的基礎(chǔ)設(shè)施,硬多租戶要求多個訪客之間不會相互影響,你可以想象這有多么困難,Kubernetes 社區(qū)甚至有一個工作小組專門討論和研究相關(guān)的問題[^15],然而雖然感興趣的工程師很多,但是成果卻非常有限。
圖 10 - 多租戶
盡管 Kubernetes 使用命名空間來劃分虛擬機(jī)群,然而這也很難實(shí)現(xiàn)真正的多租戶。多租戶的支持到底有哪些作用呢,這里簡單列幾個多租戶帶來的好處:
Kubernetes 帶來的額外部署成本對于小集群來說非常高昂,穩(wěn)定的 Kubernetes 集群一般都需要至少三個運(yùn)行 etcd 的主節(jié)點(diǎn),如果大多數(shù)的集群都是小集群,這些額外的機(jī)器會帶來很高的額外開銷;
Kubernetes 中運(yùn)行的容器可能需要共享物理機(jī)和虛擬機(jī),一些開發(fā)者可能在公司內(nèi)部遇到過自己的服務(wù)被其他業(yè)務(wù)影響,因?yàn)橹鳈C(jī)上容器可能隔離了 CPU 和內(nèi)存資源,但是沒有隔離 I/O、網(wǎng)絡(luò) 和 CPU 緩存等資源,這些資源的隔離是相對困難的;
如果 Kubernetes 能夠?qū)崿F(xiàn)硬多租戶,這不僅對云服務(wù)商和小集群的使用者來說都是個福音,它還能夠隔離不同容器之間的影響并防止?jié)撛诎踩珕栴}的發(fā)生,不過這在現(xiàn)階段還是比較難實(shí)現(xiàn)的。
總結(jié)
每個技術(shù)都有自己的生命周期,越底層的技術(shù)生命周期會越長,而越上層的技術(shù)生命周期也就越短,雖然 Kubernetes 是當(dāng)今容器界的扛把子,但是未來的事情沒有人可以說的準(zhǔn)。我們要時刻清楚手中工具的優(yōu)點(diǎn)和缺點(diǎn),花一些時間學(xué)習(xí) Kubernetes 中設(shè)計(jì)的精髓,不過如果在未來的某一天 Kubernetes 也成為了過去,我們也應(yīng)該感到喜悅,因?yàn)闀懈玫墓ぞ呷〈?/p>
[^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!螞蟻金服萬級規(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
文章名稱:談?wù)凨ubernetes的問題和局限性
當(dāng)前路徑:http://m.fisionsoft.com.cn/article/ccdgipo.html


咨詢
建站咨詢
