Serverless 与容器决战在即?有了弹性伸缩就不一样了
作者 | 阿里云容器技術(shù)專家 莫源??
本文整理自莫源于 8 月 31 日?K8s & cloudnative meetup 深圳場(chǎng)的演講內(nèi)容。關(guān)注“阿里巴巴云原生”公眾號(hào),回復(fù)關(guān)鍵詞“資料”,即可獲得 2019 全年 meetup 活動(dòng) PPT 合集及 K8s 最全知識(shí)圖譜。
導(dǎo)讀:Serverless 和 Autoscaling 是近些年來(lái)廣大開發(fā)者非常關(guān)心的內(nèi)容。有人說(shuō) Serverless 是容器 2.0,終有一天容器會(huì)和 Serverless 進(jìn)行一場(chǎng)決戰(zhàn),分出勝負(fù)。實(shí)際上,容器和 Serverless 是可以共存并且互補(bǔ)的,特別是在 Autoscaling 相關(guān)的場(chǎng)景下,Serverless 可以與容器完美兼容,彌補(bǔ)容器場(chǎng)景在使用簡(jiǎn)單、速度、成本的缺欠,在本文中將會(huì)為大家介紹容器在彈性場(chǎng)景下的原理、方案與挑戰(zhàn),以及 Serverless 是如何幫助容器解決這些問(wèn)題的。
當(dāng)我們?cè)谡務(wù)?#34;彈性伸縮"的時(shí)候
當(dāng)我們?cè)谡務(wù)?#34;彈性伸縮"的時(shí)候,我們?cè)谡務(wù)撌裁?#xff1f;"彈性伸縮"對(duì)于團(tuán)隊(duì)中不同的角色有不同的意義,而這正是彈性伸縮的魅力所在。
從一張資源曲線圖講起
這張圖是闡述彈性伸縮問(wèn)題時(shí)經(jīng)常引用的一張圖,表示的是集群的實(shí)際資源容量和應(yīng)用所需容量之間的關(guān)系。
- 其中紅色的曲線表示的是應(yīng)用實(shí)際所需的容量,因?yàn)閼?yīng)用的資源申請(qǐng)量相比節(jié)點(diǎn)而言會(huì)小很多,因此曲線相對(duì)比較平滑;
- 而綠色的折線表示的是集群的實(shí)際資源容量,折線的拐點(diǎn)表明此時(shí)進(jìn)行了手動(dòng)的容量調(diào)整,例如增加節(jié)點(diǎn)或者移除節(jié)點(diǎn),因?yàn)閱蝹€(gè)節(jié)點(diǎn)的資源容量固定且相對(duì)較大,因此以折線為主。
首先,我們先看左側(cè)第一塊黃色柵格的區(qū)域,這個(gè)區(qū)域表示集群的容量無(wú)法滿足業(yè)務(wù)的容量所需,在實(shí)際的場(chǎng)景中,通常會(huì)伴隨出現(xiàn)由于資源不足而無(wú)法調(diào)度的 Pod 等現(xiàn)象。
中間的柵格區(qū)域,集群的容量遠(yuǎn)高于實(shí)際資源所需的容量,此時(shí)會(huì)出現(xiàn)資源的浪費(fèi),實(shí)際的表現(xiàn)通常是節(jié)點(diǎn)的負(fù)載分配不均,部分節(jié)點(diǎn)上面無(wú)調(diào)度負(fù)載,而另外一些節(jié)點(diǎn)的負(fù)載相對(duì)較高。
右側(cè)柵格區(qū)域表示的是激增的峰值容量,我們可以看到,到達(dá)峰值前的曲率是非常陡峭的,這種場(chǎng)景通常是由于流量激增、大批量任務(wù)等非常規(guī)容量規(guī)劃內(nèi)的場(chǎng)景,激增的峰值流量給運(yùn)維同學(xué)的反應(yīng)時(shí)間非常短,一旦處理不當(dāng)就有可能引發(fā)事故。
彈性伸縮對(duì)于不同角色的人員,有著不同的意義:
- 開發(fā)人員希望通過(guò)彈性伸縮使應(yīng)用獲得高可用的保障;
- 運(yùn)維人員希望通過(guò)彈性伸縮降低基礎(chǔ)設(shè)施的管理成本;
- 架構(gòu)師希望通過(guò)彈性伸縮得到靈活彈性的架構(gòu)應(yīng)對(duì)突發(fā)的激增峰值。
彈性伸縮有多種不同的組件和方案,選擇適合自己業(yè)務(wù)需求的方案是落地執(zhí)行前的第一步。
Kubernetes 彈性伸縮能力解讀
Kubernetes 彈性伸縮的相關(guān)組件
Kubernetes 彈性伸縮的組件可以從兩個(gè)維度進(jìn)行解讀:一個(gè)是伸縮方向,一個(gè)是伸縮對(duì)象。
從伸縮方向上,分為橫向與縱向。從伸縮對(duì)象上,分為節(jié)點(diǎn)與 Pod。那么將這個(gè)象限進(jìn)行展開,就變成如下 3 類組件:
其中 HPA 與 Cluster-Autoscaler 是開發(fā)者最常組合使用的彈性伸縮組件。HPA 負(fù)責(zé)容器的水平伸縮,Cluster-Autoscaler 負(fù)責(zé)節(jié)點(diǎn)的水平伸縮。很多的開發(fā)者會(huì)產(chǎn)生這樣的疑問(wèn):為什么彈性伸縮一個(gè)功能需要細(xì)化成這么多組件分開處理,難道不可以直接設(shè)置一個(gè)閾值,就實(shí)現(xiàn)集群的自動(dòng)水位管理嗎?
Kubernetes 的彈性伸縮挑戰(zhàn)
了解 Kubernetes 的調(diào)度方式可以幫助開發(fā)者更好的理解 Kubernetes 彈性伸縮的設(shè)計(jì)哲學(xué)。在 Kubernetes 中,調(diào)度的最小單元是一個(gè) Pod,Pod 會(huì)根據(jù)調(diào)度策略被調(diào)度到滿足條件的節(jié)點(diǎn)上,這些策略包括資源的匹配關(guān)系、親和性與反親和性等等,其中資源的匹配關(guān)系的計(jì)算是調(diào)度中的核心要素。
通常和資源相關(guān)的有如下四個(gè)概念:
- Capacity 表示一個(gè)節(jié)點(diǎn)所能分配的容量總量;
- Limit 表示一個(gè) Pod 能夠使用的資源總量;
- Request 表示一個(gè) Pod 在調(diào)度上占用的資源空間;
- Used 表示一個(gè) Pod 的真實(shí)資源使用。
在了解這四個(gè)基本概念和使用場(chǎng)景之后,我們?cè)賮?lái)看下 Kubernetes 彈性伸縮的三大難題:
還記得在沒(méi)有使用容器前,是如何做容量規(guī)劃的嗎?一般會(huì)按照應(yīng)用來(lái)進(jìn)行機(jī)器的分配,例如,應(yīng)用 A 需要 2 臺(tái) 4C8G 的機(jī)器,應(yīng)用 B 需要 4 臺(tái) 8C16G 的機(jī)器,應(yīng)用 A 的機(jī)器與應(yīng)用 B 的機(jī)器是獨(dú)立的,相互不干擾。到了容器的場(chǎng)景中,大部分的開發(fā)者無(wú)需關(guān)心底層的資源了,那么這個(gè)時(shí)候容量規(guī)劃哪里去了呢?
在 Kubernetes 中是通過(guò)?Request?和?Limit?的方式進(jìn)行設(shè)置,Request?表示資源的申請(qǐng)值,Limit?表示資源的限制值。既然?Request?和?Limit?才是容量規(guī)劃的對(duì)等概念,那么這就代表著資源的實(shí)際計(jì)算規(guī)則要根據(jù)?Request?和?Limit?才更加準(zhǔn)確。而對(duì)于每個(gè)節(jié)點(diǎn)預(yù)留資源閾值而言,很有可能會(huì)造成小節(jié)點(diǎn)的預(yù)留無(wú)法滿足調(diào)度,大節(jié)點(diǎn)的預(yù)留又調(diào)度不完的場(chǎng)景。
在一個(gè) Kubernetes 集群中,通常不只包含一種規(guī)格的機(jī)器。針對(duì)不同的場(chǎng)景、不同的需求,機(jī)器的配置、容量可能會(huì)有非常大的差異,那么集群伸縮時(shí)的百分比就具備非常大的迷惑性。
假設(shè)我們的集群中存在 4C8G 的機(jī)器與 16C32G 兩種不同規(guī)格的機(jī)器,對(duì)于 10% 的資源預(yù)留而言,這兩種規(guī)格是所代表的意義是完全不同的。特別是在縮容的場(chǎng)景下,通常為了保證縮容后的集群不處在震蕩狀態(tài),我們會(huì)一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)來(lái)縮容節(jié)點(diǎn),那么如何根據(jù)百分比來(lái)判斷當(dāng)前節(jié)點(diǎn)是處在縮容狀態(tài)就尤為重要。此時(shí)如果大規(guī)格機(jī)器有較低的利用率被判斷縮容,那么很有可能會(huì)造成節(jié)點(diǎn)縮容后,容器重新調(diào)度后的爭(zhēng)搶饑餓。如果添加判斷條件,優(yōu)先縮容小配置的節(jié)點(diǎn),則有可能造成縮容后資源的大量冗余,最終集群中可能會(huì)只剩下所有的巨石節(jié)點(diǎn)。
集群的資源利用率是否可以真的代表當(dāng)前的集群狀態(tài)呢?當(dāng)一個(gè) Pod 的資源利用率很低的時(shí)候,不代表就可以侵占他所申請(qǐng)的資源。在大部分的生產(chǎn)集群中,資源利用率都不會(huì)保持在一個(gè)非常高的水位,但從調(diào)度來(lái)講,資源的調(diào)度水位應(yīng)該保持在一個(gè)比較高的水位。這樣才能既保證集群的穩(wěn)定可用,又不過(guò)于浪費(fèi)資源。
如果沒(méi)有設(shè)置?Request?與?Limit,而集群的整體資源利用率很高,這意味著什么?這表示所有的 Pod 都在被以真實(shí)負(fù)載為單元進(jìn)行調(diào)度,相互之間存在非常嚴(yán)重的爭(zhēng)搶,而且簡(jiǎn)單的加入節(jié)點(diǎn)也絲毫無(wú)法解決問(wèn)題,因?yàn)閷?duì)于一個(gè)已調(diào)度的 Pod 而言,除了手動(dòng)調(diào)度與驅(qū)逐,沒(méi)有任何方式可以將這個(gè) Pod 從高負(fù)載的節(jié)點(diǎn)中移走。那如果我們?cè)O(shè)置了?Request?與?Limit?而節(jié)點(diǎn)的資源利用率又非常高的時(shí)候說(shuō)明了什么呢?很可惜這在大部分的場(chǎng)景下都是不可能的,因?yàn)椴煌膽?yīng)用不同的負(fù)載在不同的時(shí)刻資源的利用率也會(huì)有所差異,大概率的情況是集群還沒(méi)有觸發(fā)設(shè)置的閾值就已經(jīng)無(wú)法調(diào)度 Pod 了。
在了解了 Kubernetes 彈性伸縮的三大問(wèn)題后,我們?cè)賮?lái)看下 Kubernetes 的解決辦法是什么?
Kubernetes 的彈性伸縮設(shè)計(jì)哲學(xué)
Kubernetes 的設(shè)計(jì)理念是將彈性伸縮分成調(diào)度層伸縮和資源層伸縮。調(diào)度層負(fù)責(zé)根據(jù)指標(biāo)、閾值伸縮出調(diào)度單元,而資源層伸縮負(fù)責(zé)滿足調(diào)度單元的資源需求。
在調(diào)度層通常是通過(guò) HPA 的方式進(jìn)行 Pod 的水平伸縮,HPA 的使用方式和我們傳統(tǒng)意義上理解的彈性伸縮是非常接近和類似的,通過(guò)設(shè)置判斷的指標(biāo)、判斷的閾值來(lái)進(jìn)行水平伸縮。
在資源層目前主流的方案是通過(guò) cluster-autoscaler 進(jìn)行節(jié)點(diǎn)的水平伸縮。當(dāng)出現(xiàn) Pod 由于資源不足造成無(wú)法調(diào)度時(shí),cluster-autoscaler 會(huì)嘗試從配置伸縮組中,選擇一個(gè)可以滿足調(diào)度需求的組,并自動(dòng)向組內(nèi)加入實(shí)例,當(dāng)實(shí)例啟動(dòng)后注冊(cè)到 Kubernetes 后,kube-scheduler 會(huì)重新觸發(fā) Pod 的調(diào)度,將之前無(wú)法調(diào)度的 Pod 調(diào)度到新生成的節(jié)點(diǎn)上,從而完成全鏈路的擴(kuò)容。
同樣在縮容時(shí),調(diào)度層會(huì)現(xiàn)根據(jù)資源的利用率與設(shè)置的閾值比較,實(shí)現(xiàn) Pod 水平的縮容。當(dāng)節(jié)點(diǎn)上 Pod 的調(diào)度資源降低到資源層縮容閾值的時(shí)候,此時(shí) Cluster-Autoscaler 會(huì)進(jìn)行低調(diào)度百分比的節(jié)點(diǎn)的排水,排水完成后會(huì)進(jìn)行節(jié)點(diǎn)的縮容,完成整個(gè)鏈路的收縮。
Kubernetes 彈性伸縮方案的阿克琉斯之踵
經(jīng)典的 Kubernetes 彈性伸縮的案例
這張圖是一個(gè)非常經(jīng)典的彈性伸縮的案例,可以代表大多數(shù)的在線業(yè)務(wù)的場(chǎng)景。應(yīng)用的初始架構(gòu)是一個(gè) Deployment,下面有兩個(gè) Pod,這個(gè)應(yīng)用的接入層是通 過(guò)Ingress Controller 的方式進(jìn)行對(duì)外暴露的,我們?cè)O(shè)置應(yīng)用的伸縮策略為:單個(gè) Pod 的 QPS 到達(dá) 100,則進(jìn)行擴(kuò)容,最小為 2 個(gè) Pod,最大為 10 個(gè) Pod。
HPA controller 會(huì)不斷輪訓(xùn) alibaba-cloud-metrics-adapter,來(lái)獲取 Ingress Gateway 當(dāng)前路由的 QPS 指標(biāo)。當(dāng) Ingress Gateway 的流量到達(dá) QPS 閾值時(shí),HPA controller 會(huì)觸發(fā) Deployment 的 Pod 數(shù)目變化;當(dāng) Pod 的申請(qǐng)容量超過(guò)集群的總量后,cluster-autoscaler 會(huì)選擇合適的伸縮組,彈出相應(yīng)的 Node,承載之前未調(diào)度的 Pod。
這樣一個(gè)經(jīng)典的彈性伸縮案例就解析完畢了,那么在實(shí)際的開發(fā)過(guò)程中,會(huì)遇到哪些問(wèn)題呢?
經(jīng)典的 Kubernetes 彈性伸縮的缺點(diǎn)與解法
首先是擴(kuò)容時(shí)延的問(wèn)題,社區(qū)標(biāo)準(zhǔn)模式是通過(guò)創(chuàng)建、釋放 ECS 的方式,擴(kuò)容的時(shí)延在 2min-2.5min 左右,而阿里云獨(dú)立的極速模式是通過(guò)創(chuàng)建、停機(jī)、啟動(dòng)的方式進(jìn)行實(shí)現(xiàn),停機(jī)時(shí)只收取存儲(chǔ)的費(fèi)用,不收取計(jì)算的費(fèi)用。可以通過(guò)非常低廉的價(jià)格獲得 50% 以上的彈性效率。此外復(fù)雜度也是 cluster-autoscaler 繞不過(guò)的問(wèn)題,想要用好 cluster-autoscaler,需要深入的了解 cluster-autoscaler 的一些內(nèi)部機(jī)制,否則極有可能造成無(wú)法彈出或者無(wú)法縮容的場(chǎng)景。對(duì)于大多數(shù)的開發(fā)者而言,cluster-autoscaler 的工作原理是黑盒的,而且 cluster-autoscaler 目前最好的問(wèn)題排查方式依然是查看日志。一旦 cluster-autoscaler 出現(xiàn)運(yùn)行異常后者由于開發(fā)者配置錯(cuò)誤導(dǎo)致無(wú)法如預(yù)期的伸縮,那么 80% 以上的開發(fā)者是很難自己進(jìn)行糾錯(cuò)的。
阿里云容器服務(wù)團(tuán)隊(duì)開發(fā)了一款 kubectl plugin,可以提供 cluster-autoscaler 更深層次的可觀測(cè)性,可以查看當(dāng)前 cluster-autoscaler 所在的伸縮階段以及自動(dòng)彈性伸縮糾錯(cuò)等能力。
雖然目前遇到的幾個(gè)核心的問(wèn)題,都不是壓死駱駝的最后一棵稻草。但是我們一直在思考,是否有其他的方式可以讓彈性伸縮使用起來(lái)更簡(jiǎn)單、更高效?
阿克琉斯的馬丁靴 - Serverless Autoscaling
資源層伸縮的核心問(wèn)題在于學(xué)習(xí)成本較高、排錯(cuò)困難、時(shí)效性差。當(dāng)回過(guò)頭來(lái)看 Serverless 的時(shí)候,我們可以發(fā)現(xiàn)這些問(wèn)題恰好是 Serverless 的特點(diǎn)與優(yōu)勢(shì),那么是否有辦法讓 Serverless 成為 Kubernetes 資源層的彈性方案呢?
Serverless Autoscaling 組件 - virtual-kubelet-autoscaler
阿里云容器服務(wù)團(tuán)隊(duì)開發(fā)了 virtual-kubelet-autoscaler,一個(gè)在 Kubernetes 中實(shí)現(xiàn) serverless autoscaling 的組件。
當(dāng)出現(xiàn)了無(wú)法調(diào)度的 Pod 的時(shí)候,virtual-kubelet 負(fù)責(zé)承載真實(shí)的負(fù)載,可以理解為一個(gè)虛擬節(jié)點(diǎn),擁有無(wú)限大的 capacity。當(dāng) Pod 調(diào)度到 virtual-kubelet 上時(shí),會(huì)將 Pod 通過(guò)輕量級(jí)實(shí)例 ECI 進(jìn)行啟動(dòng)。目前 ECI 的啟動(dòng)時(shí)間在 30s 之內(nèi),程序從調(diào)度開始到運(yùn)行一般會(huì)在 1 分鐘內(nèi)拉起。
與 cluster-autoscaler 類似,virtual-kubelet-autoscaler 也需要使用模擬調(diào)度的機(jī)制來(lái)判斷 Pod 是否可以被真實(shí)處理和承載,但是相比 cluster-autoscaler 而言,存在如下差異:
virtual-kubelet-autoscaler 不是"銀彈"
virtual-kubelet-autoscaler 并不是用來(lái)替代 cluster-autoscaler 的,virtual-kubelet-autoscaler 的優(yōu)勢(shì)在于使用簡(jiǎn)單、高彈性高并發(fā),按量按需計(jì)費(fèi)。但是與此同時(shí)也犧牲了部分的兼容性,目前對(duì) cluster-pi、coredns 等機(jī)制支持的還并不完善,只需少許的配置 virtual-kubelet-autoscaler 是可以和 cluster-autoscaler 兼容的。virtual-kubelet-autoscaler 特別適合的場(chǎng)景是大數(shù)據(jù)離線任務(wù)、CI/CD 作業(yè)、突發(fā)型在線負(fù)載等。
最后
serverless autoscaling 已經(jīng)逐漸成為 Kubernetes 彈性伸縮的重要組成部分,當(dāng) serverless autoscaling 兼容性基本補(bǔ)齊的時(shí)候,serverless 使用簡(jiǎn)單、無(wú)需運(yùn)維、成本節(jié)約的特性會(huì)與 Kubernetes 形成完美互補(bǔ),實(shí)現(xiàn) Kubernetes 彈性伸縮的新飛躍。
總結(jié)
以上是生活随笔為你收集整理的Serverless 与容器决战在即?有了弹性伸缩就不一样了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 用户数从 0 到亿,我的 K8s 踩坑血
- 下一篇: 独家解读 etcd 3.4版本 |云原生