做者 | 阿里雲容器技術專家 莫源 架構
本文整理自莫源於 8 月 31 日 K8s & cloudnative meetup 深圳場的演講內容。關注「阿里巴巴雲原生」公衆號,回覆關鍵詞「資料」, 便可得到 2019 整年 meetup 活動 PPT 合集及 K8s 最全知識圖譜。併發
導讀:Serverless 和 Autoscaling 是近些年來廣大開發者很是關心的內容。有人說 Serverless 是容器 2.0,終有一天容器會和 Serverless 進行一場決戰,分出勝負。實際上,容器和 Serverless 是能夠共存而且互補的,特別是在 Autoscaling 相關的場景下,Serverless 能夠與容器完美兼容,彌補容器場景在使用簡單、速度、成本的缺欠,在本文中將會爲你們介紹容器在彈性場景下的原理、方案與挑戰,以及 Serverless 是如何幫助容器解決這些問題的。less
當咱們在談論"彈性伸縮"的時候,咱們在談論什麼?"彈性伸縮"對於團隊中不一樣的角色有不一樣的意義,而這正是彈性伸縮的魅力所在。運維
這張圖是闡述彈性伸縮問題時常常引用的一張圖,表示的是集羣的實際資源容量和應用所需容量之間的關係。高併發
首先,咱們先看左側第一塊黃色柵格的區域,這個區域表示集羣的容量沒法知足業務的容量所需,在實際的場景中,一般會伴隨出現因爲資源不足而沒法調度的 Pod 等現象。學習
中間的柵格區域,集羣的容量遠高於實際資源所需的容量,此時會出現資源的浪費,實際的表現一般是節點的負載分配不均,部分節點上面無調度負載,而另一些節點的負載相對較高。大數據
右側柵格區域表示的是激增的峯值容量,咱們能夠看到,到達峯值前的曲率是很是陡峭的,這種場景一般是因爲流量激增、大批量任務等很是規容量規劃內的場景,激增的峯值流量給運維同窗的反應時間很是短,一旦處理不當就有可能引起事故。阿里雲
彈性伸縮對於不一樣角色的人員,有着不一樣的意義:設計
彈性伸縮有多種不一樣的組件和方案,選擇適合本身業務需求的方案是落地執行前的第一步。3d
Kubernetes 彈性伸縮的組件能夠從兩個維度進行解讀:一個是伸縮方向,一個是伸縮對象。
從伸縮方向上,分爲橫向與縱向。從伸縮對象上,分爲節點與 Pod。那麼將這個象限進行展開,就變成以下 3 類組件:
其中 HPA 與 Cluster-Autoscaler 是開發者最常組合使用的彈性伸縮組件。HPA 負責容器的水平伸縮,Cluster-Autoscaler 負責節點的水平伸縮。不少的開發者會產生這樣的疑問:爲何彈性伸縮一個功能須要細化成這麼多組件分開處理,難道不能夠直接設置一個閾值,就實現集羣的自動水位管理嗎?
瞭解 Kubernetes 的調度方式能夠幫助開發者更好的理解 Kubernetes 彈性伸縮的設計哲學。在 Kubernetes 中,調度的最小單元是一個 Pod,Pod 會根據調度策略被調度到知足條件的節點上,這些策略包括資源的匹配關係、親和性與反親和性等等,其中資源的匹配關係的計算是調度中的核心要素。
一般和資源相關的有以下四個概念:
在瞭解這四個基本概念和使用場景以後,咱們再來看下 Kubernetes 彈性伸縮的三大難題:
在 Kubernetes 中是經過 Request
和 Limit
的方式進行設置,Request
表示資源的申請值,Limit
表示資源的限制值。既然 Request
和 Limit
纔是容量規劃的對等概念,那麼這就表明着資源的實際計算規則要根據 Request
和 Limit
才更加準確。而對於每一個節點預留資源閾值而言,頗有可能會形成小節點的預留沒法知足調度,大節點的預留又調度不完的場景。
假設咱們的集羣中存在 4C8G 的機器與 16C32G 兩種不一樣規格的機器,對於 10% 的資源預留而言,這兩種規格是所表明的意義是徹底不一樣的。特別是在縮容的場景下,一般爲了保證縮容後的集羣不處在震盪狀態,咱們會一個節點一個節點來縮容節點,那麼如何根據百分比來判斷當前節點是處在縮容狀態就尤其重要。此時若是大規格機器有較低的利用率被判斷縮容,那麼頗有可能會形成節點縮容後,容器從新調度後的爭搶飢餓。若是添加判斷條件,優先縮容小配置的節點,則有可能形成縮容後資源的大量冗餘,最終集羣中可能會只剩下全部的巨石
節點。
若是沒有設置 Request
與 Limit
,而集羣的總體資源利用率很高,這意味着什麼?這表示全部的 Pod 都在被以真實負載爲單元進行調度,相互之間存在很是嚴重的爭搶,並且簡單的加入節點也絲毫沒法解決問題,由於對於一個已調度的 Pod 而言,除了手動調度與驅逐,沒有任何方式能夠將這個 Pod 從高負載的節點中移走。那若是咱們設置了 Request
與 Limit
而節點的資源利用率又很是高的時候說明了什麼呢?很惋惜這在大部分的場景下都是不可能的,由於不一樣的應用不一樣的負載在不一樣的時刻資源的利用率也會有所差別,大機率的狀況是集羣尚未觸發設置的閾值就已經沒法調度 Pod 了。
在瞭解了 Kubernetes 彈性伸縮的三大問題後,咱們再來看下 Kubernetes 的解決辦法是什麼?
Kubernetes 的設計理念是將彈性伸縮分紅調度層伸縮和資源層伸縮。調度層負責根據指標、閾值伸縮出調度單元,而資源層伸縮負責知足調度單元的資源需求。
在調度層一般是經過 HPA 的方式進行 Pod 的水平伸縮,HPA 的使用方式和咱們傳統意義上理解的彈性伸縮是很是接近和相似的,經過設置判斷的指標、判斷的閾值來進行水平伸縮。
在資源層目前主流的方案是經過 cluster-autoscaler 進行節點的水平伸縮。當出現 Pod 因爲資源不足形成沒法調度時,cluster-autoscaler 會嘗試從配置伸縮組中,選擇一個能夠知足調度需求的組,並自動向組內加入實例,當實例啓動後註冊到 Kubernetes 後,kube-scheduler 會從新觸發 Pod 的調度,將以前沒法調度的 Pod 調度到新生成的節點上,從而完成全鏈路的擴容。
一樣在縮容時,調度層會現根據資源的利用率與設置的閾值比較,實現 Pod 水平的縮容。當節點上 Pod 的調度資源下降到資源層縮容閾值的時候,此時 Cluster-Autoscaler 會進行低調度百分比的節點的排水,排水完成後會進行節點的縮容,完成整個鏈路的收縮。
這張圖是一個很是經典的彈性伸縮的案例,能夠表明大多數的在線業務的場景。應用的初始架構是一個 Deployment,下面有兩個 Pod,這個應用的接入層是通 過Ingress Controller 的方式進行對外暴露的,咱們設置應用的伸縮策略爲:單個 Pod 的 QPS 到達 100,則進行擴容,最小爲 2 個 Pod,最大爲 10 個 Pod。
HPA controller 會不斷輪訓 alibaba-cloud-metrics-adapter,來獲取 Ingress Gateway 當前路由的 QPS 指標。當 Ingress Gateway 的流量到達 QPS 閾值時,HPA controller 會觸發 Deployment 的 Pod 數目變化;當 Pod 的申請容量超過集羣的總量後,cluster-autoscaler 會選擇合適的伸縮組,彈出相應的 Node,承載以前未調度的 Pod。
這樣一個經典的彈性伸縮案例就解析完畢了,那麼在實際的開發過程當中,會遇到哪些問題呢?
首先是擴容時延的問題,社區標準模式是經過建立、釋放 ECS 的方式,擴容的時延在 2min-2.5min 左右,而阿里雲獨立的極速模式是經過建立、停機、啓動的方式進行實現,停機時只收取存儲的費用,不收取計算的費用。能夠經過很是低廉的價格得到 50% 以上的彈性效率。
此外複雜度也是 cluster-autoscaler 繞不過的問題,想要用好 cluster-autoscaler,須要深刻的瞭解 cluster-autoscaler 的一些內部機制,不然極有可能形成沒法彈出或者沒法縮容的場景。
對於大多數的開發者而言,cluster-autoscaler 的工做原理是黑盒的,並且 cluster-autoscaler 目前最好的問題排查方式依然是查看日誌。一旦 cluster-autoscaler 出現運行異常後者因爲開發者配置錯誤致使沒法如預期的伸縮,那麼 80% 以上的開發者是很難本身進行糾錯的。
阿里雲容器服務團隊開發了一款 kubectl plugin,能夠提供 cluster-autoscaler 更深層次的可觀測性,能夠查看當前 cluster-autoscaler 所在的伸縮階段以及自動彈性伸縮糾錯等能力。
雖然目前遇到的幾個核心的問題,都不是壓死駱駝的最後一棵稻草。可是咱們一直在思考,是否有其餘的方式可讓彈性伸縮使用起來更簡單、更高效?
資源層伸縮的核心問題在於學習成本較高、排錯困難、時效性差。當回過頭來看 Serverless 的時候,咱們能夠發現這些問題剛好是 Serverless 的特色與優點,那麼是否有辦法讓 Serverless 成爲 Kubernetes 資源層的彈性方案呢?
阿里雲容器服務團隊開發了 virtual-kubelet-autoscaler,一個在 Kubernetes 中實現 serverless autoscaling 的組件。
當出現了沒法調度的 Pod 的時候,virtual-kubelet 負責承載真實的負載,能夠理解爲一個虛擬節點,擁有無限大的 capacity。當 Pod 調度到 virtual-kubelet 上時,會將 Pod 經過輕量級實例 ECI 進行啓動。目前 ECI 的啓動時間在 30s 以內,程序從調度開始到運行通常會在 1 分鐘內拉起。
與 cluster-autoscaler 相似,virtual-kubelet-autoscaler 也須要使用模擬調度的機制來判斷 Pod 是否能夠被真實處理和承載,可是相比 cluster-autoscaler 而言,存在以下差別:
virtual-kubelet-autoscaler 並非用來替代 cluster-autoscaler 的,virtual-kubelet-autoscaler 的優點在於使用簡單、高彈性高併發,按量按需計費。可是與此同時也犧牲了部分的兼容性,目前對 cluster-pi、coredns 等機制支持的還並不完善,只需少量的配置 virtual-kubelet-autoscaler 是能夠和 cluster-autoscaler 兼容的。virtual-kubelet-autoscaler 特別適合的場景是大數據離線任務、CI/CD 做業、突發型在線負載等。
serverless autoscaling 已經逐漸成爲 Kubernetes 彈性伸縮的重要組成部分,當 serverless autoscaling 兼容性基本補齊的時候,serverless 使用簡單、無需運維、成本節約的特性會與 Kubernetes 造成完美互補,實現 Kubernetes 彈性伸縮的新飛躍。