本文主要講解 Knative Serving擴(kuò)縮容系統(tǒng)的設(shè)計(jì)原理及實(shí)現(xiàn)細(xì)節(jié),主要從以下三個(gè)方面進(jìn)行講解:
- Knative Serving 擴(kuò)縮容系統(tǒng)的組件;
- 涉及的API;
- 擴(kuò)縮容和冷啟動(dòng)時(shí)的 控制流和數(shù)據(jù)流的一些細(xì)節(jié);
組件
Knative Serving 是 Knative 系統(tǒng)的核心赘方,而理解 Knative Serving 系統(tǒng)內(nèi)的組件能更容易了理解 Knative Serving 系統(tǒng)的實(shí)現(xiàn):
了解其中的控制流和數(shù)據(jù)流的走向,了解其在擴(kuò)縮容過(guò)程中的作用弱左。因篇幅有限窄陡,這里只對(duì)組件進(jìn)行簡(jiǎn)要描述,后續(xù)會(huì)針對(duì)每個(gè)組件進(jìn)行詳細(xì)的單獨(dú)講解拆火。
1. queue-proxy
queue-proxy
是 一個(gè)伴隨著用戶容器運(yùn)行的 Sidecar 容器跳夭,跟用戶容器運(yùn)行在同一個(gè) Pod 中。每個(gè)請(qǐng)求到達(dá)業(yè)務(wù)容器之前都會(huì)經(jīng)過(guò) queue-proxy
容器们镜,
這也是它問(wèn)什么叫 proxy
的原因币叹。
queue-proxy
的主要作用是統(tǒng)計(jì)和限制到達(dá)業(yè)務(wù)容器的請(qǐng)求并發(fā)量,當(dāng)對(duì)一個(gè) Revision 設(shè)置了并發(fā)量之后(比如設(shè)置了5)模狭,queue-proxy
會(huì)確保不會(huì)同時(shí)有超過(guò)5個(gè)請(qǐng)求打到業(yè)務(wù)容器颈抚。當(dāng)有超過(guò)5個(gè)請(qǐng)求到來(lái)時(shí),queue-proxy
會(huì)先把請(qǐng)求暫存在自己的隊(duì)列 queue
里嚼鹉,(這也是為什么名字里有個(gè) queue的緣故)贩汉。queue-proxy
同時(shí)會(huì)統(tǒng)計(jì)進(jìn)來(lái)的請(qǐng)求量,同時(shí)會(huì)通過(guò)指定端口提供平均并發(fā)量和 rps(每秒請(qǐng)求量)的查詢锚赤。
2. Autoscaler
Autoscaler
是 Knative Serving 系統(tǒng)中一個(gè)重要的 pod匹舞,它由三部分組成:
- PodAutoscaler reconciler
- Collector
- Decider
PodAutoscaler reconciler
會(huì)監(jiān)測(cè) PodAutoscaler
(KPA)的變更,然后交由 Collector
和 Decider
處理
Collector
主要負(fù)責(zé)從應(yīng)用的 queue-proxy
那里收集指標(biāo)线脚, Collector
會(huì)收集每個(gè)實(shí)例的指標(biāo)赐稽,然后匯總得到整個(gè)系統(tǒng)的指標(biāo)。為了實(shí)現(xiàn)擴(kuò)縮容浑侥,會(huì)搜集所有應(yīng)用實(shí)例的樣本姊舵,并將收集到的樣本反映到整個(gè)集群。
Decider
得到指標(biāo)之后寓落,來(lái)決定多少個(gè)Pod 被擴(kuò)容出來(lái)蠢莺。簡(jiǎn)單的計(jì)算公式如下:
want = concurrencyInSystem/targetConcurrencyPerInstance
另外,擴(kuò)縮容的量也會(huì)受到 Revision
中最大最小實(shí)例數(shù)的限制零如。同時(shí) Autoscaler
還會(huì)計(jì)算當(dāng)前系統(tǒng)中剩余多少突發(fā)請(qǐng)求容量(可擴(kuò)縮容多少實(shí)例)進(jìn)來(lái)決定 請(qǐng)求是否走 Activator
轉(zhuǎn)發(fā)躏将。
3. Activator
Activator
是整個(gè)系統(tǒng)中所用應(yīng)用共享的一個(gè)組件,是可以擴(kuò)縮容的考蕾,主要目的是緩存請(qǐng)求并給 Autoscaler
主動(dòng)上報(bào)請(qǐng)求指標(biāo)
Activator
主要作用在從零啟動(dòng)和縮容到零的過(guò)程祸憋,能根據(jù)請(qǐng)求量來(lái)對(duì)請(qǐng)求進(jìn)行負(fù)載均衡。當(dāng) revision
縮容到零之后肖卧,請(qǐng)求先經(jīng)過(guò) Activator
而不是直接到 revision
蚯窥。 當(dāng)請(qǐng)求到達(dá)時(shí),Activator
會(huì)緩存這這些請(qǐng)求,同時(shí)攜帶請(qǐng)求指標(biāo)(請(qǐng)求并發(fā)數(shù))去觸發(fā) Autoscaler
擴(kuò)容實(shí)例拦赠,當(dāng)實(shí)例 ready后巍沙,Activator
才會(huì)將請(qǐng)求從緩存中取出來(lái)轉(zhuǎn)發(fā)出去。同時(shí)為了避免后端的實(shí)例過(guò)載荷鼠,Activator
還會(huì)充當(dāng)一個(gè)負(fù)載均衡器的作用句携,根據(jù)請(qǐng)求量決定轉(zhuǎn)發(fā)到哪個(gè)實(shí)例(通過(guò)將請(qǐng)求分發(fā)到后端所有的Pod上,而不是他們超過(guò)設(shè)置的負(fù)載并發(fā)量)允乐。 Knative Serving 會(huì)根據(jù)不同的情況來(lái)決定是否讓請(qǐng)求經(jīng)過(guò) Activator
矮嫉,當(dāng)一個(gè)應(yīng)用系統(tǒng)中有足夠多的pod實(shí)例時(shí),Activator
將不再擔(dān)任代理轉(zhuǎn)發(fā)角色牍疏,請(qǐng)求會(huì)直接打到 revision
來(lái)降低網(wǎng)絡(luò)性能開(kāi)銷蠢笋。
跟 queue-proxy
不同,Activator
是通過(guò) websocket 主動(dòng)上報(bào)指標(biāo)給 Autoscaler
鳞陨,這種設(shè)計(jì)當(dāng)然是為了應(yīng)用實(shí)例盡可能快的冷啟動(dòng)昨寞。queue-proxy
是被動(dòng)的拉取:Autoscaler
去 queue-proxy
指定端口拉取指標(biāo)厦滤。
API
PodAutoscaler (PA,KPA)
API: podautoscalers.autoscaling.internal.knative.dev
PodAutoscaler
是對(duì)擴(kuò)縮容的一個(gè)抽象援岩,簡(jiǎn)寫是 KPA 或 PA ,每個(gè) revision
會(huì)對(duì)應(yīng)生成一個(gè) PodAutoscaler
馁害。
可通過(guò)下面的指令查看
kubectl get kpa -n xxx
ServerlessServices (SKS)
API: serverlessservices.networking.internal.knative.dev
ServerlessServices
是 KPA
產(chǎn)生的,一個(gè) KPA
生成一個(gè) SKS
蹂匹,SKS
是對(duì) k8s service 之上的一個(gè)抽象碘菜,
主要是用來(lái)控制數(shù)據(jù)流是直接流向服務(wù) revision
(實(shí)例數(shù)不為零) 還是經(jīng)過(guò) Activator
(實(shí)例數(shù)為0)。
對(duì)于每個(gè) revision
限寞,會(huì)對(duì)應(yīng)生成兩個(gè)k8s service 忍啸,一個(gè)public service
,一個(gè) private service
.
private service
是標(biāo)準(zhǔn)的 k8s service履植,通過(guò)label selector 來(lái)篩選對(duì)應(yīng)的deploy 產(chǎn)生的pod计雌,即 svc 對(duì)應(yīng)的 endpoints 由 k8s 自動(dòng)管控。
public service
是不受 k8s 管控的玫霎,它沒(méi)有 label selector凿滤,不會(huì)像 private service
一樣 自動(dòng)生成 endpoints。public service
對(duì)應(yīng)的 endpoints
由 Knative SKS reconciler
來(lái)控制庶近。
SKS
有兩種模式:proxy
和 serve
-
serve
模式下public service
后端 endpoints 跟private service
一樣翁脆, 所有流量都會(huì)直接指向revision
對(duì)應(yīng)的 pod。 -
proxy
模式下public service
后端 endpoints 指向的是 系統(tǒng)中Activator
對(duì)應(yīng)的 pod鼻种,所有流量都會(huì)流經(jīng)Activator
反番。
數(shù)據(jù)流
下面看幾種情況下的數(shù)據(jù)流向,加深對(duì)Knative 擴(kuò)縮容系統(tǒng)機(jī)制的理解。
1. 穩(wěn)定狀態(tài)下的擴(kuò)縮容
穩(wěn)定狀態(tài)下的工作流程如下:
- 請(qǐng)求通過(guò)
ingress
路由到public service
罢缸,此時(shí)public service
對(duì)應(yīng)的 endpoints 是 revision 對(duì)應(yīng)的 pod -
Autoscaler
會(huì)定期通過(guò)queue-proxy
獲取revision
活躍實(shí)例的指標(biāo)篙贸,并不斷調(diào)整 revision 實(shí)例。
請(qǐng)求打到系統(tǒng)時(shí)枫疆,Autoscaler
會(huì)根據(jù)當(dāng)前最新的請(qǐng)求指標(biāo)確定擴(kuò)縮容比例爵川。 -
SKS
模式是serve
, 它會(huì)監(jiān)控private service
的狀態(tài),保持public service
的 endpoints 與private service
一致 养铸。
2. 縮容到零
縮容到零過(guò)程的工作流程如下:
-
AutoScaler
通過(guò)queue-proxy
獲取revision
實(shí)例的請(qǐng)求指標(biāo) - 一旦系統(tǒng)中某個(gè)
revision
不再接收到請(qǐng)求(此時(shí)Activator
和queue-proxy
收到的請(qǐng)求數(shù)都為 0) -
AutoScaler
會(huì)通過(guò)Decider
確定出當(dāng)前所需的實(shí)例數(shù)為 0雁芙,通過(guò)PodAutoscaler
修改 revision 對(duì)應(yīng) Deployment 的 實(shí)例數(shù) - 在系統(tǒng)刪掉
revision
最后一個(gè) Pod 之前,會(huì)先將Activator
加到 數(shù)據(jù)流路徑中(請(qǐng)求先到Activator
)钞螟。Autoscaler
觸發(fā)SKS
變?yōu)?proxy
模式兔甘,此時(shí)SKS
的public service
后端的endpoints 變?yōu)?Activator
的IP,所有的流量都直接導(dǎo)到Activator
- 此時(shí)鳞滨,如果在冷卻窗口時(shí)間內(nèi)依然沒(méi)有流量進(jìn)來(lái)洞焙,那么最后一個(gè) Pod 才會(huì)真正縮容到零。
3. 冷啟動(dòng)(從零開(kāi)始擴(kuò)容)
冷啟動(dòng)過(guò)程的工作流程如下:
當(dāng) revision
縮容到零之后拯啦,此時(shí)如果有請(qǐng)求進(jìn)來(lái)澡匪,則系統(tǒng)需要擴(kuò)容。因?yàn)?SKS
在 proxy
模式褒链,流量會(huì)直接請(qǐng)求到 Activator
唁情。Activator
會(huì)統(tǒng)計(jì)請(qǐng)求量并將 指標(biāo)主動(dòng)上報(bào)到 Autoscaler
, 同時(shí) Activator
會(huì)緩存請(qǐng)求甫匹,并 watch SKS
的 private service
甸鸟, 直到 private service
對(duì)應(yīng)的endpoints產(chǎn)生。
Autoscaler
收到 Activator
發(fā)送的指標(biāo)后兵迅,會(huì)立即啟動(dòng)擴(kuò)容的邏輯抢韭。這個(gè)過(guò)程的得出的結(jié)論是至少一個(gè)Pod要被創(chuàng)造出來(lái),AutoScaler
會(huì)修改 revision
對(duì)應(yīng) Deployment
的副本數(shù)為為N(N>0),AutoScaler
同時(shí)會(huì)將 SKS
的狀態(tài)置為 serve
模式恍箭,流量會(huì)直接到導(dǎo)到 revision
對(duì)應(yīng)的 pod上刻恭。
Activator
最終會(huì)監(jiān)測(cè)到 private service
對(duì)應(yīng)的endpoints的產(chǎn)生,并對(duì) endpoints 進(jìn)行健康檢查扯夭。健康檢查通過(guò)后鳍贾,Activator
會(huì)將之前緩存的請(qǐng)求轉(zhuǎn)發(fā)到
健康的實(shí)例上。
最終 revison
完成了冷啟動(dòng)(從零擴(kuò)容)交洗。
本文作者: zhaojizhuang
本文鏈接: https://chumper.cn/2020/09/30/knative-autoscalling/
版權(quán)聲明: 本博客所有文章除特別聲明外贾漏,均采用 [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/) 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處藕筋!