Azure Container Apps (ACA) に Spring Boot Webサービスをデプロイする (Docker Hub カスタムコンテナイメージ)
こんにちは、@studio_meowtoon です。今回は、Azure Container Apps 環境で Spring Boot Web アプリケーションをコンテナとして起動する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
Microsoft Azure Container Apps (ACA) に Spring Boot Web アプリケーションのカスタムコンテナイメージをデプロイします。
JAR ファイル形式のアプリをコンテナとして起動
要素 | 概要 |
---|---|
terminal | ターミナル |
Azure | クラウド環境 |
Azure Container Apps | コンテナ実行環境 |
app-hello-spring-boot | カスタムコンテナ |
JVM | Java 実行環境 |
app.jar | Java アプリケーション |
tomcat | Web サーバー |
この記事では、Docker Hub に公開するパブリックアクセス可能なカスタムコンテナイメージを使用しています。実際のシステム開発では、どのレジストリからコンテナイメージを取得するかは異なる場合がありますので、適宜ご確認ください。
技術トピック
Microsoft Azure Container Apps (ACA) とは?
こちらを展開してご覧いただけます。
Microsoft Azure Container Apps (ACA)
Azure 上で実行されるコンテナアプリケーションのプラットフォームです。
ACA は、Docker コンテナと Kubernetes クラスタの環境をサポートしており、開発者はコンテナイメージを作成して、Kubernetes リソースとしてデプロイすることができます。また、カスタムドメイン名をサポートしているため、自社のブランドを維持することができます。
メリット | 説明 |
---|---|
簡単なセットアップとデプロイ | ACA は、簡単なユーザーインターフェイスを備えており、数回のクリックでコンテナアプリケーションをセットアップしてデプロイすることができます。 |
スケーラビリティ | ACA は、自動的にスケーリングを行うことができます。アプリケーションに必要なリソースが増加した場合、ACA は自動的に必要なリソースを追加して処理を分散します。 |
セキュリティ | ACA は、コンテナアプリケーションを実行する際に必要なセキュリティ機能を提供しています。例えば Azure Active Directory との統合や、コンテナレベルでのアクセス制御などがあります。 |
コスト効率 | ACA は、必要なときに必要なリソースを追加するため、無駄なリソースの使用を最小限に抑えることができます。また、必要なリソースに対してのみ支払いを行うため、コスト効率的に利用することができます。 |
開発環境
- Windows 11 Home 22H2 を使用しています。
WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。
WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Java JDK ※ こちらの関連記事からインストール方法をご確認いただけます
$ java -version
openjdk version "11.0.18" 2023-01-17
OpenJDK Runtime Environment (build 11.0.18+10-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.18+10-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
Maven ※ こちらの関連記事からインストール方法をご確認いただけます
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.18, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker --version
Docker version 23.0.1, build a5ee5b1
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
作成する Web アプリケーションの仕様
No | エンドポイント | HTTPメソッド | MIME タイプ |
---|---|---|---|
1 | /api/data | GET | application/json |
Hello World を表示する手順
Spring Boot Web サービスの作成
こちらの関連記事で手順がご確認いただけます。
ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。
プロジェクトフォルダに移動
プロジェクトフォルダに移動します。
※ ~/tmp/hello-spring-boot をプロジェクトフォルダとします。
$ cd ~/tmp/hello-spring-boot
コンテナイメージの確認
Docker デーモンを起動します。
$ sudo service docker start
* Starting Docker: docker [ OK ]
コンテナイメージを確認します。
$ docker images | grep app-hello-spring-boot
app-hello-spring-boot latest 39115028afa6 12 seconds ago 390MB
Docker Hub にコンテナイメージを登録
Docker Hub のアカウントを作成します。
こちらを展開してご覧いただけます。
Docker Hub は、コンテナの共有、保存、および管理のためのクラウドベースのレジストリです。Docker Hub には、コミュニティによって作成された公式およびコミュニティによるイメージが格納されています。また、ユーザーがカスタムコンテナイメージをアップロードおよび共有することもできます。
Docker Hub にログインします。
$ docker login
Login Succeeded
コンテナイメージにタグを付けます。
ここで $USER という埋め込み変数は、Ubuntu のシェル変数 USER のことです。つまり、カスタムコンテナイメージを Docker Hub にプッシュする際に指定するアカウント名と、Ubuntu のユーザー名を同じにすると、イメージの取り扱いが簡単になります。ただし、この方法は検証用途に限定されます。
$ docker tag app-hello-spring-boot:latest \
$USER/app-hello-spring-boot:latest
説明を開きます。
docker tag コマンドは、ローカルに保存されているコンテナイメージに、指定したタグを付けることで、コンテナイメージをリネームすることができます。
この例では、app-hello-spring-boot という名前のコンテナイメージに、user/app-hello-spring-boot:latest というタグを付けています。ここで user は、Docker Hub 上のユーザー名を表します。タグには、コロン : 以降にバージョンなどの情報を含めることができますが、ここでは latest を指定しているため、最新バージョンを表しています。
Docker Hub にコンテナイメージをプュシュします。
$ docker push $USER/app-hello-spring-boot:latest
説明を開きます。
docker push コマンドは、コンテナイメージを Docker Hub のリポジトリにプッシュするために使用されます。user/app-hello-spring-boot はプッシュするイメージの名前とタグを指定し、latest はイメージのバージョンを指定しています。
これにより、Docker Hub 上に user というユーザー名のリポジトリが作成され、その中に app-hello-spring-boot という名前のコンテナイメージがアップロードされます。
ここまでの手順で、Docker Hub に $USER/app-hello-spring-boot:latest というカスタムコンテナイメージをプッシュすることができました。
シェル変数の作成
シェル変数として、Ubuntu に以下の値を作成します。状況により、コンテナ アプリの名前を変える必要があります。
location_name=japaneast
resource_group_name=rg-hello
containerapp_env_name=cae-hello
containerapp_name=ca-hello-spring-boot
container_image_name=app-hello-spring-boot:latest
Azure 環境にサインイン
こちらの関連記事の続きから手順を説明する記事となります。
Azure CLI でログインします。
$ az login
Azure 環境
リソースグループ
リソースグループを作成します。
$ az group create \
--name $resource_group_name \
--location $location_name
説明を開きます。
このコマンドは、Azure CLI を使用して Azure のリソースグループを作成しています。
コマンド | 内容 |
---|---|
az group create | Azure のリソースグループを作成するためのコマンドです。 |
オプション | 値 | 内容 |
---|---|---|
--name | rg-hello | リソースグループの名前を指定します。 |
--location | japaneast | リソースグループを作成する場所を japaneast に指定しています。 japaneast は Azure の日本東部地域を指します。 |
コンテナ アプリ環境
拡張機能をインストールします。
※ 初回のみ必要となります。
手順を表示します。
拡張機能
拡張機能をインストールします。
$ az extension add --name containerapp --upgrade
Microsoft.App 名前空間を登録します。
$ az provider register --namespace Microsoft.App
Microsoft.OperationalInsights プロバイダーを登録します。
$ az provider register --namespace Microsoft.OperationalInsights
コンテナ アプリ環境を作成します。
※ Kubernetes 基盤の環境がベースとなっているので少し時間がかかります。
$ az containerapp env create \
--resource-group $resource_group_name \
--name $containerapp_env_name \
--location $location_name
説明を開きます。
このコマンドは、Azure Container Apps 環境を作成しています。
コマンド | 内容 |
---|---|
az containerapp env create | Container Apps 環境を作成するためのコマンドです。 |
オプション | 値 | 内容 |
---|---|---|
--resource-group | rg-hello | アプリケーションをデプロイするリソースグループの名前です。 |
--name | cae-hello | Container Apps 環境の名前です。 |
--location | japaneast | リソースグループを作成する場所です。japaneast は Azure の日本東部地域を指します。 |
コンテナ アプリ環境を削除する場合は以下のコマンドを実行します。
$ az containerapp env delete \
--resource-group $resource_group_name \
--name $containerapp_env_name
コンテナ アプリ
コンテナ アプリの作成とデプロイを行います。
※ $USER の部分はご自身のコンテナリポジトリに読み替えて下さい。
$ az containerapp create \
--resource-group $resource_group_name \
--environment $containerapp_env_name \
--name $containerapp_name \
--image $USER/$container_image_name \
--target-port 8080 \
--ingress 'external' \
--min-replicas 0
説明を開きます。
このコマンドは、Azure Container App インスタンスを作成するためのコマンドです。以下が各オプションが実行する内容です。
コマンド | 内容 |
---|---|
az containerapp create | Container Apps を作成する為のコマンドです。 |
オプション | 値 | 内容 |
---|---|---|
--resource-group | rg-hello | デプロイするリソースが属するリソースグループの名前を指定します。 |
--environment | cae-hello | Container Apps 環境の名前を指定します。 |
--name | ca-hello-spring-boot | Container Apps の名前を指定します。 |
--image | $USER/app-hello-spring-boot:latest | 実行するコンテナイメージの名前を指定します。ここでは、前述の手順で Docker Hub にプッシュしたイメージ名を使用しています。 |
--target-port | 8080 | コンテナが公開するポートを指定します。ここでは、Spring Boot アプリケーションがポート 8080 で公開されているため、8080 を指定しています。 |
--ingress | 'external' | コンテナを外部からアクセスできるようにするためのイングレス設定を指定します。ここでは、外部からのアクセスを許可する 'external' を指定しています。 |
--min-replicas | 0 | 最小レプリカ数を指定します。ここでは、最小レプリカ数を 0 に設定しています。 |
--min-replicas 0: と設定することにより、アクセスが300秒間ない場合にアプリケーションがスケールゼロ状態に移行します。
コンテナ アプリを削除する場合は以下のコマンドを実行します。
$ az containerapp delete \
--resource-group $resource_group_name \
--name $containerapp_name
コンテナ アプリの FQDN をシェル変数 containerapp_fqdn として取得します。
$ containerapp_fqdn=$(az containerapp show \
--resource-group $resource_group_name \
--name $containerapp_name \
--query 'properties.configuration.ingress.fqdn' \
--output tsv)
コンテナ アプリの FQDN を確認します。
$ set | grep containerapp_fqdn
containerapp_fqdn=ca-hello-spring-boot.wonderfulgrass-e3276e77.japaneast.awsomecontainerapps.io
Azure Portal の確認
ここまでの作業で、Azure Container Apps にコンテナ アプリをデプロイすることができました。
コンテナ動作の確認
ターミナルから curl コマンドで確認します。
$ curl https://$containerapp_fqdn/api/data -w '\ntime_total: %{time_total}s\n'
出力(※ time_total は省略)
{"message":"Hello World!"}
ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。
コンテナに接続
$ az containerapp exec \
--resource-group $resource_group_name \
--name $containerapp_name
コンテナに接続後にディレクトリを確認します。
※ コンテナから出るときは ctrl + D を押します。
az containerapp exec コマンドは、Azure Container Apps 内のコンテナ対して対話型シェルを実行するために使用されます。
# pwd
/app
# ls -lah
total 17M
drwxr-xr-x 1 root root 4.0K Aug 2 00:00 .
drwxr-xr-x 1 root root 4.0K Aug 2 01:22 ..
-rw-r--r-- 1 root root 17M Aug 1 23:46 app.jar
top コマンドで状況を確認します。
top - 01:24:20 up 8:54, 0 users, load average: 0.14, 0.22, 0.18
Tasks: 3 total, 1 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.0 us, 0.8 sy, 0.0 ni, 96.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15990.8 total, 4770.9 free, 2144.2 used, 9075.8 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 13491.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 3518000 129108 20636 S 0.0 0.8 0:05.56 java
33 root 20 0 2616 528 464 S 0.0 0.0 0:00.00 sh
40 root 20 0 9080 3692 3180 R 0.0 0.0 0:00.00 top
top コマンドで cpu を表示した状況です。
top - 01:24:28 up 8:54, 0 users, load average: 0.13, 0.22, 0.18
Tasks: 3 total, 1 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu0 : 3.0 us, 0.7 sy, 0.0 ni, 96.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 2.0 us, 0.7 sy, 0.0 ni, 97.0 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
%Cpu2 : 3.3 us, 0.7 sy, 0.0 ni, 96.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 1.7 us, 1.0 sy, 0.0 ni, 97.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15990.8 total, 4765.2 free, 2149.5 used, 9076.0 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 13485.6 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 3518000 129108 20636 S 0.0 0.8 0:05.57 java
33 root 20 0 2616 528 464 S 0.0 0.0 0:00.00 sh
40 root 20 0 9080 3692 3180 R 0.0 0.0 0:00.00 top
コンテナの情報を表示してみます。
# cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
このコンテナは Ubuntu をベースに作成されています。つまり、Ubuntu と同じように扱うことができます。
パフォーマンスの計測
コンテナ 環境
項目 | バージョン |
---|---|
Base Image | Ubuntu 20.04.6 LTS |
JVM | openjdk version "11.0.18" 2023-01-17 |
Spring Boot | v2.7.8 |
コンテナ リソースの割り当て
項目 | 設定値 |
---|---|
CPU コアの数 | 0.5 |
メモリ サイズ(Gi) | 1Gi |
リクエスト処理完了までの所要時間
No | 状況 | リクエスト所要時間(秒) |
---|---|---|
1 | デプロイ直後 | 0.359941秒 |
2 | 連続して2回目 | 0.198545秒 |
3 | さらに3回目 | 0.215914秒 |
4 | スケールゼロ回復直後 | 15.883182秒 |
5 | 連続して2回目 | 0.193921秒 |
6 | さらに3回目 | 0.190443秒 |
ログ ストリーム:起動時間を表示するログ
状況 | アプリ起動時間(秒) |
---|---|
デプロイ直後 | 8.001秒 |
スケールゼロ回復直後 | 8.197秒 |
2023-08-02T00:57:26.494853482Z 2023-08-02 00:57:26.494 INFO 1 --- [ main] com.example.springboot.Application : Started Application in 8.001 seconds (JVM running for 9.591)
2023-08-02T01:10:53.504096753Z 2023-08-02 01:10:53.503 INFO 1 --- [ main] com.example.springboot.Application : Started Application in 8.197 seconds (JVM running for 9.837)
メトリック:CPU使用率
状況 | CPU使用率 |
---|---|
デプロイ後:ピーク値 | 0.0953コア |
スケールゼロ回復後:ピーク値 | 0.08コア |
メトリック:メモリ使用量
状況 | メモリ使用量 |
---|---|
デプロイ後:ピーク値 | 115.9MB |
スケールゼロ回復後:ピーク値 | 118.3MB |
アプリケーションがスケールゼロ状態から再びアクティブになった後、リクエストを処理するまでにかなり時間がかかる状況がわかります。ただしスケールゼロ状態は、--min-replicas 1: と設定することにより回避可能です。
まとめ
Azure Container Apps 環境で、Dockerfile からビルドした Spring Boot Web サービスのカスタムコンテナイメージを起動することができました。
Maven、Docker、Azure CLI を使って、Spring Boot アプリの開発からコンテナイメージの作成、Azure 環境へのデプロイまで、すべてをターミナルから行うことができます。このように、クラウドでのシステム開発に必要なスキルや理解を深めることができます。初めての人でも簡単に手順を追うことができるので、ぜひ挑戦してみてください。
どうでしたか? 検証目的として、WSL Ubuntu で、Spring Boot Web アプリケーションを Azure Container Apps 環境でコンテナとして手軽に起動することができます。ぜひお試しください。今後も Azure の開発環境などを紹介していきますので、ぜひお楽しみにしてください。
比較してみよう
今回と同じ仕様を実装する記事がご確認いただけます。