導讀
作為 Severless Framework 就離不開按需配置設定資源的能力,Knative 提供了基于流量的自動擴縮容能力,可以根據應用的請求量在高峰時期自動擴容執行個體數,當請求量減少以後自動縮容執行個體數,做到自動化的幫助您節省成本。此外 Knative 還提供了基于流量的灰階釋出能力,可以根據流量百分比進行灰階釋出。本文會從以下 4 個方面展開介紹:
- ASK Knative 中流量請求機制
- 基于流量的灰階釋出
- 彈性自動擴縮容
- 示例示範
在介紹Knative 灰階釋出和自動彈性前,我們先來看一下 ASK Knative 中流量請求機制。
ASK Knative 流量請求機制
在 ASK Knative 中,流量首先通過SLB網關,然後根據轉發規則,将請求轉發到對應服務的POD上,這裡轉發規則是通過Knative Ingress Controlller建立,該 controller 通過 Route 中設定的規則,最終轉換成 SLB 規則。

再談 Knative 應用生命周期
Knative Service 是直接面向開發者操作的資源對象,它直接負責對Route和Configuration的管控,一個Service 分别對應一個Route和一個Configuration
Service
每次 Service 變化如果需要建立新的 Workload 就更新 Configuration,然後每次 Configuration 更更新都會建立一個唯一的 Revision。Configuration 可以認為是版本控制器,負責管理多個Revision版本

Route
Route 主要負責 Knative 的流量管理,控制流量分發到不同到Revision, 并且支援按照百分比進行流量分發。這裡我們可以通過在Traffic中對不同的Revison 設定不同對流量比例即可控制流量分發。

Revision
Revision. 一個Revision可以認為是一個Configuration的快照。通過Revision可以實作曆史版本追蹤,以及灰階釋出的過程中進行復原等功能。

那麼接下來我們看一下基于流量的灰階釋出我們可以怎樣做。
假設一開始我們建立了V1版本的Revison, 這時候如果有新的版本變更,那麼我們隻需要更新Service 中的Configuration, 就會建立出V2版本,然後我們可以通過Route對V1、V2設定不同對流量比例,這裡v1是70%, v2是30%, 那麼流量就會分别按照7:3的比例分發到這兩個版本上。一旦新到V2版本驗證沒有問題,那麼我們接下來就可以通過調整比例繼續灰階,直到新版本V2 100%。在這個灰階到過程中,一旦發現新版本有異常,可以通過調整比例進行復原操作。
除此以外,我們可以在Route到Traffic 中對Revison打Tag, 打完Tag的Revison, 我們可以直接通過Url進行單獨的版本測試,對這個版本對調試不會影響正常對流量通路。

自動彈性
接下來我們聊一下自動彈性。作為 Severless Framework 就離不開按需配置設定資源的能力,Knative 提供了基于流量的自動擴縮容KPA能力,以及基于CPU和Memory的HPA彈性能力,除此以外,Knative 提供了彈性的擴充能力,我們可以基于不同的名額自定義彈性功能。
- Knative Pod 自動擴縮容 (KPA)
- Pod 水準自動擴縮容 (HPA)
- 支援定時 + HPA的自動擴縮容政策
- 事件網關(基于流量請求的精準彈性)
- 擴充自定義擴縮容插件
KPA
Knative Serving 中預設使用KPA。

上圖展示了 Knative Autoscaler 的工作機制,Route 負責接入流量,Autoscaler 負責做彈性伸縮。當沒有業務請求的時候會縮容到零,縮容到零後 Route 進來的請求會轉到 Activator 上。當第一個請求進來之後 Activator 會保持住 http 連結,然後通知 Autoscaler 去做擴容。Autoscaler 把第一個 pod 擴容完成以後 Activator 就把流量轉發到 Pod ,進而做到了縮容到零也不會損失流量的目的。
當後續有流量進來之後,流量會直接Route到Pod上,這時候Autoscaler會直接采集Pod中的名額,根據名額進行1-N的擴縮容操作。
HPA
基于CPU、Memory的自動擴縮容-HPA

