🔖

ACIをHTTPSで外部公開できるのか調べてみた

2025/01/28に公開

ACIでアプリを外部公開する

概要

最近Azureでコンテナを扱う機会があり、Azure Container Instance(ACI)が結構シンプルで扱いやすいと感じたのだが、
そういえばVNETに統合して配置したACIを外部公開するときってどういう構成をとるのがいいのか、あまり記事がなかったので実際に試してみた。

構成

以下のような構成が実際にとれるのか試してみた。何点か補足する。

  • DBと接続することを考えて、ACIは用意したVNET上(プライベート)にデプロイする。
  • ACI自体にHTTPSで公開する設定がないため、Application Gatewayを全段に配置。
  • 個人環境での検証のため、料金は最小限にすべくドメインとサーバ証明書は以下のように用意
    • ドメインはお名前.comで無料のドメインを取得し、サブドメインをAzure DNSに委任
    • サーバ証明書をZeroSSLで無料のサーバ証明書を発行
      alt text

手順

ドメインとサーバ証明書

ドメインの取得

お名前.comからドメインを取得する手順は割愛

サブドメイン委任

  1. サブドメインをAzure DNSで作成して、払いだされたNSレコードに設定されているAzureのDNSサーバをメモする。
  2. メモしたAzure DNSサーバを、お名前.comで取得したドメインで、サブドメインのNSレコードに設定する。
    最大3日かかると記載があったが、設定してから5分もしないうちに設定完了のメール通知が来た。

alt text

サーバ証明書の取得

  • ブラウザ上でサーバ証明書を簡単に発行できるため、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用のサブネットを用意して、用意したサブネットを選択
    alt text

  • パブリックの静的IPアドレスを作成
    alt text

  • バックエンドには、ACIで割り当てられたプライベートIPを設定
    alt text

  • プロトコルをHTTPSにして、変換したPFX形式のサーバ証明書をアップロード
    alt text

  • バックエンドはHTTPプロトコル
    alt text

  • バックエンドターゲットに設定したバックエンドを指定
    alt text

NSG

  • このままだと世界中のどこからでもアクセスできてしまうので、NSGを使ってIP制限をする。

  • 65200-65535ポートはApplication Gatewayで必要なポートのため、インバウンドルールで開ける必要がある。

    • ソースはAnyで開けるのではなく、ラベルでGatewayManagerを選択する。
      alt text
  • NSGをApplication Gatewayのサブネットに紐づけることで、Iトラフィックを制御。
    alt text

アクセス

  • Application Gatewayに紐づけたパブリックIPアドレスでDNSのAレコードを作成して、DNS名でアクセスできるようにする。

alt text

  • DNS名でアクセスすると無事つながって、証明書エラーも特になし。

alt text

その他

ACIでファイルマウント

  • ACIにエフェメラルボリュームを持たせられるのか調べたところ、Azure Files共有をSMB経由でマウントができるとのこと。Azure Container Instances に Azure ファイル共有をマウントする
    • ただし、マウントの認証にマネージドIDは使えないので、アクセスキーの発行が必要
    • セキュリティを考慮するとローテーションも考える必要がありそう

マルチコンテナのデプロイ

  • ローカルにdockerコマンドをインストールしていると、docker-composeコマンドでコンテナグループを作成することも可能

まとめ

  • Azure Container InstanceとApplication Gatewayを組み合わせれば、シンプルでセキュアなアプリの外部公開が可能
  • 今回は個人検証のためなるべくコストを抑えてDNSやサーバ証明書の設定を実施したが、本番環境では、固定IPや正式な証明書の利用など、さらに堅牢な構成を検討する必要がある。

Discussion