Azure Container Instances (ACI) からAzure Container Registry (ACR) へのアクセスをVNet経由にしたい

このエントリは2024/11/25現在の情報に基づいています。将来の機能追加や変更に伴い、記載事項からの乖離が発生する可能性があります。

問い合わせ

大昔にACIについて問い合わせをしてきた人から久しぶりに問い合わせをもらった。

以前、ACIからACRのイメージをPullする場合、VNetを経由することはできなかったが、現在はどうなのか?

「ドキュメント見てくれよー」と思いつつ、そのドキュメントの表現に疑問があったので、動作確認した。このエントリはその記録でもある。

どうなのか?

ドキュメント上、現在ではVNet経由でのPullができるようになったように読めるが、「ACRにとってのTrusted serviceとしてACIを構成し、Managed IdentityでのRBACを構成する」ことが前提になっているので、信頼済みサービスとしてFirewallをバイパスできるようになっているだけである。

ドキュメントは以下のあたり。

マネージド ID を使用した Azure Container Registry から Azure Container Instances へのデプロイ / Deploy to Azure Container Instances from Azure Container Registry using a managed identity
https://learn.microsoft.com/azure/container-instances/using-azure-container-registry-mi
コンテナー インスタンスを Azure 仮想ネットワークにデプロイする / Deploy container instances into an Azure virtual network
https://learn.microsoft.com/azure/container-instances/container-instances-vnet

ただ、以前はManaged IdentityでのRBACがサポートされていなかったので、この点では改善されている。具体的には以下の差分の通りで、以前は

という記述があったが、この記述が削除されている。

https://github.com/MicrosoftDocs/azure-compute-docs/commit/377a3fc69476525ec78e5c3c1b810776acacaacb

動作確認してみる

動作確認のシナリオは以下の通り。

  • 簡単なコンテナーイメージをACRにPushしておき、そのイメージをACIに展開して動作確認する。
  • ACRの診断設定>すべてのログを取得しておき、アクセスがどのIPアドレスから行われているかを確認する。
  • この前段として、ACRはPremium SKUで作成し、ネットワークアクセスはパブリックアクセスを禁止しつつ、信頼済みサービスに対してFirewallのバイパスを有効化しておく。

具体的には以下のドキュメントを参照。

信頼されたサービスがネットワーク制限付きコンテナー レジストリに安全にアクセスできるようにする / Allow trusted services to securely access a network-restricted container registry
https://learn.microsoft.com/azure/container-registry/allow-access-trusted-services

以降でACI作成の手順を記載する。

ACIの作成

手順は以下のドキュメントに記載の通りであるが、ここにも記載しておく。

マネージド ID を使用した Azure Container Registry から Azure Container Instances へのデプロイ / Deploy to Azure Container Instances from Azure Container Registry using a managed identity
https://learn.microsoft.com/azure/container-instances/using-azure-container-registry-mi

上記のACRのドキュメントでは、ACIのmanaged identityとして、system assigned / user assigned のいずれを使ってもよいことになっているが、Azure CLIで構成する場合、2024/11/25現在user assignedでないと以下のようなエラーが出るので、user assignedを使っている。

user assignedを使う場合は、事前にmanaged identityを作成して、ACRのロールにidentityを関連付ける。今回関連付けが必要なロールはAcrPull。

az identity create -g $RESOURCE_GROUP -n $ID_NAME

# Get resource ID of the user-assigned identity
USERID=$(az identity show -g $RESOURCE_GROUP -n $ID_NAME --query id --output tsv)
# Get service principal ID of the user-assigned identity
SPID=$(az identity show -g $RESOURCE_GROUP -n $ID_NAME --query principalId --output tsv)

# $REGISTRY_ID is a resource id for Azure Container Registry
az role assignment create --assignee $SPID --scope $REGISTRY_ID --role acrpull

ACRではでパブリックアクセスを抑止し、その後ACIを作成する。このとき、identityを関連付け、さらにOSの種類、CPUコア数、メモリサイズや、コンテナーイメージを指定しておく。

az container create -n $CONTAINER_GROUP_NAME \
   -g $RESOURCE_GROUP \
   --image $REGISTRY_NAME.azurecr.io/$IMAGE:$TAG \
   --acr-identity $USERID \
   --assign-identity $USERID \
   --vnet $VNET_NAME \
   --subnet $SUBNET_NAME \
   --os-type Linux \
   --memory 2 \
   --cpu 1

これで準備はおしまい。

試してみる

ACIに対し、ACRからイメージをプルするよう指示する。これはACIを停止し、ACIを再起動すると、そのタイミングでACRからイメージをプルするので、そのログを追跡する。

ACRで診断設定を構成しているため、ContainerRegistryRepositoryEventsというログテーブルが作成され、ここにイメージプル時のIPアドレスが記載されている(ACI側のログではIPアドレスを追跡できない)。Public IPアドレスは赤でマスクしているが、この値はMicrosoftが管理するPublic IPではあるものの、どのリソースにも関連付けていないIPアドレスであった。つまり、ACIからACRへのアクセスを(Firewallをバイパスして)受け付けている、ということがわかる。

構成図にすると、オレンジではなく、赤線のルートをたどっている。

Container Appsではどうなのか?

上記の結果を伝えると、更問としてContainer Apps (ACA) の場合はどうなのか、という問い合わせがあった。下図のようにカスタムVNetを使い、ACRへのPrivate Endpointを構成している場合(Container Appsの属するSubnetは10.0.2.0/24)、

ContainerRegistryRepositoryEventsに記録されるIPアドレスは、Container AppsのPrivate IPアドレスである。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください