上一篇我們講到了dapr提供的bindings,通過繫結可以讓我們的程式輕裝上陣,在極端情況下幾乎不需要整合任何sdk,僅需要通過httpclient+text.json即可完成對外部元件的呼叫,這樣只需要對外暴露一個輕量級的http伺服器提供restapi即可作為一個雲函式提供對外服務。上一篇我們同時也提到了在serverless框架下的函式還可以按需進行自動擴容縮容的,在極端情況下甚至可以將例項縮容至0,理想情況下serverless在無人訪問時不佔用系統除磁碟外的任何資源,當有訪問時通過自動化擴容快速啟動應用例項提供服務,當請求增多/減少時又相應的進行自動化擴容/縮容,當請求完全沒有時再次縮容到0。那今天我們就看看我們如何通過dapr+prometheus+keda來實現一套自動化擴容縮容吧。
目錄:
一、通過Dapr實現一個簡單的基於.net的微服務電商系統
二、通過Dapr實現一個簡單的基於.net的微服務電商系統(二)——通訊框架講解
三、通過Dapr實現一個簡單的基於.net的微服務電商系統(三)——一步一步教你如何擼Dapr
四、通過Dapr實現一個簡單的基於.net的微服務電商系統(四)——一步一步教你如何擼Dapr之訂閱釋出
五、通過Dapr實現一個簡單的基於.net的微服務電商系統(五)——一步一步教你如何擼Dapr之狀態管理
六、通過Dapr實現一個簡單的基於.net的微服務電商系統(六)——一步一步教你如何擼Dapr之Actor服務
七、通過Dapr實現一個簡單的基於.net的微服務電商系統(七)——一步一步教你如何擼Dapr之服務限流
八、通過Dapr實現一個簡單的基於.net的微服務電商系統(八)——一步一步教你如何擼Dapr之鏈路追蹤
九、通過Dapr實現一個簡單的基於.net的微服務電商系統(九)——一步一步教你如何擼Dapr之OAuth2授權
十、通過Dapr實現一個簡單的基於.net的微服務電商系統(十)——一步一步教你如何擼Dapr之繫結
十一、通過Dapr實現一個簡單的基於.net的微服務電商系統(十一)——一步一步教你如何擼Dapr之自動擴/縮容
附錄:(如果你覺得對你有用,請給個star)
一、電商Demo地址
照例得先嘮嘮這個擴容縮容機制到底是如何實現的熟悉k8sHPA機制的同學請跳過,k8s的HPA(Horizontal Pod Autoscaler),我們直接搬官方文件定義吧:“Pod 水平自動擴縮(Horizontal Pod Autoscaler) 可以基於 CPU 利用率自動擴縮 ReplicationController、Deployment、ReplicaSet 和 StatefulSet 中的 Pod 數量。 除了 CPU 利用率,也可以基於其他應程式提供的自定義度量指標 來執行自動擴縮。 Pod 自動擴縮不適用於無法擴縮的物件,比如 DaemonSet。”,單靠HPA提供的CPU/MEM利用率來做自動擴縮容很難用於真實的生產環境,同時HPA只能作用於1->N,N->1的情況。而serverless需要涵蓋例項從0->N,N->0的情況,所以單靠HPA是無法滿足我們的訴求的。而這個時候就需要一款基於HPA擴充套件的k8s元件來為我們提供相應的服務。而Dapr選擇微軟自家的KEDA(已經開源並捐獻給了CNCF基金會)。注意KEDA並不是為了覆蓋HPA的功能,而是作為一個輕量化的元件整合在k8s裡為hpa提供擴充套件服務。
除了keda,我們還需要一些指標,因為keda需要某些指標來作為其對pod的擴容和縮容的憑據,這部分指標目前恰好可以用dapr已經整合好的prometheus來提供。之前鏈路追蹤其實就是dapr+zipkin,而指標同樣也可以通過dapr+prometheus來完成。關於指標這部分在dapr的官方文件裡monitoring有詳細描述,使用起來和之前我們介紹的鏈路追蹤無太大差異,所以就不單開文章講解了,有訴求的同學可以直接訪問文件來自行搭建。
好了,接下來我們開始搭建,不過照例還是先上流程圖。注意此圖僅僅是簡易示例,真實的呼叫鏈會涉及更多的細節,此處不展開:
首先我們需要將prometheus安裝進來,通過Dapr提供的指南,我們可以使用helm進行安裝。
kubectl create namespace dapr-monitoring helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install dapr-prom prometheus-community/prometheus -n dapr-monitoring
tips:由於一個詭異的bug導致在windows平臺下的docker環境內無法啟動node-exporter,如果你不幸遇到了,可以使用這行程式碼解決,具體的issuse在這裡
kubectl patch ds dapr-prom-prometheus-node-exporter --type "json" -p '[{"op": "remove", "path" : "/spec/template/spec/containers/0/volumeMounts/2/mountPropagation"}]' -n dapr-monitoring
檢查你的dapr-monitoring,確保所有pod都能啟動,接著我們需要公開prometheus-server用於訪問頁面。通過kubectl edit svc dapr-prom-prometheus-server -n dapr-monitoring 開啟svc將spec.service.type從ClusterIP改為NodePort,如果你需要固定埠,再增加spec.ports.nodePort即可。儲存文件後我們再查詢kubectl get svc dapr-prom-prometheus-server -n dapr-monitoring 看看埠號是多少,然後訪問loalhost:port,如果出現以下頁面,則說明prometheus部署成功:
由於dapr會自動將指標寫入prometheus,當我們操作一下我們的電商demo之後,我們就可以從prometheus查詢到對應指標的情況了,以http請求數的情況為例:
prometheus先放一邊,接著我們安裝KEDA,依然參考dapr的文件,不過接下來我們和官方文件有一點出入,官方文件演示的是通過component讓keda監聽kafka,通過流量指標來確定擴容/縮容訂閱器的。我們這裡的演示是讓keda監聽prometheus的特定指標dapr_http_server_request_count來實現擴容/縮的。原理都一樣,即藉助keda來實現。接下來依然是通過helm安裝keda。
helm repo add kedacore https://kedacore.github.io/charts helm repo update kubectl create namespace keda helm install keda kedacore/keda --namespace keda
同樣安裝完畢後,觀察我們的keda,確保兩個pod都已經正確running之後,我們嘗試對我們的閘道器配置keda的ScaledObject來實現自動擴容/縮容:首先還是編寫一個ScaledObject,這是keda安裝後會自動在k8s裡申明的CRD資源符
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: prometheus-scaledobject namespace: dapreshop spec: scaleTargetRef: name: apigateway pollingInterval: 15 #指定keda的採集頻次,單位秒 minReplicaCount: 1 #指定預設規格 maxReplicaCount: 10 #最大擴容規格 triggers: - type: prometheus metadata: serverAddress: http://dapr-prom-prometheus-server.dapr-monitoring.svc.cluster.local #prometheus服務的svc用於keda採集指標 metricName: dapr_http_server_request_count #具體的指標名 query: sum(rate(dapr_http_server_request_count{app_id="apigateway"}[2m])) #這是prometheus特有的PromQL,這段query的意思是我們需要採集以2分鐘為一個維度對閘道器的請求平均訪問速率,這裡不展開,大家可以搜PromQL中文文件瞭解更多 threshold: '3' #閾值
當我們apply這個yaml之後,可以通過kubectl get so,hpa觀察我們的scaleobject和hpa的資源是否建立成功,一切OK後,我們通過postman的runner請求閘道器,看看hpa是否可以工作吧:
可以看到請求過來後,我們的指標已經被正確的收集到了,接著我們查詢一下閘道器的情況,可以看到已經被正確的擴容了:
當請求歸零後,過一段時間再次訪問會發現例項被縮容到了預設規格。這就是今天對dapr+keda實現動態擴容/縮容的介紹。當然要做到真正的雲函式那樣的從0例項快速冷啟動還需要一個過程,冷啟動在傳統雲商提供的雲函式環境裡是通過預熱池實現的,而本地化搭建要實現0例項冷啟動需要AOT的支援,至少就目前而言.netcore尚未支援AOT編譯成原生程式碼的情況下還很遙遠。但是不能說沒有實現serverless冷啟動做這個就沒有意義,當我們在特定場景比如做活動需要動態擴容/縮容時,完全可以通過keda去實現。當請求稀少的夜間我們完全就可以將例項縮容到1份繼續執行,或者類似於dapr官方文件示例那樣的訂閱器平時不需要執行時完全可以縮容到0個例項,等待訊息來觸發擴容執行消費。