Azure Container Appsのすすめ

この記事は[Microsoft Top Partner Engineer's Advent Calender 2023](https://japan.zdnet.com/extra/ms_202311/35211313/) 19日目の記事です。

https://japan.zdnet.com/extra/ms_202311/35211313/

Azure Container Appsを使う機会が最近あったのですが、コンテナを扱うのであればAzure Container Appsが一番いいのでは！？と実際使ってみて感じました。今回はそんなAzure Container Appsを具体例を交えてご紹介したいと思います。

# AzureのコンテナPaaSサービス
Azureで利用可能なコンテナのPaaSサービスは以下があります。
* Azure Container Instances
* Azure Container Apps
* Azure Kubernetes Service
* Azure App Service (Web App for Containers)

Azure Container AppsはAzure Container InstancesとAzure Kubernetes Serviceの中間にあたるようなサービスとなっており、シンプルにコンテナのオーケストレーション環境を作ることができます。Azure Container Appsは2022年5月にGAになったサービスです。

:::note warn
~~2023年12月時点では残念ながら西日本リージョンは非対応です。東日本リージョンでは利用できます。~~
2025/3/13：ついに西日本リージョンでも利用可能となりました！
https://azure.microsoft.com/en-us/updates?id=484299
:::
:::note info
各サービスの違いや使い分けについては以下が参考となります。
[Container Apps と他の Azure コンテナー オプションの比較](https://learn.microsoft.com/ja-jp/azure/container-apps/compare-options)
[Azure コンピューティング サービスを選択する](https://learn.microsoft.com/ja-jp/azure/architecture/guide/technology-choices/compute-decision-tree)
:::

# Azure Container AppsでWordPress + MySQL環境を作ってみる
Azure Container Appsがどのようなサービスか具体的にご紹介するため、WordPressの環境をAzure Container Apps上につくってみました。MySQLはAzure Database for MySQLで構成する方がシンプルで運用もしやすいですが、今回はあえてContainer Apps環境の上にMySQLコンテナを載せてみます。

## 構成
外部からアクセスできるContainer Apps環境を作成し、その環境上にWordPressコンテナとMySQLコンテナをデプロイします。Container Apps環境はコンテナアプリが所属するグループにあたるようなものです。コンテナアプリは必ずいずれかのContainer Apps環境に属します。
※ 下図にLBがありますが、LBはContainer Apps環境を作ると自動的に作成されます。

![99-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/86879a0f-e91d-d4e6-a8ae-f5e307c3de33.png)

## リソースプロバイダーの有効化
作業対象のサブスクリプションで初めてContainer Appsを作成する場合は「Microsoft.App」のリソースプロバイダーを有効にする必要があります。リソース作成時に自動的に必要なリソースプロバイダーを有効化してくれることが多いですが、新しい環境でContainer Appsを構築してみた際、手動で有効化しないとデプロイが進まない事象が発生しました。手動で有効化しておくと確実でしょう。

サブスクリプションの管理画面へ遷移し、「リソースプロバイダー」のメニューから有効化できます。「Registered」になっていなければ、「Microsoft.App」を選択して[登録]をクリックしましょう。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/fc0ee282-ce1d-abcf-d473-2dd9ef8e8a7a.png)


## Cotainer Apps環境の作成
Azure Portalから作成する場合、Container Apps環境単体で作成することができません。最初に作るコンテナアプリと一緒に作成します。

「コンテナーアプリ」の管理画面へ遷移して[＋作成]を選択します。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/593071a4-76e3-9d55-32a9-3e9f636adc2e.png)

コンテナーアプリの作成画面の下方にContainer Apps環境に関する設定箇所があります。作成したいリージョンを選択してから[新規作成]をクリックします。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/4608a4b1-f0b7-7ca9-f674-759e5b536639.png)

