オフラインジョブやストリーミングデータなどのイベント駆動型ワークロードを処理する場合、CPU 使用率やメモリ使用率に基づく従来の水平ポッド自動スケーリング(HPA)では、応答が十分に迅速でないことがあります。ack-keda は、メッセージキューおよびデータベースなど、さまざまなイベントソースからのバックログを監視し、数秒以内に Job または Deployment を自動的に作成します。タスク完了後にはリソースをゼロまでスケールダウンすることで、効率的かつリアルタイムなリソーススケジューリングとコスト最適化を実現します。
仕組み
ack-keda は、ACK と統合された Kubernetes ベースのイベント駆動型自動スケーリング(KEDA)の強化版です。そのコア機構では、Scaler を導入し、イベントソースとアプリケーションの間のブリッジとして機能します。
-
イベントソースの監視:
Scalerは、MongoDB などの外部イベントソースに接続し、指定されたメトリック(例:特定の条件を満たすドキュメント数)を定期的に照会します。 -
アプリケーションのスケーリングを推進する:
-
Scalerが未処理データなど、イベントのバックログを検出した場合、ack-keda はScaledJobまたはScaledObjectに関連付けられた対象ワークロードを即座にスケールアップします。具体的には、新しい Job を作成するか、Deployment の Pod レプリカ数を増加させます。 -
イベントが処理され、
Scalerがバックログを検出しなくなった場合、ack-keda はワークロードを自動的にスケールダウンします。Job の場合は、完了済みリソースをクリーンアップして、不要な容量およびメタデータの蓄積を防止します。
-
主なメリット:
-
多様なイベントソースへの対応: Kafka、MySQL、PostgreSQL、RabbitMQ、MongoDB などのデータソースをサポートします。詳細については、「RabbitMQ Queue」をご参照ください。
-
柔軟な同時実行制御:
maxReplicaCountなどのパラメーターを使用して、同時実行タスクの最大数を制限し、トラフィックバーストから下流システムを保護します。 -
自動メタデータクリーンアップ: タスク完了後、
ScaledJobは完了済みの Job およびその Pod を自動的に削除し、メタデータの蓄積による API Server の負荷を軽減します。

