Serverless Knative Serving弹性扩缩容实践整理
文章目錄
- (一)基礎(chǔ)
- (1)認(rèn)識(shí)
- (2)Knative Serving對(duì)象模型
- (3)knative-serving
- (4)Knative的擴(kuò)縮容流程原理
- (二)彈性擴(kuò)縮容實(shí)踐
- (1)自動(dòng)擴(kuò)縮容類型選擇
- 1. 介紹
- 2.配置示例
- (2)縮容至0和冷啟動(dòng)問題
- (3)Knative Service的彈性伸縮配置
- (4)Knative Service灰度發(fā)布實(shí)踐
- (三)參考命令
- (四)參考
(一)基礎(chǔ)
(1)認(rèn)識(shí)
Knative的服務(wù)管理組件Serving是管理應(yīng)用服務(wù)的理想選擇,它通過自動(dòng)縮容為零和基于HTTP負(fù)載自動(dòng)擴(kuò)展的方式簡(jiǎn)化了部署流程。Knative平臺(tái)可管理應(yīng)用服務(wù)的部署、版本、網(wǎng)絡(luò)、擴(kuò)縮容。
(2)Knative Serving對(duì)象模型
【1】服務(wù)(Service):service.serving.knative.dev資源自動(dòng)管理用戶工作負(fù)載的整個(gè)生命周期。它控制路由和配置對(duì)象的創(chuàng)建,在服務(wù)更新時(shí)確保應(yīng)用有對(duì)應(yīng)的服務(wù)路由、配置和新的修訂版。服務(wù)可以被定義為總是把流量路由到最新的修訂版或特定修訂版。
【2】路由(Route):route.serving.knative.dev資源用于映射一個(gè)網(wǎng)絡(luò)端點(diǎn)到一個(gè)或更多修訂版。你可以用多種方式來管理流量,包括分流和命名路由。
【3】配置(configuration):configuration.serving.knative.dev資源維護(hù)了部署應(yīng)用的最終狀態(tài)。它遵循云原生應(yīng)用12要素原則,提供了代碼和配置分離的機(jī)制。每次修改配置會(huì)創(chuàng)建一個(gè)新的修訂版。
【4】修訂版(Revision):revision.serving.knative.dev資源是在每次變更工作負(fù)載時(shí)生成的代碼和配置的時(shí)間點(diǎn)快照。修訂版是不可變對(duì)象。系統(tǒng)會(huì)保留有用的修訂版本,刪除不再使用的修訂版。修訂版對(duì)應(yīng)的Pod實(shí)例數(shù)量會(huì)根據(jù)流量的大小自動(dòng)進(jìn)行伸縮。
(3)knative-serving
Knative Serving組件在啟動(dòng)時(shí)會(huì)自動(dòng)創(chuàng)建如上所示的一些pod工作負(fù)載,這些pod構(gòu)成了Serving的整體管理能力。(備注:并非所有場(chǎng)景默認(rèn)都是如上組件)
【1】activator(Service):負(fù)責(zé)為不活躍狀態(tài)的修訂版接收并緩存請(qǐng)求,同時(shí)報(bào)告指標(biāo)數(shù)據(jù)給Autoscaler。在Autoscaler擴(kuò)展修訂版之后,它還負(fù)責(zé)將請(qǐng)求重試到修訂版
【2】autoscaler(Service):接收請(qǐng)求指標(biāo)數(shù)據(jù)并調(diào)整需要的Pod 數(shù)量以處理流量負(fù)載。
【3】autoscaler-hpa :接收請(qǐng)求指標(biāo)數(shù)據(jù)并調(diào)整需要的Pod 數(shù)量以處理流量負(fù)載。針對(duì)于 Horizontal Pod Autoscaler (HPA) 擴(kuò)縮容類型實(shí)現(xiàn)。
【4】Controller(Service):協(xié)調(diào)所有公共Knative對(duì)象,自動(dòng)擴(kuò)展CRD。當(dāng)用戶請(qǐng)求一個(gè)Knative Service給Kubernetes API時(shí),Controller將創(chuàng)建對(duì)應(yīng)配置和路由,并將配置轉(zhuǎn)換為revision,同時(shí)將revision轉(zhuǎn)化為Deployment和KPA。
【5】default-domain:默認(rèn)域名設(shè)置。默認(rèn)情況下,路由的完全限定域名是{route}.{namespace}.{default-domain}. Knative Serving 路由example.com用作默認(rèn)域。
【6】domain-mapping:自定義域名設(shè)置
【7】domainmapping-webhook:域名映射攔截處理模塊
【8】net-kourier-controller:Knative Kourier 網(wǎng)關(guān)控制器;
【9】webhook :Webhook(Service):攔截所有Kubernetes API調(diào)用以及所有CRD的插入和更新操作,用來設(shè)置默認(rèn)值,拒絕不一致和無效的對(duì)象,驗(yàn)證和修改Kubernetes API調(diào)用。
(4)Knative的擴(kuò)縮容流程原理
【1】默認(rèn)情況下,創(chuàng)建后的Pod副本在沒有請(qǐng)求后會(huì)變成0,縮容到0。當(dāng)新的請(qǐng)求過來時(shí),首先通過入口網(wǎng)關(guān)轉(zhuǎn)發(fā)給Activator組件,并報(bào)告數(shù)據(jù)給Autoscaler組件。
【2】接著Autoscaler會(huì)創(chuàng)建修訂版的Deployment對(duì)象,構(gòu)建相應(yīng)的Pod副本。
【3】Activator會(huì)將緩存的客戶端請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的Pod副本。Gateway然后會(huì)將新的請(qǐng)求直接轉(zhuǎn)發(fā)給相應(yīng)的Pod副本,不再轉(zhuǎn)發(fā)給Activator。
【4】Autoscaler創(chuàng)建的pod中默認(rèn)都有倆個(gè)容器,一個(gè)是User Container即對(duì)應(yīng)的業(yè)務(wù)服務(wù),一個(gè)是Queue Proxy是系統(tǒng)容器,以Sidecar方式存在,該容器負(fù)責(zé)向Autoscaler報(bào)告用戶容器流量指標(biāo)。Autoscaler接收到這些指標(biāo)之后,會(huì)根據(jù)流量指標(biāo)及相應(yīng)的算法調(diào)整Deployment的Pod副本數(shù)量,從而實(shí)現(xiàn)自動(dòng)擴(kuò)縮容,如果一段周期內(nèi)沒有請(qǐng)求,Autoscaler會(huì)將Pod副本數(shù)設(shè)置為零,回收Pod所占資源。
【5】Autoscaler默認(rèn)基于Pod接收到的并發(fā)請(qǐng)求數(shù)擴(kuò)縮容資源。計(jì)算公式是:Pod數(shù)=并發(fā)請(qǐng)求總數(shù)/Pod并發(fā)請(qǐng)求數(shù)的目標(biāo)值。
(二)彈性擴(kuò)縮容實(shí)踐
(1)自動(dòng)擴(kuò)縮容類型選擇
1. 介紹
Knative Serving 支持 Knative Pod Autoscaler (KPA) 和 Kubernetes 的 Horizontal Pod Autoscaler (HPA) 的實(shí)現(xiàn)。
KPA:Knative Serving 核心的一部分,安裝 Knative Serving 后默認(rèn)啟用。支持縮放到零功能。不支持基于 CPU 的自動(dòng)縮放。
HPA:不是 Knative Serving 核心的一部分,需要單獨(dú)安裝。不支持縮放到零功能。支持基于 CPU 的自動(dòng)縮放。
如果想要支持KPA,需要單獨(dú)安裝,安裝方式如下:
yaml配置文件下載地址:https://github.com/knative/serving/releases,注意保持版本統(tǒng)一
修改自動(dòng)擴(kuò)縮容類型選擇可以有倆種設(shè)置方式,一個(gè)是Global (ConfigMap)全局設(shè)置,一個(gè)是Per Revision特定的修訂版本設(shè)置
2.配置示例
apiVersion: serving.knative.dev/v1 kind: Service metadata:name: helloworld-nodejs spec:template:metadata:labels:app: helloworld-nodejsannotations:autoscaling.knative.dev/class: "hpa.autoscaling.knative.dev"autoscaling.knative.dev/metric: "cpu"autoscaling.knative.dev/target: "75"autoscaling.knative.dev/minScale: "1"autoscaling.knative.dev/maxScale: "10"spec:containers:- image: registry.cn-hangzhou.aliyuncs.com/knative-samples/helloworld-go:160e4dc8resources:requests:cpu: '200m'1:通過autoscaling.knative.dev/class: "hpa.autoscaling.knative.dev"指定HPA彈性插件。
2:通過autoscaling.knative.dev/metric設(shè)置HPA CPU指標(biāo)。
3:通過autoscaling.knative.dev/target設(shè)置HPA CPU指標(biāo)的閾值。
4:通過autoscaling.knative.dev/minScale: "1"設(shè)置彈性策略實(shí)例數(shù)的最小值。
5:通過autoscaling.knative.dev/maxScale: "10"設(shè)置彈性策略實(shí)例數(shù)的最大值。
上面的配置信息是針對(duì)Per Revision構(gòu)建方式。構(gòu)建命令通過kubectl apply 即可
上面的autoscaling.knative.dev/metric屬性設(shè)置了監(jiān)控指標(biāo)類型。指標(biāo)可以是"concurrency", “rps” or “cpu” 。即并發(fā)數(shù)、每秒請(qǐng)求數(shù)、CPU使用率。
默認(rèn)的設(shè)置是Default: “concurrency”
(2)縮容至0和冷啟動(dòng)問題
縮容至0可以被啟用在設(shè)置KnativePodAutoscaler (KPA)類型下,且僅可以設(shè)置為全局配置。縮放到零值控制 Knative 是否允許副本縮小到零(如果設(shè)置為 true),或者如果設(shè)置為 false,則停止在 1 個(gè)副本。
屬性配置鍵為:enable-scale-to-zero。默認(rèn)是true,即支持縮容至0個(gè)pod,設(shè)置為false,會(huì)保留一個(gè)副本
注意:這里著重說明下這個(gè)屬性,這個(gè)屬性是config-autoscaler的ConfigMap,我們可以通過下面命令查看其屬性信息
kubectl -n knative-serving describe cm config-autoscaler
默認(rèn)是true代表可以縮容至0。雖然縮容至0可以有效的節(jié)省服務(wù)器資源的消耗,但是也帶來了一個(gè)很關(guān)鍵的問題,即Serverless中的冷啟動(dòng)問題,就拿自己參與項(xiàng)目為例,一個(gè)應(yīng)用鏡像打包后超過900M,如果縮容至0,那么在空閑后第一批請(qǐng)求過來了冷啟動(dòng)的時(shí)間可能需要至少30s的時(shí)間才能啟動(dòng)鏡像,而這對(duì)于用戶使用無疑是不友好的,所以我們對(duì)于一些核心,啟動(dòng)耗時(shí)的應(yīng)用需要進(jìn)行預(yù)留實(shí)例,保留至少一個(gè)實(shí)例,這樣在新的請(qǐng)求過來可以立馬響應(yīng),對(duì)用戶使用沒有影響。
Tips:除了enable-scale-to-zero方式之外,還可以通過設(shè)置annotations的autoscaling.knative.dev/minScale來限制當(dāng)前服務(wù)至少有一個(gè)負(fù)載存活
如果需要設(shè)置的話,可以將config-autoscaler組件的configMap的enable-scale-to-zero設(shè)置為false
kubectl -n knative-serving edit cm config-autoscalerenable-scale-to-zero屬性值控制Knative修訂版縮容到零或保留1個(gè)副本。scale-to-zero-grace-period屬性值控制的是縮容到零的寬限周期。縮容到零的寬限周期是指系統(tǒng)在刪除最后一個(gè)副本之前等待的時(shí)間上限。默認(rèn)值:30s。
參考配置如下
scale-to-zero-pod-retention-period屬性控制的是縮容到零時(shí)最后一個(gè)Pod的保留期。scale-to-zero-pod-retention-period定義了當(dāng)Autoscaler決定要縮容到零時(shí),最后一個(gè)Pod保留的最小時(shí)長(zhǎng)。該設(shè)置主要針對(duì)那些啟動(dòng)代價(jià)高、流量突發(fā)性高的場(chǎng)景。默認(rèn)值:0s。
apiVersion: serving.knative.dev/v1 kind: Service metadata:name: helloworld-gonamespace: default spec:template:metadata:annotations:autoscaling.knative.dev/scaleToZeroPodRetentionPeriod: "1m5s"spec:containers:- image: gcr.io/knative-samples/helloworld-go(3)Knative Service的彈性伸縮配置
Knative Serving為我們提供了一些擴(kuò)縮容配置項(xiàng),包括副本的初始大小,pod副本最小數(shù)量,最大數(shù)量限制。下面通過簡(jiǎn)單的實(shí)例去分析下這些彈性伸縮配置
【1】準(zhǔn)備測(cè)試服務(wù)配置文件,參考如下
在上述配置中,revision中配置了修訂版的彈性伸縮策略。各個(gè)屬性代表的意義如下。
·autoscaling.knative.dev/class:表示Autoscaler的實(shí)現(xiàn)方式,這個(gè)屬
性的可選值有kpa.autoscaling.knative.dev或hpa.autoscaling.knative.dev。 KPA支持縮容到零,HPA支持基于CPU的擴(kuò)展機(jī)制。
·autoscaling.knative.dev/metric:度量指標(biāo)默認(rèn)為并發(fā)數(shù),該屬性
還可以根據(jù)業(yè)務(wù)情況選擇每秒請(qǐng)求數(shù)或CPU使用率。
·autoscaling.knative.dev/target:自動(dòng)縮放的目標(biāo)值是Autoscaler維
護(hù)應(yīng)用的每個(gè)副本度量指標(biāo)的目標(biāo)值。
·autoscaling.knative.dev/minScale:表示每個(gè)修訂版副本需要保留
的最小數(shù)量。在任何時(shí)間點(diǎn),副本不會(huì)少于這個(gè)數(shù)量。通過該設(shè)置,
我們可以有效地減少服務(wù)的冷啟動(dòng)時(shí)間。
·autoscaling.knative.dev/maxScale:表示每個(gè)修訂版副本所能達(dá)到
的最大數(shù)量。在任何時(shí)間點(diǎn),副本都不會(huì)超過指定的最大值,從而避
免資源被過度使用。
上面的配置僅使用了一部分,具體的可以參考官方文檔:
https://knative.dev/v1.0-docs/serving/autoscaling/scale-bounds/
【2】創(chuàng)建應(yīng)用服務(wù)
kubectl apply -f service.yaml可以通過rancher看到已經(jīng)創(chuàng)建了pod,也可以通過下面的命令查看
【3】因?yàn)樵O(shè)置了 autoscaling.knative.dev/minScale: “1” ,其中 minScale表示最小保留實(shí)例數(shù)為1,通過上圖可以觀察到存在一個(gè)pod
【4】Autoscaler基于每個(gè)Pod的平均請(qǐng)求數(shù)(并發(fā)數(shù))進(jìn)行自動(dòng)擴(kuò)縮容,默認(rèn)并發(fā)數(shù)為100。Pod數(shù)=并發(fā)請(qǐng)求總數(shù)/容器并發(fā)數(shù)。如果服務(wù)中并發(fā)數(shù)設(shè)置為10,并且加載了50個(gè)并發(fā)請(qǐng)求的服務(wù),則Autoscaler就會(huì)創(chuàng)建5個(gè)Pod。
【5】下面通過hey壓測(cè)工具進(jìn)行測(cè)試
備注:下面的壓測(cè)工具使用的是hey,為了方便建議這里直接使用二進(jìn)制包的方式
二進(jìn)制包地址:
https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
查看該pod分配的域名地址
kubectl get ksvc --namespace default
執(zhí)行壓力測(cè)試,發(fā)起50個(gè)并發(fā)請(qǐng)求,持續(xù)30秒對(duì)hellowrold-go服務(wù)進(jìn)行壓測(cè)。
執(zhí)行壓測(cè)結(jié)束后,查看工作負(fù)載情況,執(zhí)行命令
kubectl get pod -l serving.knative.dev/service=helloworld-go
正常情況下當(dāng)發(fā)起的并發(fā)請(qǐng)求數(shù)是50個(gè),服務(wù)自動(dòng)縮放的目標(biāo)值是10,按照“副本數(shù)=并發(fā)數(shù)/目標(biāo)值”算法,那么pod數(shù)量就是5。但是在某些情況下,由于Knative Serving還有一個(gè)控制參數(shù)叫目標(biāo)使用率,一旦并發(fā)數(shù)達(dá)到預(yù)設(shè)目標(biāo)的70%(默認(rèn)值),Autoscaler就會(huì)繼續(xù)擴(kuò)容。引入目標(biāo)使用率的主要目的是在擴(kuò)容時(shí)減小由Pod啟動(dòng)時(shí)間帶來的延遲,使負(fù)載到達(dá)前就將Pod實(shí)例啟動(dòng)起來。
【6】在等待幾分鐘后,再次查詢就會(huì)發(fā)現(xiàn)pod數(shù)有降成1了,僅保留一個(gè)實(shí)例
(4)Knative Service灰度發(fā)布實(shí)踐
灰度部署是指逐漸將生產(chǎn)環(huán)境流量從老版本切換到新版本。通常流量是按比例分配的。例如 90% 的請(qǐng)求流向老版本,10% 的請(qǐng)求流向新版本。然后沒有發(fā)現(xiàn)問題,就逐步擴(kuò)大新版本上的流量,減少老版本上的流量。
除了切流量外,對(duì)于多租戶的平臺(tái),例如云計(jì)算平臺(tái),灰度部署也可以將一些新的版本先部署到一些用戶上,如果沒有問題,擴(kuò)大部署,直到全部用戶。一般的策略是,從內(nèi)部用戶開始,然后是一般用戶,最后是大客戶。
這個(gè)技術(shù)大多數(shù)用于缺少足夠測(cè)試,或者缺少可靠測(cè)試,或者對(duì)新版本的穩(wěn)定性缺乏信心的情況下。
把一部分用戶切到新版上來,然后看一下有沒有問題。如果沒有問題就繼續(xù)擴(kuò)大升級(jí),直到全部升級(jí)完成。
這里準(zhǔn)備實(shí)例,當(dāng)前所使用的是一個(gè)單體化項(xiàng)目,演示的場(chǎng)景如下:
【1】構(gòu)建倆個(gè)版本的應(yīng)用,這倆個(gè)版本一個(gè)作為舊版本,一個(gè)作為升級(jí)后的版本。通過不斷變更的流量比例來實(shí)現(xiàn)應(yīng)用服務(wù)灰度發(fā)布,當(dāng)前設(shè)置倆個(gè)revision各占50%的流量,即切換一半用戶訪問至新版本。
【2】倆個(gè)版本應(yīng)用的鏡像通過docker push推送到私庫(kù)中:
【3】構(gòu)建工作負(fù)載配置文件如下
【5】通過瀏覽器進(jìn)行測(cè)試,由于是在內(nèi)網(wǎng)自動(dòng)分配的域名需修改本地的hosts文件
192.168.XXX.XXX tag-header.serving-test.127.0.0.1.nip.io
【6】Knative默認(rèn)使用的是kourier網(wǎng)關(guān),現(xiàn)在需要看下該網(wǎng)關(guān)暴露的端口入口信息,當(dāng)前我們使用30218端口測(cè)試
kubectl --namespace kourier-system get service kourier【7】測(cè)試tag-header.serving-test,觀察下面可以看到多次訪問時(shí)返回?cái)?shù)據(jù)不同
測(cè)試地址:http://tag-header.serving-test.127.0.0.1.nip.io:30218/
通過多次訪問該地址可以發(fā)現(xiàn)結(jié)果不同,對(duì)應(yīng)的流量被劃分到不同的應(yīng)用服務(wù)中去了
(三)參考命令
【1】根據(jù)描述文件創(chuàng)建應(yīng)用
kubectl apply -f service.yaml【2】查看 Knative 工作負(fù)載
# 查詢命名空間serving-test下的工作負(fù)載 kubectl get ksvc --namespace serving-test【3】查看應(yīng)用詳細(xì)信息
# 查看knative-serving命名空間下configMap名稱config-autoscaler的詳細(xì)信息 kubectl -n knative-serving describe cm config-autoscaler# 查詢命名空間knative-serving下pod名稱為activator-645854dc69-b9ds9的詳細(xì)信息 kubectl describe pod activator-645854dc69-b9ds9 --namespace knative-serving【4】編輯配置
# 編輯knative-serving命名空間下configMap名稱config-autoscaler的詳細(xì)信息 kubectl -n knative-serving edit cm config-autoscaler【5】查詢pod信息
kubectl get pod -l serving.knative.dev/service=helloworld-go【6】查看pod日志
kubectl logs輸出pod中一個(gè)容器的日志。輸出pod中一個(gè)容器的日志。如果pod只包含一個(gè)容器則可以省略容器名。
kubectl logs [-f] [-p] POD [-c CONTAINER]# 查看knative-serving命名空間中pod名稱autoscaler-78cd799dcc-zwk9l的日志信息 kubectl logs -f autoscaler-78cd799dcc-zwk9l --namespace knative-serving(四)參考
【1】基于流量請(qǐng)求數(shù)實(shí)現(xiàn)服務(wù)自動(dòng)擴(kuò)縮容
https://knative.club/02serving/zi-dong-kuo-suo-rong-kpa-pei-zhi/ji-yu-liu-liang-qing-qiu-shu-shi-xian-fu-wu-zi-dong-kuo-suo-rong
【2】《Knative實(shí)戰(zhàn):基于Kubernetes的無服務(wù)器架構(gòu)實(shí)踐》Knative的服務(wù)管理組件Serving
【3】詳解 Knative Serving
https://www.jianshu.com/p/10b5b68e8cb1
【4】knative官方文檔彈性伸縮模塊
https://knative.dev/v1.0-docs/serving/autoscaling/
【5】阿里云開發(fā)者社區(qū)knative Serving
https://www.aliyun.com/search?k=Knative%20Serving&page=1&scm=
總結(jié)
以上是生活随笔為你收集整理的Serverless Knative Serving弹性扩缩容实践整理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POSIX 标准
- 下一篇: 度度熊学队列(双端队列练习)