Container Apps環境の設定画面へ遷移します。
#### 基本
* **環境名**にはContainer Apps環境名を入力します。
* **環境の種類**は「ワークロードプロファイル」を選択します。ワークロードプロファイルは2023年8月末にGAした比較的新しい機能です。従量課金プランの上限を超えるCPUやメモリを割り当てる必要があるコンテナやGPUを使うコンテナを動かせる専用プランが強調されている機能となりますが、従来よりも強化された従量課金プランも使えるので、これから作る分にはワークロードプロファイル一択でよいのではないかと思います。ワークロードプロファイルについては [こちらの投稿](https://qiita.com/chappy7121/items/773b94072c93c543f3ec) で整理しています。
* **ゾーン冗長**を有効にすると複数の可用性ゾーンに分散してコンテナアプリを展開してくれるようになります。今回はテスト目的なので無効で作ります。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/a7a67434-189d-8e06-6a99-dd5732d28cb9.png)

#### ワークロードプロファイル
ワークロードプロファイルは従量課金プラン（Consumption）を利用するので、追加せずに次へ進みます。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/8beafce3-39d8-71da-470b-d2579b9dbdaf.png)

#### 監視
ログの出力先の指定です。ログは出力しておかないとトラブルが発生した時に確認できなくなるので、基本は出力するようにするべきかと思います。
* **Azureログ分析**は指定のLog Analyticsにログを出力します。今回はこちらを選択します。
* **Azure Monitor**はおなじみの診断設定でログの出力先を指定できるようになります。

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/0c251eec-69d6-5fbd-fd14-cee3bd97aef5.png)

#### ネットワーク
* 自分の仮想ネットワークにContainer Apps環境を配置するかどうかを選択します。
「いいえ」を選択した場合はMicrosoftマネージドなネットワークに配置されます。
自分の仮想ネットワークに接続していないと利用できない機能がいくつかあるので、基本は自分の仮想ネットワークを利用するのがよいでしょう。ワークロードプロファイルの場合、サブネットサイズの最低要件は/27ですが、動作させるコンテナアプリの数に応じてサイズを検討しましょう。

* 仮想IPの設定項目は外部公開するか、内部公開するかの選択です。今回は外部からアクセスさせたいので、「外部」を選びます。
なお、1つのContainer Apps環境で外部公開・内部公開の両方を同時に設定することはできません。

* インフラストラクチャリソースグループの項目は、Container Apps環境を作ると自動的に作成されるリソースグループの名前を指定します。指定しない場合は「ME_」から始まるリソースグループができあがります。このリソースグループの中にContainer Apps環境が利用するLoad BalancerとそのパブリックIPリソースが作成されます。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/654ff91a-8552-bbd8-4a4b-d5690cf05620.png)

Container Appsの設定項目は以上です。
[作成]ボタンを押すとコンテナアプリの作成画面に戻ります。

## WordPressコンテナアプリの作成
Container Apps環境の設定に引き続き、WordPressコンテナのデプロイ設定をおこなっていきます。

#### 基本
デプロイ先のリソースグループを指定し、作成するコンテナアプリの名前を入力します。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/82dbfcb5-3993-6964-3e3b-950694d49cb8.png)

#### コンテナー
コンテナのデプロイ設定です。
「クイックスタートイメージを使用する」にチェックが入っていると、いわゆるhello worldなコンテナがデプロイされるので、チェックを外します。

:::note info
ContainerAppsがどんなものか、設定項目は何があるのかを見てみる用途にはチェックひとつでContainer Apps環境を作れるこのクイックスタートイメージは便利です。
:::

Docker Hubで公開されているWordPressコンテナイメージをデプロイするので、以下のように設定します。

| 項目| 設定値 |
|:--|:--|
| イメージのソース | Docker Hub または その他のレジストリ  |
| イメージの種類  | パブリック |
| レジストリログインサーバー |  docker.io |
| イメージとタグ | wordpress:latest |

コンテナリソースの割り当ては既定値のままとします。

:::note info
従量課金プランの場合、利用できるCPU/メモリの値の組み合わせが決まっています。組み合わせ表は[こちらのページ](https://learn.microsoft.com/ja-jp/azure/container-apps/containers)にあります。
:::

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/5904b0eb-4f82-5bbc-6916-648dceb00542.png)

#### Bindings
何も変更せず、次へ進みます。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/c18ddc1c-10ab-e68e-25ff-7f85db9a64bf.png)

