本文選自 《Knative 雲原生應用開發指南》 。
Autoscaler 機制
Knative Serving 為每個 POD 注入 QUEUE 代理容器(queue-proxy),該容器負責向 Autoscaler 報告使用者容器并發名額。Autoscaler 接收到這些名額之後,會根據并發請求數及相應的算法,調整 Deployment 的 POD 數量,進而實作自動擴縮容。
算法
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"
結果正如我們所預期的:擴容出來了 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"
結果如我們所預期:最多擴容出來了 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 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”