ACK支援在控制台上安裝ack-keda,提供事件驅動彈效能力。本文介紹事件驅動彈性的概念、原理及如何使用事件驅動彈性。
事件驅動彈性概述
Kubernetes中,容器水平伸縮器HPA(Horizontal Pod Autoscaler)是最常執行的 App彈性方案。容器水平伸縮的核心是基於資源使用率與預設的閾值水位之間的關係,來確認伸縮的計劃。容器水平伸縮的方式具有使用簡單、資源指標豐富等特點,但是它對於需要即時彈性的情境,尤其是對基於事件來源進行離線作業支撐不足。ACK提供了ack-keda來提供事件驅動彈效能力,事件驅動彈性適用於音視頻離線轉碼、事件驅動作業、流式資料處理等情境。
事件驅動彈性的原理
ACK通過增強版本的ack-keda來提供事件驅動彈效能力,下圖是ack-keda的基本原理。
ack-keda會從事件來源中進行資料的周期性消費。當訊息出現堆積,即可秒級觸發一個批次的離線任務伸縮。下一個周期到來時,會非同步進行下一個批次的作業伸縮。ack-keda具有以下特性:
豐富的事件來源支援
ack-keda支援例如Kafka、MySQL、PostgreSQL、RabbitMQ、MongoDB等資料來源。更多資料來源,請參見RabbitMQ Queue。
離線任務的並發控制
對於大規模的離線作業而言,底層管控的穩定性會面臨比較大的挑戰,需要提供資源、額度、API請求的整體控制。ack-keda提供了單批次、總批次的任務並發控制,保障系統的穩定性。
結束任務後自動清理中繼資料
大規模離線作業執行完畢後,會留存大量的中繼資料資訊。中繼資料資訊的堆積會造成APIServer的穩定性下降,造成叢集的效能下降、穩定性不足,甚至可能影響其他的業務。ack-keda會在任務執行結束後自動清理中繼資料,降低中繼資料的量級。
案例說明
在本案例中,準備了一個簡單的轉碼作業。當有一個新任務到來的時候會向MongoDB插入一條類似下面的資料{"type":"mp4","state":"waiting","createTimeStamp":"1610332940","fileName":"World and peace","endTimeStamp":"","uuid":"1fae72ff-3239-42f5-af97-04711d8007e8"}
。此時,Container Service的事件驅動控制器會從資料庫中查詢到狀態為"state":"waiting"
的任務,彈出與任務數目匹配的Job Pod來承載轉碼任務,完成轉碼業務並將資料中的state
欄位從之前的waiting
修改成finished
。同時Job完成後,將自動清理中繼資料,降低中繼資料對APIServer帶來的壓力,減輕開發人員的負擔。
步驟一:部署ack-keda
在控制台左側導覽列,選擇 。
在應用市場頁面搜尋方塊中搜尋ack-keda,找到並單擊ack-keda。
單擊右上方一键部署。選擇叢集,單擊下一步,然後單擊确定。
在控制台左側導覽列單擊叢集,在叢集列表頁面中,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。在左側導覽列中單擊
,可以看到建立的ack-keda。
步驟二:部署基於mongoDB事件來源驅動彈性樣本
部署Mongo DB。
如果您已有MongoDB服務,可跳過此步驟。
重要此資料庫只用於測試,請勿用於生產環境。
建立mongoDB.yaml。
apiVersion: apps/v1 kind: Deployment metadata: name: mongodb spec: replicas: 1 selector: matchLabels: name: mongodb template: metadata: labels: name: mongodb spec: containers: - name: mongodb image: mongo:4.2.1 imagePullPolicy: IfNotPresent ports: - containerPort: 27017 name: mongodb protocol: TCP --- kind: Service apiVersion: v1 metadata: name: mongodb-svc spec: type: ClusterIP ports: - name: mongodb port: 27017 targetPort: 27017 protocol: TCP selector: name: mongodb
部署Mongo DB到叢集的mongodb命名空間中。
kubectl apply -f mongoDB.yaml -n mongodb
登入資料庫,註冊使用者。
建立使用者。
# 建立使用者 kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.createUser({ user:"test_user",pwd:"test_password",roles:[{ role:"readWrite", db: "test"}]})'
登入資料庫。
# 登入認證 kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.auth("test_user","test_password")'
建立Collection。
# 建立Collection kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.createCollection("test_collection")'
部署TriggerAuthentication和ScaledJob。
在ack-keda中對於事件來源的登入認證需要使用TriggerAuthentication。例如對於MongoDB事件來源,TriggerAuthentication中的
secretTargetRef
欄位會將指定Secret中的串連方式讀取到ack-keda中,完成對MongoDB的登入認證。建立auth.yaml。
apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: mongodb-trigger spec: secretTargetRef: - parameter: connectionString name: mongodb-secret key: connect --- apiVersion: v1 kind: Secret metadata: name: mongodb-secret type: Opaque data: connect: bW9uZ29kYjovL3Rlc3RfdXNlcjp0ZXN0X3Bhc3N3b3JkQG1vbmdvZGItc3ZjLm1vbmdvZGIuc3ZjLmNsdXN0ZXIubG9jYWw6MjcwMTcvdGVzdA==
部署TriggerAuthentication到叢集的mongodb-test命名空間中。
kubectl apply -f auth.yaml -n mongodb-test
部署ScaledJob。
ScaledJob主要用於配置Job模板以及指定查詢的資料庫及查詢運算式等。以下樣本配置的是從test資料庫中的test_collection中,查詢滿足
{"type":"mp4","state":"waiting"}
的待轉碼資料。建立scaledJob.yaml。
apiVersion: keda.sh/v1alpha1 kind: ScaledJob metadata: name: mongodb-job spec: jobTargetRef: # Job模板配置 template: spec: containers: - name: mongo-update image: registry.cn-hangzhou.aliyuncs.com/carsnow/mongo-update:v6 args: - --connectStr=mongodb://test_user:test_password@mongodb-svc.mongodb.svc.cluster.local:27017/test - --dataBase=test - --collection=test_collection imagePullPolicy: IfNotPresent restartPolicy: Never backoffLimit: 1 pollingInterval: 15 maxReplicaCount: 5 successfulJobsHistoryLimit: 0 failedJobsHistoryLimit: 10 triggers: - type: mongodb metadata: dbName: test # 要查詢的資料庫 collection: test_collection # 要查詢的collection query: '{"type":"mp4","state":"waiting"}' # 會對查詢轉碼類型為mp4且狀態是waiting的資料拉起job進行處理 queryValue: "1" authenticationRef: name: mongodb-trigger
query
:配置資料條目。當ack-keda查詢到Mongo資料庫中有滿足該條件的資料條目時,將啟動Job資源。部署ScaledJob到叢集的mongodb-test命名空間中。
kubectl apply -f scaledJob.yaml -n mongodb-test
插入5條待轉碼資料。
# 插入5條待轉碼資料 kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.test_collection.insert([ {"type":"mp4","state":"waiting","createTimeStamp":"1610352740","fileName":"My Love","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d8007e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610350740","fileName":"Harker","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d8007e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610152940","fileName":"The World","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d87767e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610390740","fileName":"Mother","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04799d8007e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610344740","fileName":"Jagger","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d80099e8"}, ])'
步驟三:驗證事件驅動彈性
執行以下命令,查看Job動態。
# watch job
watch -n 1 kubectl get job -n mongodb-test
可以看到成功擴充出5個Job。此時再登入資料庫,觀察轉碼業務狀態,可以看到資料狀態已經從waiting
變成了finished
。