利用 Horizontal Pod Autoscaling,kubernetes 能夠根據監測到的 CPU 、Memory使用率 通過 修改deployment 中 pod 的數量,進行擴容。在Knative 中內建了HPA的能力,通過autoscaling class可以選擇HPA的能力。
定時與HPA融合
支援定時+HPA的自動擴縮容:
- 提前規劃容量進行資源預熱
- 與CPU、Memory彈性名額相結合

事件網關
基于流量請求的精準彈性:
- 基于請求數自動彈性
- 支援1對1任務分發

自定義擴縮容插件
Knative 中提供了靈活的擴縮容插件機制, 開發者可以通過設定`autoscaling.knative.dev/class`來指定所使用的具體插件。自定義擴縮容插件隻需要實作下面兩個關鍵能力即可:
- 采集名額
- 調整Pod執行個體數

這裡我們分别示範一下基于流量灰階釋出和自動擴縮容的功能。
灰階流量釋出
我們以 helloworld 的服務為例,分别執行如下操作:
- 建立 helloworld 服務
- 更新服務
- 灰階釋出
- 登入 容器服務管理控制台 。
- 在叢集清單頁面中,單擊目标叢集名稱或者目标叢集右側操作列下的詳情。
- 在叢集管理頁左側導航欄中,選擇應用 > Knative。
- 在服務管理頁簽右上角,單擊建立服務。
- 設定叢集、命名空間、服務名稱,選擇所要使用的鏡像和鏡像版本等配置資訊。這裡我們建立 helloworld-go 服務。

- 單擊建立。建立完成後,您可以在服務管理頁簽的清單中,點選helloworld-go看到新建立的服務。

此時我們通路服務:
$ curl -H "host: helloworld-go.default.example.com" http://39.106.199.35
Hello World!
點選【建立修訂版本】,這裡我們設定新版本環境變量為:TARGET=Knative

點選下一步,我們可以設定新版本的流量比例,這裡我們設定新版本流量為0,點選建立。

在服務詳情中,可以看到新的版本已經建立完成,如圖:

由于新版本流量為0,是以目前通路helloworld-go 服務的話,還是請求到原來的版本中。
$ curl -H "host: helloworld-go.default.example.com" http://39.106.199.35
Hello World!
接下來我們開始灰階流量釋出,點選【設定流量比例】,将新、舊版本各設定為50%。

在服務詳情中,可以看到新、舊的版本已經建立完成,如圖:

由于新、舊版本流量各為50%,是以目前通路helloworld-go 服務的話,基本是50%進行流量配置設定。

我們通過調整流量比例繼續灰階,直到新版本100%,完成灰階釋出。

在這個過程中,如何發現新版本有問題,可以随時通過調整流量比例的方式進行復原操作。
基于流量的自動擴縮容
我們模拟并發場景,并發50,持續30s。使用hey工具(hey壓測工具的詳細介紹請參見
hey)
hey -z 30s -c 50 -host "helloworld-go.default.example.com" "http://39.106.199.35"
結果如下:
$ kubectl get po
helloworld-go-g2qfr-deployment-5f557f97cc-76mjb 2/2 Running 0 38s
helloworld-go-g2qfr-deployment-5f557f97cc-7j797 2/2 Running 0 34s
helloworld-go-g2qfr-deployment-5f557f97cc-fh4nl 2/2 Running 0 2m4s
helloworld-go-g2qfr-deployment-5f557f97cc-kdqjx 2/2 Running 0 38s
helloworld-go-g2qfr-deployment-5f557f97cc-kmxsz 2/2 Running 0 26s
helloworld-go-g2qfr-deployment-5f557f97cc-p24s8 2/2 Running 0 2m48s
helloworld-go-g2qfr-deployment-5f557f97cc-wq89q 2/2 Running 0 36s
helloworld-go-g2qfr-deployment-5f557f97cc-zfhf6 2/2 Running 0 38s
helloworld-go-g2qfr-deployment-5f557f97cc-xvdf6 2/2 Running 0 38s
helloworld-go-g2qfr-deployment-5f557f97cc-aeaf8 2/2 Running 0 37s
helloworld-go-g2qfr-deployment-5f557f97cc-dfdsa 2/2 Running 0 46s
當然,我們也可以在日志服務中配置檢視
Pod擴縮容趨勢:

總結
本文我們介紹了基于流量的灰階釋出以及自動彈性政策,并分别進行了示例示範。歡迎有興趣同學關注 Knative 釘釘交流群。