本トピックでは、シミュレートされた動画トランスコーディングのシナリオを例として説明します。"state":"waiting" を含むレコードが MongoDB データベースに挿入されると、ack-keda は自動的に Job Pod を作成してトランスコーディングタスクを実行し、完了後にレコードの状態を "state":"finished" に更新します。Job 完了後、そのメタデータは自動的にクリーンアップされ、API Server の負荷が軽減されます。
手順 1:ack-keda のデプロイ
-
ACK クラスター ページで、ご利用のクラスター名をクリックします。クラスターの詳細ページ左側のナビゲーションウィンドウで、 をクリックします。
-
デプロイ をクリックします。画面の指示に従って ack-keda を検索・選択し、最新のチャートバージョンを選択してインストールを完了します。
手順 2:MongoDB イベント駆動型自動スケーリングのサンプルをデプロイ
1. サンプル用の名前空間を作成
本サンプルでは、データベースをデプロイするための mongodb 名前空間と、自動スケーリング設定を配置するための mongodb-test 名前空間を使用します。
kubectl create ns mongodb
kubectl create ns mongodb-test
2. MongoDB のデプロイ
既に MongoDB サービスをお持ちの場合は、このステップをスキップしてください。
-
mongoDB.yaml を作成します。
重要この MongoDB サービスはデモンストレーション専用であり、高可用性を提供しません。本番環境では使用しないでください。
apiVersion: apps/v1 kind: Deployment metadata: name: mongodb namespace: mongodb spec: replicas: 1 selector: matchLabels: name: mongodb template: metadata: labels: name: mongodb spec: containers: - name: mongodb image: registry-cn-shanghai.ack.aliyuncs.com/acs/mongo:v5.0.0 imagePullPolicy: IfNotPresent ports: - containerPort: 27017 name: mongodb protocol: TCP --- kind: Service apiVersion: v1 metadata: name: mongodb-svc namespace: mongodb spec: type: ClusterIP ports: - name: mongodb port: 27017 targetPort: 27017 protocol: TCP selector: name: mongodb -
MongoDB をデプロイします。
kubectl apply -f mongoDB.yaml
3. MongoDB データベースの初期化
-
MongoDB Pod の名前を取得します。
MONGO_POD_NAME=$(kubectl get pods -n mongodb -l name=mongodb -o jsonpath='{.items[0].metadata.name}') echo "MongoDB Pod 名は: $MONGO_POD_NAME" -
testデータベース内に、ユーザーtest_userおよびコレクションtest_collectionを作成します。# ユーザーの作成 kubectl exec -n mongodb ${MONGO_POD_NAME} -- mongo --eval 'db.createUser({ user:"test_user",pwd:"test_password",roles:[{ role:"readWrite", db: "test"}]})' # ユーザーの認証 kubectl exec -n mongodb ${MONGO_POD_NAME} -- mongo --eval 'db.auth("test_user","test_password")' # コレクションの作成 kubectl exec -n mongodb ${MONGO_POD_NAME} -- mongo test --eval 'db.createCollection("test_collection")'
4. TriggerAuthentication および ScaledJob の構成
ack-keda は、TriggerAuthentication リソースを使用して、イベントソースへの接続に必要な認証情報を安全に管理します。ScaledJob は ack-keda のコアリソースであり、スケーリングルール、ポーリング間隔、および実行する Job のテンプレートを定義します。
-
auth.yaml を作成し、TriggerAuthentication をデプロイします。
MongoDB イベントソースの場合、TriggerAuthentication の
secretTargetRefフィールドは、指定された Secret から接続文字列を読み取り、ack-keda が MongoDB に対して認証を行うために使用します。apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: mongodb-trigger namespace: mongodb-test spec: secretTargetRef: - parameter: connectionString name: mongodb-secret key: connect --- apiVersion: v1 kind: Secret metadata: name: mongodb-secret namespace: mongodb-test type: Opaque data: connect: bW9uZ29kYjovL3Rlc3RfdXNlcjp0ZXN0X3Bhc3N3b3JkQG1vbmdvZGItc3ZjLm1vbmdvZGIuc3ZjLmNsdXN0ZXIubG9jYWw6MjcwMTcvdGVzdA== -
TriggerAuthentication をデプロイします。
kubectl apply -f auth.yaml -
ScaledJob をデプロイします。
ScaledJob は、Job テンプレートを設定し、使用するデータベースとクエリ式を指定します。次の例では、test データベースの test_collection に、保留中のトランスコーディングタスクを表す
{"type":"mp4","state":"waiting"}と一致するドキュメントを照会します。-
scaledJob.yaml を作成します。
apiVersion: keda.sh/v1alpha1 kind: ScaledJob metadata: name: mongodb-job namespace: mongodb-test spec: jobTargetRef: # Job テンプレートの構成 template: spec: containers: - name: mongo-update image: registry-cn-shanghai.ack.aliyuncs.com/acs/mongo-update:v6 args: - --dataBase=test - --collection=test_collection - --operation=updateMany - --update={"$set":{"state":"finished"}} env: - name: MONGODB_CONNECTION_STRING value: mongodb://test_user:test_password@mongodb-svc.mongodb.svc.cluster.local:27017/test imagePullPolicy: IfNotPresent restartPolicy: Never backoffLimit: 1 pollingInterval: 15 maxReplicaCount: 5 successfulJobsHistoryLimit: 0 failedJobsHistoryLimit: 10 triggers: - type: mongodb metadata: dbName: test # クエリ対象のデータベース collection: test_collection # クエリ対象のコレクション query: '{"type":"mp4","state":"waiting"}' # mp4 ファイルで「waiting」状態のレコードに対してジョブを起動 queryValue: "1" authenticationRef: name: mongodb-triggerqueryフィールドは、データの条件を定義します。ack-keda が MongoDB 内でこの条件に一致するドキュメントを検出すると、Job リソースが起動されます。 -
ScaledJob をデプロイします。
kubectl apply -f scaledJob.yaml
-
手順 3:イベントのシミュレーションおよび自動スケーリングのトリガー
-
mongodb名前空間内の MongoDB インスタンスに、5 件の保留中レコードを挿入して、着信タスクをシミュレートします。MONGO_POD_NAME=$(kubectl get pods -n mongodb -l name=mongodb -o jsonpath='{.items[0].metadata.name}') # 5 件の保留中のトランスコーディングレコードを挿入 kubectl exec -n mongodb ${MONGO_POD_NAME} -- mongo test --eval 'db.test_collection.insert([ {"type":"mp4","state":"waiting","createTimeStamp":"1610352740","fileName":"My Love"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610350740","fileName":"Harker"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610152940","fileName":"The World"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610390740","fileName":"Mother"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610344740","fileName":"Jagger"} ])' -
自動スケーリングの動作を確認します。
mongodb-test 名前空間内の Job リソースを継続的に監視します。
watch kubectl get job -n mongodb-test期待される出力では、5 件の Job が作成され、完了後に自動的にクリーンアップされます。
NAME STATUS COMPLETIONS DURATION AGE mongodb-job-4wxgx Complete 1/1 3s 10s mongodb-job-9bs8r Complete 1/1 3s 10s mongodb-job-p6pnb Complete 1/1 3s 10s mongodb-job-pshkv Complete 1/1 4s 10s mongodb-job-t6fs8 Complete 1/1 4s 10s -
データベース内のデータ状態をクエリします。
MONGO_POD_NAME=$(kubectl get pods -n mongodb -l name=mongodb -o jsonpath='{.items[0].metadata.name}') kubectl exec -n mongodb ${MONGO_POD_NAME} -- mongo test --eval 'db.test_collection.find({"type":"mp4"}).pretty()'期待される出力では、すべてのレコードの
stateフィールドの値がwaitingからfinishedに変更されています。