ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

Web App for Containers でセキュアな ACR から docker pull する + おまけ

f:id:horihiro:20210706155005p:plain

Web App for Containers でコンテナー イメージを docker pull する際に、Private Endpoint で保護されたセキュアな Azure Container Registry (ACR) からの docker pull も可能になりました!👏👏👏

元ネタはこちらの、Azure App Service チームのブログです。

azure.github.io

背景的なアレ

Web App for Containers も含めた App Service では VNET 統合を使用することで、App Service から VNET 内のリソースにアクセスできるようになります。
でも実は、ACR 側で Private link を使って、かつ、パブリック アクセスを拒否することで ACR をセキュアにすると、今までは Web App for Containers から ACR から docker pull できない (アクセスが拒否される) という状況でした。

イメージとしては、docker デーモンを起動しているホスト マシンでの docker pull 時の通信が、VNET に向けられていない、という感じです。
# あくまでイメージなので、正確なところはわかりません。起動した docker コンテナーは VNET 内のリソースへのアクセスはできます。

これが docker pull の段階から VNET 経由で ACR にアクセスできるようになった、というお話です。

事前設定

まず Web App for Containers を VNET 統合しておきます。これが大前提。

次に ACR の Private Link を有効にしておきます。
ACR での Private Link の利用についてはこちら。

docs.microsoft.com

Azure ポータルから ACR の [Networking] ブレードからポチポチしていくとできるので、そんなに難しいことはありません。

f:id:horihiro:20210706104453p:plain

Private Endpoint を作成する VNET は、Web App for Containers が VNET 統合しているものと同じものを選択しましょう (サブネットはそれぞれ専用のものになるので、違っていても大丈夫) 。

なお ACR からの docker pull に Web App for Containers の Managed Identity は使えないので、ACR の [Access keys] ブレードから Admin user を有効にしておく必要があります。

f:id:horihiro:20210706112628p:plain

元ブログにも書いてありますが、見落としてて数十分無駄にしたので、自分用の備忘録に。

We need Premium SKU to enable private endpoint and currently admin access must be enabled:

# なぜ元ブログのトップ絵には、Managed Identity があるのかw

キモになる設定

ここからは Web App for Containers 側の設定です。

1. docker pull を VNET 越しにする設定

この度、WEBSITE_PULL_IMAGE_OVER_VNET というアプリ設定が仲間入りしました!
いかにも VNET 越しに docker pull しそうな設定名です。

ちなみに、Web 検索してみたら、2021/7/6 現在で 2 件ほどしかヒットしませんので、今なら検索トップも夢ではありません!!(ォィ

az webapp config appsettings set --resource-group secureacrsetup --name secureacrweb2021 --settings 'WEBSITE_PULL_IMAGE_OVER_VNET=true'

元ブログでは Azure CLI を使って設定していますが、もちろん Azure ポータルから設定しても大丈夫です。 f:id:horihiro:20210706113413p:plain

2. Outbound 通信を全て VNET 経由にする設定

Outbound を全て VNET 経由にする、と言えば、みんな大好き WEBSITE_VNET_ROUTE_ALL=1 が思い浮かびますが、上記ブログには別の方法が書かれています。

az webapp config set --resource-group secureacrsetup --name secureacrweb2021 --generic-configurations '{"vnetRouteAllEnabled": true}'

こちらも見慣れない vnetRouteAllEnabled というプロパティを true に設定しています。
見慣れないですが、またもや名前から動作が想像できるプロパティです。名前重要。

Resource Explorer で確認してみると、確かにありますね。

f:id:horihiro:20210706110652p:plain

ARM テンプレートのリファレンスを確認してみると、api-version=2020-06-01 から SiteConfig の中にあるようなので、恐らく 1 年位前には既にあったのかもしれません 。
へー、知らなかった。

f:id:horihiro:20210706114058p:plain

docs.microsoft.com

ちなみに動作としては WEBSITE_VNET_ROUTE_ALL=1 と全く同じのようで、WEBSITE_VNET_ROUTE_ALL=1vnetRouteAllEnabled": true 、どちらかが設定されていれば OK です。
アプリ設定で管理したい場合は、WEBSITE_VNET_ROUTE_ALL を使えばいいでしょう。

意外だったのが、WEBSITE_DNS_SERVER=168.63.129.16 が要らないことです。

試しに sshd 入りのコンテナーを動かして、その中で nslookup してみると、アプリ設定 (=環境変数) WEBSITE_DNS_SERVER がないコンテナーでも、ACR の IP アドレスがプライベート IP アドレスとして解決できています。

f:id:horihiro:20210706121809p:plain

ちょっとこのあたりについては、どの時に WEBSITE_DNS_SERVER=168.63.129.16 が必要でどの時にいらないのか、まだ勉強中です。

以上の設定で、無事 Private Link を使って Private Endpoint 経由のみにアクセス制限した ACR 上のコンテナー イメージを、Web App for Containers から docker pull できるようになります。
お試しあれ。

おまけ ~ Private DNS Zone を削除する

そんなに使い機会はないんですが、こちらも備忘録に。

Private Link を試してみて、その後不要になれば当然リソースを削除すると思いますが、その時に ACR をプライベート IP アドレスを解決するための Private DNS Zone リソースも消そうとするとたまに見るのがこれ。

f:id:horihiro:20210706122253p:plain

意訳すると「子リソースを消してないのに消せねぇって」といったところでしょうか。
ただ、関係しそうなリソースをあらかた消しても、 Private DNS Zone を消す時だけはこれが出て失敗します。

そんな時は、Private DNS Zone があるリソース グループで隠しリソースを表示してみてください。

f:id:horihiro:20210706122649p:plain

リソース タイプが microsoft.network/privatednszones/virtualnetworklinks で、試した Private Link にいかにも関連してそうなリソースが出てきます。
これを先に消してしまえば、Private DNS Zone も消せるようになります。

(一緒に消してくれたらいいのに。ボソッ

以上、おまけでした。