天天看點

自動擴縮容 - Autoscaler

本文選自 《Knative 雲原生應用開發指南》

Knative Serving 預設情況下,提供了開箱即用的快速、基于請求的自動擴縮容功能 - Knative Pod Autoscaler(KPA)。下面帶你體驗如何在 Knative 中配置 Autoscaler。

Autoscaler 機制

Knative Serving 為每個 POD 注入 QUEUE 代理容器(queue-proxy),該容器負責向 Autoscaler 報告使用者容器并發名額。Autoscaler 接收到這些名額之後,會根據并發請求數及相應的算法,調整 Deployment 的 POD 數量,進而實作自動擴縮容。

自動擴縮容 - Autoscaler

算法

Autoscaler 基于每個 POD 的平均請求數(并發數)。預設并發數為 100。POD數=并發請求總數/容器并發數

如果服務中并發數設定了10,這時候如果加載了50個并發請求的服務,Autoscaler 就會建立了 5 個 POD(50個并發請求/10=POD)。

Autoscaler實作了兩種操作模式的縮放算法:Stable/穩定模式和Panic/恐慌模式。

穩定模式

在穩定模式下,Autoscaler 調整 Deployment 的大小,以實作每個 POD 所需的平均并發數。 POD 的并發數是根據60秒視窗内接收所有資料請求的平均數來計算得出。

恐慌模式

Autoscaler 計算 60 秒視窗内的平均并發數,系統需要 1 分鐘穩定在所需的并發級别。但是,Autoscaler 也會計算 6 秒的恐慌視窗,如果該視窗達到目标并發的2倍,則會進入恐慌模式。在恐慌模式下,Autoscaler 在更短、更敏感的緊急視窗上工作。一旦緊急情況持續 60 秒後,Autoscaler 将傳回初始的 60 秒穩定視窗。

|
                                  Panic Target--->  +--| 20
                                                    |  |
                                                    | <------Panic Window
                                                    |  |
       Stable Target--->  +-------------------------|--| 10   CONCURRENCY
                          |                         |  |
                          |                      <-----------Stable Window
                          |                         |  |
--------------------------+-------------------------+--+ 0
120                       60                           0
                     TIME           

配置 KPA

通過上面的介紹,我們對 Knative Pod Autoscaler 工作機制有了初步的了解,那麼接下來介紹如何配置 KPA。在 Knative中配置 KPA 資訊,需要修改 k8s 中的 ConfigMap:config-autoscaler,該 ConfigMap 在 knative-serving 命名空間下。檢視 config-autoscaler 使用如下指令:

kubectl -n knative-serving get cm config-autoscaler           

預設的 ConfigMap 如下:

apiVersion: v1
kind: ConfigMap
metadata:
 name: config-autoscaler
 namespace: knative-serving
data:
 container-concurrency-target-percentage: "70"
 container-concurrency-target-default: "100"
 requests-per-second-target-default: "200"
 target-burst-capacity: "200"
 stable-window: "60s"
 panic-window-percentage: "10.0"
 panic-threshold-percentage: "200.0"
 max-scale-up-rate: "1000.0"
 max-scale-down-rate: "2.0"
 enable-scale-to-zero: "true"
 tick-interval: "2s"
 scale-to-zero-grace-period: "30s"           
  • container-concurrency-target-percentage: 容器并發請求數比例。容器實際最大并發數 = 容器最大并發請求數 * 容器并發請求數比例。例如,Revision 設定的容器最大并發請求數為:10,容器并發請求數比例為:70%, 那麼在穩定狀态下,實際容器的最大并發請求數為:7
  • container-concurrency-target-default:容器并發請求預設值。當 Revision 中未設定容器最大并發請求數時,使用該預設值作為容器最大并發請求數
  • requests-per-second-target-default: 每秒請求并發(RPS)預設值。當使用RPS進行度量時,autoscaler 會依據此值進行擴縮容判斷
  • target-burst-capacity:突發請求容量。在突發流量場景下,切換到 Activator 模式進行流量控制。取值範圍為[-1,+∞)。-1表示一直使用 Activator 模式;0表示不使用突發流量功能。
  • stable-window: 穩定視窗期。穩定模式視窗期
  • panic-window-percentage:恐慌視窗比例。通過恐慌視窗比例,計算恐慌視窗期。恐慌視窗期 = 恐慌視窗比例 * 穩定視窗期/100
  • panic-threshold-percentage:恐慌模式比例門檻值。目前并發請求數大于容器最大并發請求數 * 恐慌比例門檻值,并且達到恐慌視窗期,則進入恐慌模式。
  • max-scale-up-rate:最大擴容比例。每次擴容允許的最大速率。目前最大擴容數 = 最大擴容比例 * Ready的Pod數量
  • max-scale-down-rate:最大縮容比例。
  • enable-scale-to-zero:允許縮容至0。
  • tick-interval:擴縮容計算間隔。
  • scale-to-zero-grace-period:縮容至0優雅下線時間。

為 KPA 配置縮容至 0

為了正确配置使 Revision 縮容為0,需要修改 ConfigMap 中的如下參數。

scale-to-zero-grace-period

scale-to-zero-grace-period 表示在縮為0之前,inactive revison 保留的運作時間(最小是30s)。

scale-to-zero-grace-period: 30s           

stable-window

當在 stable mode 模式運作中,autoscaler 在穩定視窗期下平均并發數下的操作

stable-window: 60s           

stable-window 同樣可以配置在 Revision 注釋中

autoscaling.knative.dev/window: 60s           

enable-scale-to-zero

保證 enable-scale-to-zero參數設定為true

Termination period

Termination period(終止時間)是 POD 在最後一個請求完成後關閉的時間。POD 的終止周期等于穩定視窗值和縮放至零寬限期參數的總和。在本例中,Termination period 為 90 秒。

配置并發數

可以使用以下方法配置 Autoscaler 的并發數。

target

target 定義在給定時間(軟限制)需要多少并發請求,是 Knative 中 Autoscaler 的推薦配置。

在 ConfigMap 中預設配置的并發 target 為100

`container-concurrency-target-default: 100`           

這個值可以通過 Revision 中的

autoscaling.knative.dev/target

注釋進行修改:

autoscaling.knative.dev/target: 50           

containerConcurrency

注意:隻有在明确需要限制在給定時間有多少請求到達應用程式時,才應該使用 containerConcurrency (容器并發)。隻有當應用程式需要強制的并發限制時,才建議使用 containerConcurrency。

containerConcurrency 限制在給定時間允許并發請求的數量(硬限制),并在 Revision 模闆中配置。

containerConcurrency: 0 | 1 | 2-N           
  • 1: 将確定一次隻有一個請求由 Revision 給定的容器執行個體處理。
  • 2-N: 請求的并發值限制為2或更多
  • 0: 表示不作限制,有系統自身決定

配置擴縮容邊界(minScale 和 maxScale)

通過 minScale 和 maxScale 可以配置應用程式提供服務的最小和最大Pod數量。通過這兩個參數配置可以控制服務冷啟動或者控制計算成本。

minScale 和 maxScale 可以在 Revision 模闆中按照以下方式進行配置:

spec:
  template:
    metadata:
      autoscaling.knative.dev/minScale: "2"
      autoscaling.knative.dev/maxScale: "10"           

通過在 Revision 模闆中修改這些參數,将會影響到 PodAutoscaler 對象,這也表明在無需修改 Knative Serving 系統配置的情況下,PodAutoscaler 對象是可被修改的。

edit podautoscaler <revision-name>           

注意:這些注釋适用于 Revision 的整個生命周期。即使 Revision 沒有被任何 route 引用,minscale 指定的最小 POD 計數仍将提供。請記住,不可路由的 Revision 可能被垃圾收集掉。

預設情況

如果未設定 minscale 注釋,pods 将縮放為零(如果根據上面提到的 configmap,enable-scale-to-zero 為 false,則縮放為1)。

如果未設定 maxscale 注釋,則建立的 Pod 數量将沒有上限。

下面我們看一下基于 KPA 配置的示例

Knative 0.10.0 版本部署安裝可以參考:

阿裡雲部署 Knative

我們使用官方提供的 autoscale-go 示例來進行示範,示例 service.yaml 如下:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: autoscale-go
  namespace: default
spec:
  template:
    metadata:
      labels:
        app: autoscale-go
      annotations:
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1           

擷取通路網關:

$ kubectl get svc istio-ingressgateway --namespace istio-system --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"
121.199.194.150           

Knative 0.10.0 版本中擷取域名資訊:

$ kubectl get route autoscale-go --output jsonpath="{.status.url}"| awk -F/ '{print $3}'
autoscale-go.default.example.com           

場景1:并發請求示例

如上配置,目前最大并發請求數 10。 我們執行 30s 内保持 50 個并發請求,看一下執行情況:

hey -z 30s -c 50   -host "autoscale-go.default.example.com"   "http://121.199.194.150?sleep=100&prime=10000&bloat=5"           
自動擴縮容 - Autoscaler

結果正如我們所預期的:擴容出來了 5 個 POD。

場景2:擴縮容邊界示例

修改一下 servcie.yaml 配置如下:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: autoscale-go
  namespace: default
spec:
  template:
    metadata:
      labels:
        app: autoscale-go
      annotations:
        autoscaling.knative.dev/target: "10"
        autoscaling.knative.dev/minScale: "1"
        autoscaling.knative.dev/maxScale: "3"        
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1           

目前最大并發請求數 10,minScale 最小保留執行個體數為 1,maxScale 最大擴容執行個體數為 3。

我們依然執行 30s 内保持 50 個并發請求,看一下執行情況:

hey -z 30s -c 50   -host "autoscale-go.default.example.com"   "http://121.199.194.150?sleep=100&prime=10000&bloat=5"           
自動擴縮容 - Autoscaler

結果如我們所預期:最多擴容出來了 3 個POD,并且即使在無通路請求流量的情況下,保持了 1 個運作的 POD。

結論

看了上面的介紹,是不是感覺在 Knative 中配置應用擴縮容是如此簡單。其實 Knative 中除了支援 KPA 之外,也支援K8s HPA。你可以通過如下配置基于 CPU 的 Horizontal POD Autoscaler(HPA):

通過在修訂模闆中添加或修改

autoscaling.knative.dev/class

autoscaling.knative.dev/metric

值作為注釋,可以将Knative 配置為使用基于 CPU 的自動縮放,而不是預設的基于請求的度量。配置如下:

spec:
  template:
    metadata:
      autoscaling.knative.dev/metric: concurrency
      autoscaling.knative.dev/class: hpa.autoscaling.knative.dev           

你可以自由的将 Knative Autoscaling 配置為使用預設的 KPA 或 Horizontal POD Autoscaler(HPA)。

阿裡巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”

繼續閱讀