Azure Container Apps ジョブを動作させる (イベント ドリブン トリガー編)
概要
以前に以下を記載しましたが、今回はイベントによってトリガーされる Azure Container Apps ジョブを作成してみます。
Azure Container Apps ジョブを動作させる (手動トリガー編)
Azure Container Apps ジョブを動作させる (スケジュール トリガー編)
詳細
イメージとストレージ キューの準備
今回は以下のサンプル プログラムを使用してみます。
- container-apps-event-driven-jobs-tutorial
https://github.com/Azure-Samples/container-apps-event-driven-jobs-tutorial
見やすい形で内容を一旦確認したいので、一旦ローカルに落とします。
D:\projects>git clone https://github.com/Azure-Samples/container-apps-event-driven-jobs-tutorial.git
Cloning into 'container-apps-event-driven-jobs-tutorial'...
remote: Enumerating objects: 41, done.
remote: Counting objects: 100% (41/41), done.
remote: Compressing objects: 100% (31/31), done.
Receiving objects: 58% (24/41)used 33 (delta 8), pack-reused 0
Receiving objects: 100% (41/41), 17.57 KiB | 5.86 MiB/s, done.
Resolving deltas: 100% (11/11), done.
Visual Studio Code 等で開いて、どのような内容なのか見てみます。
Dockerfile は以下の内容でした。
FROM node:lts-alpine
ENV NODE_ENV=production
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install --production --silent && mv node_modules ../
COPY . .
RUN chown -R node /usr/src/app
USER node
CMD ["node", "index.js"]
index.js を確認すると、メッセージをデキューし、処理してから削除するという事をしているのがわかります。
require("dotenv").config();
const { QueueClient, QueueServiceClient } = require("@azure/storage-queue");
const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING;
const queueName = process.env.AZURE_STORAGE_QUEUE_NAME;
async function main() {
const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString);
const queueClient = queueServiceClient.getQueueClient(queueName);
// 1. Dequeue one message from the queue
const response = await queueClient.receiveMessages({
numberOfMessages: 1,
visibilityTimeout: 60, // set this to longer than the expected processing time (in seconds)
});
if (response.receivedMessageItems.length === 0) {
console.log("No message received. Exiting...");
return;
}
const message = response.receivedMessageItems[0];
console.log(`Processing message: ${message.messageText}`);
// 2. Process the message here
// 3. Delete the message from the queue
await queueClient.deleteMessage(message.messageId, message.popReceipt);
console.log("Message processed");
// 4. Exit
}
main();
また、ストレージ アカウントへの接続文字列やキュー名の取得のために、以下環境変数から値を取得しています。
AZURE_STORAGE_CONNECTION_STRING
AZURE_STORAGE_QUEUE_NAME
概要は確認したのでイメージをビルドして、ACR へログインしてから push します。
docker build -t <Image Name> .
docker push <Image Name>:<Tag>
なお、直接 ACR から build する事もできますが、その場合は以下を実施します。
az acr build --registry "<Name of ACR>.azurecr.io" --image "<Image Name>" "https://github.com/Azure-Samples/container-apps-event-driven-jobs-tutorial.git"
最後にストレージ アカウントとキューも作成しておきます。
ジョブの作成
下準備ができたところで、Azure Container Apps ジョブを作成します。
Azure Container Apps ジョブを動作させる (手動トリガー編) 及び、
Azure Container Apps ジョブを動作させる (スケジュール トリガー編)ではポータルから作成しましたが、今回は、Azure CLI で行います。イベント ドリブンという事もありパラメーターも多くなります。
az containerapp job create --name "<Job Name>" \
--resource-group "<Resource Groupe Name>" \
--environment "<Container Apps Environemnt Full Resource ID>" \
--trigger-type "Event" \
--replica-timeout "1800" \
--replica-retry-limit "1" \
--replica-completion-count "1" \
--parallelism "1" \
--min-executions "0" \
--max-executions "10" \
--polling-interval "60" \
--scale-rule-name "<Scale Rule Name>" \
--scale-rule-type "azure-queue" \
--scale-rule-metadata "accountName=<Storage Account Name>" "queueName=<Storage Account Queue Name>" "queueLength=1" \
--scale-rule-auth "connection=connection-string-secret" \
--image "<ACR Name>.azurecr.io/<Image Name>" \
--cpu "0.25" \
--memory "0.5Gi" \
--secrets "connection-string-secret=<Storage Account Connection String>" \
--registry-server "<ACR Name>.azurecr.io" \
--env-vars "AZURE_STORAGE_QUEUE_NAME=<Storage Account Queue Name>" "AZURE_STORAGE_CONNECTION_STRING=secretref:connection-string-secret" \
いくつかピックアップして考察します。
--trigger-type "Event"
今回はイベント ドリブン トリガーを作成したいので、Event
にします。
--scale-rule-name "<Scale Rule Name>"
スケーリング ルールを決める必要があるのですが、その名前になります。任意の名前を設定します。
--scale-rule-type "azure-queue"
今回キューでトリガーするジョブを作成するので、その場合には azure-queue
とします。
以下公式ドキュメントが参考になります。
- ジョブを構築してデプロイする
https://learn.microsoft.com/ja-jp/azure/container-apps/tutorial-event-driven-jobs#build-and-deploy-the-job - Azure Container Apps でスケーリング ルールを設定する
https://learn.microsoft.com/ja-jp/azure/container-apps/scale-app?pivots=azure-cli
動作確認
作成完了しましたので、キューにメッセージを入れて動作を見てみます。
以下のようにメッセージを入れてみました。(暫く時間を置いて、2 回実施してみました)
成功しました。
更に詳細を見てみます。ContainerAppSystemLogs_CL
から見てみます。
ContainerAppSystemLogs_CL
| where TimeGenerated >= datetime(2024-01-01 10:40:00) and TimeGenerated <= datetime(2024-01-01 11:00:00)
| where ExecutionName_s has "das-job-0001"
| project TimeGenerated, Reason_s, JobName_s, ExecutionName_s,EventSource_s,ReplicaName_s,Log_s,Count_d
| order by TimeGenerated asc
KEDA が動作している事がわかります。
次に、ContainerAppConsoleLogs_CL
を見てみます。
ContainerAppConsoleLogs_CL
| where TimeGenerated >= datetime(2024-01-01 10:40:00) and TimeGenerated <= datetime(2024-01-01 11:50:00)
| where * contains "das-job-0001"
| order by TimeGenerated asc
1 回目の実行
2 回目の実行
index.js に記載した以下の部分のログが出力されている事がわかります。
console.log(`Processing message: ${message.messageText}`);
console.log("Message processed");
まとめ
今回はイベント ドリブン トリガーで動作する、Azure Container Apps ジョブを作成してみました。機会があれば、次は KEDA によるスケーリング等について、もっと深堀してみたいと思います。
Discussion