🔖
ACIをHTTPSで外部公開できるのか調べてみた
ACIでアプリを外部公開する
概要
最近Azureでコンテナを扱う機会があり、Azure Container Instance(ACI)が結構シンプルで扱いやすいと感じたのだが、
そういえばVNETに統合して配置したACIを外部公開するときってどういう構成をとるのがいいのか、あまり記事がなかったので実際に試してみた。
構成
以下のような構成が実際にとれるのか試してみた。何点か補足する。
- DBと接続することを考えて、ACIは用意したVNET上(プライベート)にデプロイする。
- ACI自体にHTTPSで公開する設定がないため、Application Gatewayを全段に配置。
- 個人環境での検証のため、料金は最小限にすべくドメインとサーバ証明書は以下のように用意
- ドメインはお名前.comで無料のドメインを取得し、サブドメインをAzure DNSに委任
- サーバ証明書をZeroSSLで無料のサーバ証明書を発行
手順
ドメインとサーバ証明書
ドメインの取得
お名前.comからドメインを取得する手順は割愛
サブドメイン委任
- サブドメインをAzure DNSで作成して、払いだされたNSレコードに設定されているAzureのDNSサーバをメモする。
- メモしたAzure DNSサーバを、お名前.comで取得したドメインで、サブドメインのNSレコードに設定する。
最大3日かかると記載があったが、設定してから5分もしないうちに設定完了のメール通知が来た。
サーバ証明書の取得
- ブラウザ上でサーバ証明書を簡単に発行できるため、ZeroSSLで取得したドメインのサーバ証明書を発行する。
- ドメイン所有の検証はメール検証、DNS検証などがあるが、DNS検証を選択
- Azure DNS上にCNAMEレコードを登録し、ZeroSSL側で検証を進めるとサーバ証明書をダウンロードできるようになる。
- Application Gatewayに取得したサーバ証明書をアップロードする際は、PFX形式であげる必要があるので以下のコマンドで変換
- 今回は個人のため無料のサーバ証明書を使ったが、実際にはAzure上AppService証明書を発行したり、正式な機関で発行したものを使う
openssl pkcs12 -export \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile ca_bundle.crt \
-password pass:任意のパスワード
ACI
- 以下のコマンドでACIを作成
az container create \
--resource-group <リソースグループ名> \
--name webtest \
--image nginx:latest \
--cpu 1 \
--memory 1 \
--vnet-name <VNet名> \
--subnet <サブネット名> \
--ports 80
注意点
- IPアドレスはパブリック/プライベートどちらも固定化されず、起動の度に変わる可能性がある。
- プライベートの場合、initコンテナか別途Automationを使った仕組みを考える必要があると参考に記載があったが、Event GridでACIの起動イベントをトリガーに、Azure FunctionでApplication Gatewayのバックエンドを更新できるはず。(別途検証して記事にしたい)
Azure Container Instances に固定の IP アドレスを割り当てる以外の代替案 - ACIをVNETに配置する要件がなければ、パブリックにデプロイするとDNSラベル(FQDN)が設定できるので、Application GatewayからDNSラベルを指せばよさそう。
Application Gateway
-
Application GatewayはBasicとStandardで10倍ぐらいコストが違う。個人のためBasicで検証
-
事前にApplication Gateway用のサブネットを用意して、用意したサブネットを選択
-
パブリックの静的IPアドレスを作成
-
バックエンドには、ACIで割り当てられたプライベートIPを設定
-
プロトコルをHTTPSにして、変換したPFX形式のサーバ証明書をアップロード
-
バックエンドはHTTPプロトコル
-
バックエンドターゲットに設定したバックエンドを指定
NSG
-
このままだと世界中のどこからでもアクセスできてしまうので、NSGを使ってIP制限をする。
-
65200-65535ポートはApplication Gatewayで必要なポートのため、インバウンドルールで開ける必要がある。
- ソースはAnyで開けるのではなく、ラベルでGatewayManagerを選択する。
- ソースはAnyで開けるのではなく、ラベルでGatewayManagerを選択する。
-
NSGをApplication Gatewayのサブネットに紐づけることで、Iトラフィックを制御。
アクセス
- Application Gatewayに紐づけたパブリックIPアドレスでDNSのAレコードを作成して、DNS名でアクセスできるようにする。
- DNS名でアクセスすると無事つながって、証明書エラーも特になし。
その他
ACIでファイルマウント
- ACIにエフェメラルボリュームを持たせられるのか調べたところ、Azure Files共有をSMB経由でマウントができるとのこと。Azure Container Instances に Azure ファイル共有をマウントする
- ただし、マウントの認証にマネージドIDは使えないので、アクセスキーの発行が必要
- セキュリティを考慮するとローテーションも考える必要がありそう
マルチコンテナのデプロイ
- ローカルにdockerコマンドをインストールしていると、docker-composeコマンドでコンテナグループを作成することも可能
- ただし、一部制限はありそうだが、AzureFile共有や基本的な設定はサポートされている。Azure での Docker コンテナーのデプロイ
まとめ
- Azure Container InstanceとApplication Gatewayを組み合わせれば、シンプルでセキュアなアプリの外部公開が可能
- 今回は個人検証のためなるべくコストを抑えてDNSやサーバ証明書の設定を実施したが、本番環境では、固定IPや正式な証明書の利用など、さらに堅牢な構成を検討する必要がある。
Discussion