Azure Container Apps Jobを試してみる
https://learn.microsoft.com/ja-jp/azure/container-apps/jobs-get-started-cli?pivots=container-apps-job-scheduled#create-a-container-apps-environment を参考にAzure Container Apps Jobを試してみます
試してみること
今回は実行するとSlackにPOSTする、というimageを作成して、1分ごとにSlackにPOSTする処理をAzure Container Apps Jobに設定してみたいと思います。
流れ
- サンプルのDocker imageを作成
- Azure Container Registryを作成しDocker imageをpush
- Azure Container Apps Jobを作成
手順
サンプルのDocker imageを作成
- 実行するscript
#!/bin/sh
echo "Sample slack notification script starting"
curl -s -X POST \
-H 'Content-type: application/json' \
--data '{"text":"Hello, World!"}' \
https://hooks.slack.com/services/xxxx # 事前にwebhookのURLを取得しておく
echo ""
echo "Sample slack notification script finished"
- Dockerfile
# ベースイメージとしてalpineを使用
FROM alpine
# 必要ならcurlをインストール
RUN apk --no-cache add curl
COPY send_slack.sh /send_slack.sh
RUN chmod +x /send_slack.sh
# コンテナ起動時に実行するコマンド
CMD ["/send_slack.sh"]
- buildしてローカルでテストしてみます
docker build -t my-slack-curl .
docker run my-slack-curl
Sample slack notification script starting
ok
Sample slack notification script finished
こんな感じでPOSTされます
Azure Container Registryを作成してimageをpush
- Terraformで構築します(Terraform Cloud使ってます
# main.tf
terraform {
cloud {
organization = "tsaeki"
workspaces {
name = "example_azure_container_apps_job"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "Japan East"
}
resource "azurerm_container_registry" "example" {
name = "exampleAzureContainerAppsJob"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Basic"
admin_enabled = false
}
- 構築
terraform init
terraform plan
terraform apply
- 先程作成したimageをpushします
docker login exampleazurecontainerappsjob.azurecr.io
# username/password ※
docker tag my-slack-curl exampleazurecontainerappsjob.azurecr.io/my-slack-curl
docker push exampleazurecontainerappsjob.azurecr.io/my-slack-curl
※ username/passwordはContainer Registryの Access Keys
にあります
Azure Container Apps Jobを作成
https://learn.microsoft.com/ja-jp/azure/container-apps/jobs-get-started-cli?pivots=container-apps-job-scheduled を参考に実行していきます
- セットアップ
az login
az upgrade
az extension add --name containerapp --upgrade'
az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights
- Container Apps 環境を作成する
RESOURCE_GROUP="example-resources"
LOCATION="japaneast"
ENVIRONMENT="env-jobs-quickstart"
JOB_NAME="my-job"
## Container Apps 環境を作成する
az containerapp env create \
--name "$ENVIRONMENT" \
--resource-group "$RESOURCE_GROUP" \
--location "$LOCATION"
- スケジュールされたジョブを作成して実行する
az containerapp job create \
--name "$JOB_NAME" \
--resource-group "$RESOURCE_GROUP" \
--environment "$ENVIRONMENT" \
--trigger-type "Schedule" \
--replica-timeout 1800 \
--replica-retry-limit 1 \
--replica-completion-count 1 \
--parallelism 1 \
--image "exampleazurecontainerappsjob.azurecr.io/my-slack-curl:latest" \
--cpu "0.25" \
--memory "0.5Gi" \
--cron-expression "*/1 * * * *" \
--registry-server "exampleazurecontainerappsjob.azurecr.io" \
--registry-username "<username>" \
--registry-password "<password>"
※ username/passwordはContainer Registryのです
動作確認
1分ごとにSlackにPOSTされてることを確認します。
またAzure PortalからContainer App JobsのExecution historyを見てみましょう。
ちゃんと動いてたら Succeeded
になってると思います。
うまく動いてないと Running
のままだったりします。
- 最近のジョブの実行履歴を一覧表示する
az containerapp job execution list \
--name "$JOB_NAME" \
--resource-group "$RESOURCE_GROUP" \
--output table --query '[].{Status: properties.status, Name: name, StartTime: properties.startTime}'
# output
Status Name StartTime
--------- --------------- -------------------------
Succeeded my-job-28388014 2023-12-22T21:34:00+00:00
Succeeded my-job-28388013 2023-12-22T21:33:00+00:00
Succeeded my-job-28388012 2023-12-22T21:32:00+00:00
Succeeded my-job-28388011 2023-12-22T21:31:00+00:00
Succeeded my-job-28388010 2023-12-22T21:30:00+00:00
Succeeded my-job-28388009 2023-12-22T21:29:18+00:00
- ジョブの実行ログのクエリを実行する
実行ログを表示します。
# Container Apps 環境の Log Analytics ワークスペース ID を変数に保存します。
LOG_ANALYTICS_WORKSPACE_ID=`az containerapp env show --name "$ENVIRONMENT" --resource-group "$RESOURCE_GROUP" --query "properties.appLogsConfiguration.logAnalyticsConfiguration.customerId" --output tsv`
# 最新のジョブ実行の名前を変数に保存します。
JOB_EXECUTION_NAME=`az containerapp job execution list --name "$JOB_NAME" --resource-group "$RESOURCE_GROUP" --query "[0].name" --output tsv`
# 確認
echo $LOG_ANALYTICS_WORKSPACE_ID
19f94564-30db-46e9-ae50-7114b5b5c5a8
echo $JOB_EXECUTION_NAME
my-job-28388018
# ジョブ実行用の Log Analytics に対してクエリを実行します。
az monitor log-analytics query \
--workspace "$LOG_ANALYTICS_WORKSPACE_ID" \
--analytics-query "ContainerAppConsoleLogs_CL | where ContainerGroupName_s startswith '$JOB_EXECUTION_NAME' | order by _timestamp_d asc" \
--query "[].Log_s"
以下のような結果が表示されます。
[
"Starting Job Envoy Sidecar",
"[2023-12-22 21:38:05.524][16][warning][main] [source/server/server.cc:704] No admin address given, so no admin HTTP server started.",
"[2023-12-22 21:38:05.540][16][warning][main] [source/server/server.cc:814] there is no configured limit to the number of allowed active connections. Set a limit via the runtime key overload.global_downstream_max_connections",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.843114501Z\",\"logger\":\"LocalProxyClient\",\"caller\":\"proxy/main.go:125\",\"msg\":\"Getting latest ServiceRedirectInfos. Id:k8se-apps_my-job-28388018-rvzb8\"}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.877920055Z\",\"logger\":\"controllers.Proxy\",\"caller\":\"controllers/iptables_controller.go:95\",\"msg\":\"Generating chains and rules for k8se-apps/cappscanary-blackdune-5e3499bd, total mappings: 1\"}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.883695001Z\",\"logger\":\"LocalProxyClient\",\"caller\":\"proxy/main.go:145\",\"msg\":\"Start listening services redirect info updates\"}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.883654756Z\",\"logger\":\"LocalProxyClient\",\"caller\":\"proxy/main.go:139\",\"msg\":\"Initialized\"}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.877865323Z\",\"logger\":\"controllers.Proxy\",\"caller\":\"controllers/iptables_controller.go:88\",\"msg\":\"Start syncing all iptables rules\"}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.877935073Z\",\"logger\":\"controllers.Proxy\",\"caller\":\"controllers/iptables_controller.go:95\",\"msg\":\"Generating chains and rules for k8se-apps/cappscanary-blackdune-5e3499bd--1-30-4, total mappings: 1\"}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.883626744Z\",\"logger\":\"controllers.Proxy.stopwatch\",\"caller\":\"stopwatch/stopwatch.go:32\",\"msg\":\"measured: \",\"OperationName\":\"sync iptables rules\",\"Duration\":5}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.877952175Z\",\"logger\":\"controllers.Proxy\",\"caller\":\"controllers/iptables_controller.go:113\",\"msg\":\"Loading into iptables.\",\"Details\":{\"numNATChains\":6,\"numNATRules\":3,\"numServices\":2}}",
"{\"level\":\"info\",\"ts\":\"2023-12-22T21:38:05.883589124Z\",\"logger\":\"controllers.Proxy\",\"caller\":\"controllers/iptables_controller.go:131\",\"msg\":\"Successfully synced all iptables rules\"}",
"Sample slack notification script starting",
"okSample slack notification script finished"
]
こちらはAzure Portalからも確認できます。
ContainerAppConsoleLogs_CL
| where ContainerGroupName_s startswith 'my-job-28388018'
| order by _timestamp_d asc
感想
他にもAzureでこのようなバッチを処理するサービスはありますが、shell scriptを実行したいときとかよさそうです。
あとChatGPTを使うと、ちょっと試してみたい環境(今回はTerraformやSlackへPOSTするスクリプト)を作ってくれるので、やっぱり便利だなぁーと思いました。
参考
Discussion