#### イングレス
コンテナへのアクセス設定です。
* WordPressコンテナにアクセスできる必要があるので、イングレスは「有効」にします。
* 外部からアクセスできる必要があるので、イングレストラフィックは「どこからでもトラフィックを受け入れます」を選択します。
* WordPressコンテナにはHTTPアクセスするので、イングレスタイプは「HTTP」を選択します。

:::note info
HTTPを選択した場合は外部公開されるポートは80か443になります。TCPを選択した場合は外部公開ポートに任意のポートを指定できますが、80または443は指定できないようになっています。HTTPとTCPで動作の挙動/仕様が異なるようなので、コンテナの実装によってはここがハマるポイントになるかなと思います。
参考：[Azure Container Apps でのイングレス - プロトコルの種類](https://learn.microsoft.com/ja-jp/azure/container-apps/ingress-overview#protocol-types)
:::

* クライアント証明書認証は使わないので「無視」を選択します。
* テスト目的なのでセキュリティで保護されていない接続は許可します。
* ターゲットポートは80です。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/95afbe30-8ac7-c649-047c-e1dfa2fa4c29.png)

タグは特に設定しません。
設定が完了したのでデプロイします。

### デプロイ後の動作確認
デプロイされたコンテナアプリの「概要」ページへアクセスします。
概要右側にコンテナにアクセスするためのURLが表示されているので、クリックします。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/4c183e92-745b-cde7-bd48-d5d9212f2779.png)

無事にWordPressの画面が出てきました。
※ httpsからhttpに変更してアクセスしないと画面表示されるものの、レイアウトが崩壊しました。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/9caff829-2db1-21fc-e2b2-e9ed1af0b11f.png)

## MySQLコンテナアプリの作成
続いてMySQLのコンテナを作成します。
WordPressコンテナ同様、コンテナーアプリの管理画面から新規作成していきます。

#### 基本
リソースグループ、コンテナアプリ名を指定します。
Container Apps環境は作成済みのものを選択します。

#### コンテナー
コンテナーの設定は以下のようにします。

| 項目| 設定値 |
|:--|:--|
| イメージのソース | Docker Hub または その他のレジストリ  |
| イメージの種類  | パブリック |
| レジストリログインサーバー |  docker.io |
| イメージとタグ | mysql:latest |

コンテナーリソースの割り当ては既定値のままとします。

MySQLコンテナの起動時にWordPress用のDBと接続用ユーザーを自動生成させるため、以下の環境変数を設定しておきます。
| 項目| 設定値 |
|:--|:--|
| MYSQL_ROOT_PASSWORD | rootユーザのパスワードを指定  |
| MYSQL_DATABASE  | wordpressdb |
| MYSQL_USER |  wordpressuser |
| MYSQL_PASSWORD | wordpressuserのパスワードを指定 |

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/f3fb7670-60d9-5b97-10cf-c80efb47d8ea.png)

#### Bindings
設定は変更せず、次へ進みます。

#### イングレス
* WordPressコンテナからアクセスできるようにイングレスは有効にします。
* 外部からMySQLコンテナに直接アクセスさせたくないので、イングレストラフィックは「Container Apps環境に限定」を選択します。これを選択するとコンテナ同士でしか通信できなくなります。今回はテスト目的なのでMySQLへの管理アクセスは無視します。
* イングレスタイプはTCPを選択します。
* ターゲットポート、公開されたポートともにMySQLの既定ポートである3306を指定します。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/b0618120-ec61-5d52-8a66-c7c92a3ac1f4.png)

タグは特に設定しません。
設定が完了したのでデプロイします。

## WordPressコンテナからMySQLへの接続設定
MySQLコンテナができたので、WordPressコンテナからMySQLへの接続設定をおこないます。

接続に利用するパスワードのような機密情報はシークレットに登録するのが望ましいです。シークレットの登録方法はいろいろありますが、今回はコンテナアプリに付随しているシークレット登録機能を利用します。

WordPressコンテナの管理画面を開き、[シークレット]のメニュー選択し、[＋追加]をクリックします。
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/2b069053-81e9-b34d-8f06-f3b31d50efb8.png)

