基於Kubernetes和Istio的Serverless框架Knative解析之Autoscaler
- 2019 年 12 月 6 日
- 筆記

我們都是知道Kubernetes中個資源對象叫 autoscaler,該對象在serverless架構中更是不可或缺,有了它可以負責應用的自動水平伸縮,用戶再也不用關心示例的個數和資源消耗,下文是來自阿里巴巴UC事業群基礎研發部的陳有坤同學對Knative的解析之autoscaler部分,還有大量的解析等待放出,起關注本公眾號的後續內容。
首先對Knative做個基礎介紹。Knative是一款基於Kubernetes的平台,用來構建、部署和管理現代serverless應用的框架。該框架試圖將雲原生應用開發的以下三個領域的最佳實踐結合起來:
- 構建容器(和函數)
- 為工作負載提供服務(和動態擴展)
- 事件
Knative是由谷歌與Pivotal、IBM、Red Hat 和SAP緊密協作開發的。
Knative構建在Kubernetes和Istio之上,它的設計考慮到了多種角色通過該框架進行交互,包括開發人員、運維人員和平台提供者。

Knative所涉及的角色(圖片來源於Knative GitHub倉庫)
Knative致力於提供可重用的「通用模式和最佳實踐組合」實現,目前可用的組件包括:
- Build:從源到容器的構建編排;
- Eventing:管理和交付事件;
- Serving:請求驅動的計算,可以縮放到零。
以上內容引用自: InfoQ | 谷歌發佈Knative:用於構建、部署和管理Serverless工作負載的Kubernetes框架:http://www.infoq.com/cn/news/2018/07/knative-kubernetes-serverless
以上是對Knative的基本介紹,關於Knative的更多信息大家可以關注其GitHub:https://github.com/knative
下面首先解析的是Serving中的Autoscaling組件,該組件的功能是根據網絡流量來自動伸縮應用實例的個數。
Knative是如何做伸縮容的?
處理伸縮容問題,首先要解決的問題是根據什麼指標判斷伸縮容?cpu、內存、請求數?這裡knative使用的是請求數。
其次是伸縮多少的問題。
Knative的伸縮是依賴修改deployment的replica數實現的。
如何採集請求數?
啟動revision的pod時,也會啟動一個autoscaler(一個knative revision只啟動一個autoscaler),autoscaler自己本身也會scale到0,用於接收請求數統計和處理伸縮容。
業務pod中,會注入queue-proxy sidecar,用於接收請求,在這裡會統計並發數,每秒向autoscaler彙報,接收到的請求會轉發給業務container。
註:單租戶模式下一個revision啟動一個autoscaler,多租戶共用一個autoscaler
計算需要pod的個數?
autoscaler接收到並發統計的時候,會根據算法計算需要的pod個數。
算法中有兩種模式,分別是panic和stable模式,一個是短時間,一個是長時間,為了解決短時間內請求突增的場景,需要快速擴容。
文檔中描述的算法是,默認的target concurrency是1,如果一個revision 35QPS,每個請求花費0.25秒,Knative Serving 覺得需要 9 個 pod。
ceil(35 * .25) = ceil(8.75) = 9
Stable Mode(穩定模式)
在穩定模式下,Autoscaler 根據每個pod期望的並發來調整Deployment的副本個數。根據每個pod在60秒窗口內的平均並發來計算,而不是根據現有副本個數計算,因為pod的數量增加和pod變為可服務和提供指標數據有一定時間間隔。
Panic Mode (恐慌模式)
Panic時間窗口默認是6秒,如果在6秒內達到2倍期望的並發,則轉換到恐慌模式下。在恐慌模式下,Autoscaler根據這6秒的時間窗口計算,這樣更能及時的響應突發的流量請求。每2秒調整Deployment的副本數達到想要的pod個數(或者最大10倍當前pod的數量),為了避免pod數量頻繁變動,在恐慌模式下只能增加,不會減少。60秒後會恢復回穩定模式。
autoscaler單租戶圖

上圖基於 https://github.com/knative/serving/blob/master/docs/scaling/DEVELOPMENT.md 繪製。
模式
const ( // 每個pod實例同時只處理一個請求 RevisionRequestConcurrencyModelSingle RevisionRequestConcurrencyModelType = "Single" // 每個pod實例同時處理多個請求 RevisionRequestConcurrencyModelMulti RevisionRequestConcurrencyModelType = "Multi" )
配置
apiVersion: v1 kind: ConfigMap metadata: name: config-autoscaler namespace: knative-serving data: # Static parameters: # 期望每個pod並發請求數 multi-concurrency-target: "1.0" # 如果是單個並發,值要接近1.0 single-concurrency-target: "0.9" # stable窗口時間,計算平均並發會用到。如果進入panic模式後,經過stable窗口時間也會恢復stable stable-window: "60s" # 如果平均並發在panic窗口時間內達到2倍目標並發,autoscaler進入panic模式。 # 在panic模式下,自動伸縮按在panic窗口時間的平均並發來操作。 panic-window: "6s" # 最大增長比例,每次調整會根據並發計算增長比例,最大增長不超過這個值 max-scale-up-rate: "10" # 計算並發值的參數,每一段時間得到最大並發,作為一個bucket,最後彙報的時候, # 平均並發 = 各個bucket最大並發之和 / 總bucket數,彙報間隔是1秒(hard coded) concurrency-quantum-of-time: "100ms" # 是否開啟縮容到0 enable-scale-to-zero: "true" # 實驗性:開啟垂直擴容 # Requires a VPA installation (e.g. ./third_party/vpa/install-vpa.sh) enable-vertical-pod-autoscaling: "false" # 如果開啟了enable-vertical-pod-autoscaling,這個值就會替代multi-concurrency-target, # 如果成熟了後期會變成默認值 vpa-multi-concurrency-target: "10.0" # 多長時間調整一次 tick-interval: "2s" # Dynamic parameters (take effect when config map is updated): # 空閑多長時間縮容到0 scale-to-zero-threshold: "5m"
社區網址:http://www.servicemesher.com