シークレットの登録画面が出てくるので、必要な情報を入力します。今回は簡易な「Container Appsシークレット」を使います。なお、KeyVault参照の方を使うとマネージドID認証を使ってKeyVaultに保存したシークレットを参照できます。
今回は以下の2つの情報を登録します。
| キー | 値 |
|:--|:--|
| wordpress-db-user | wordpressuser |
| wordpress-db-password | MYSQL_PASSWORDで指定したパスワード |

![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/9589a1dc-eff0-a024-34b2-b7f38ca8cd7e.png)

登録されました。
![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/e5bf062d-520f-c6c1-3c24-3fce38a47573.png)

WordPressコンテナの環境変数にMySQLへの接続情報を追加します。
コンテナの設定を変更する場合、「リビジョン」を選択し、「＋新しいリビジョンを作成」を選びます。コンテナの設定を変えたいだけなのに、リビジョンを作成？？と最初は戸惑いましたが、Container Appsでは設定を変更してコンテナをデプロイしなおす際に新たなリビジョンを作る仕様になっています。リビジョン＝コンテナのデプロイ設定定義一式、という感じです。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/d9455b23-01a8-d7f0-8d01-49c5553003d4.png)

コンテナの設定を変更する場合、**コンテナー**タブの対象コンテナイメージの編集を選択します。今回は環境変数を追加するので、下の方にある**環境変数**のところに設定を追加します。
追加する環境変数は以下です。
| 名前 | ソース | 値 |
|:--|:--|:--|
| WORDPRESS_DB_HOST | 手動エントリ | MySQLコンテナアプリ名(今回の例だとca-mysql) |
| WORDPRESS_DB_USER | シークレットの参照 | wordpress-db-user |
| WORDPRESS_DB_PASSWORD | シークレットの参照 | wordpress-db-password |
| WORDPRESS_DB_NAME | 手動エントリ | wordpressdb |

![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/4a21999c-f815-a905-d599-6db459511643.png)

追加が完了したら、[保存]を選択し、[作成]を選択します。
新しいリビジョンが作成され、コンテナが自動的に置き換えられます。

![23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/28c36ee7-fe12-4211-ba2f-abf9286dbdcb.png)

しばらくしたら新しくデプロイしたコンテナが実行中になるので、WordPressコンテナへアクセスしてみます。接続設定前は「DBを設定しましょう」といった内容の画面が出てきていましたが、サイトやWordPress管理ユーザーの設定画面が出てきました。MySQLと正しく接続できているようです。

![27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/03897438-8b0f-d9b4-4827-774f180aaea1.png)

WordPressの設定をおこなってWordPressにログインしてみると、正常に動作していることが確認できました。WordPressコンテナやMySQLコンテナのデプロイ方法や設定方法をネットで調べながら作業してみて、ここまで1時間ちょっとでできました。Container Appsでコンテナ、お手軽ですね！
![30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/7a9597ef-f156-36c7-c5fe-4d840fff3e8a.png)

この状態だとMySQLコンテナは永続化の設定が入っていないので、MySQLコンテナを再起動するとデータが消失します。それではWordPressとしては使い物にならないので、永続化の設定も試したみたのですが、ボリュームマウントに使うAzure Filesの制限事項にMySQLコンテナが抵触して、正常に動作しませんでした・・・。永続化の設定は別の投稿で記載したいと思います。

# まとめ
私自身コンテナはそこまで詳しくないのですが、Azure Container Appsを使うことでコンテナ環境を簡単に作ることができました。

今回の例では使っていませんが、Azure Container Appsには他にも以下のような機能があります。
* スケーリング
* 正常性プローブ（コンテナの起動チェック、動作中の正常性確認）
* 複数リビジョンモード（異なる設定のコンテナを同時展開できる機能。A/Bテストやブルーグリーンデプロイ、といった使い方ができます）
* サイドカーコンテナ、Initコンテナ
* Dapr

使える機能は徐々に追加されており、今後ますます使いやすいサービスに発展していくことが期待できます。Azureでコンテナを扱う、という場合はぜひAzure Container Appsの利用を検討してみてください。