Azure Container Apps (ACA) に Java JAX-RS カスタムコンテナイメージをデプロイする
こんにちは、@studio_meowtoon です。今回は、Azure Container Apps 環境で、Java JAX-RS Web アプリケーションをコンテナとして起動する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
Microsoft Azure Container Apps (ACA) に Java JAX-RS Web アプリケーションのカスタムコンテナイメージをデプロイします。
WAR ファイル形式のアプリをコンテナとして起動
要素 | 概要 |
---|---|
terminal | ターミナル |
Azure | クラウド環境 |
Azure Container Apps | コンテナ実行環境 |
app-hello-jaxrs | カスタムコンテナ |
JVM | Java 実行環境 |
jetty | Web サーバー |
ROOT.war | Java アプリケーション |
この記事では、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
Azure CLI ※ こちらの関連記事からインストール方法をご確認いただけます
$ az --version
azure-cli 2.45.0
core 2.45.0
telemetry 1.0.8
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
作成する Web アプリケーションの仕様
No | エンドポイント | HTTPメソッド | MIME タイプ |
---|---|---|---|
1 | /api/data | GET | application/json |
Hello World を表示する手順
Java JAX-RS Web サービスの作成
こちらの関連記事で手順がご確認いただけます。
ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。
プロジェクトフォルダに移動
プロジェクトフォルダに移動します。
※ ~/tmp/hello-jaxrs をプロジェクトフォルダとします。
$ cd ~/tmp/hello-jaxrs
コンテナイメージの確認
Docker デーモンを起動します。
$ sudo service docker start
* Starting Docker: docker [ OK ]
コンテナイメージを確認します。
$ docker images | grep app-hello-jaxrs
app-hello-jaxrs latest a810eb763163 About an hour ago 185MB
Docker Hub にコンテナイメージを登録
Docker Hub にログインします。
$ docker login
Login Succeeded
コンテナイメージにタグを付けます。
ここで $USER という埋め込み変数は、Ubuntu のシェル変数 USER のことです。つまり、カスタムコンテナイメージを Docker Hub にプッシュする際に指定するアカウント名と、Ubuntu のユーザー名を同じにすると、イメージの取り扱いが簡単になります。ただし、この方法は検証用途に限定されます。
$ docker tag app-hello-jaxrs:latest \
$USER/app-hello-jaxrs:latest
Docker Hub にコンテナイメージをプュシュします。
$ docker push $USER/app-hello-jaxrs:latest
ここまでの手順で、Docker Hub に $USER/app-hello-jaxrs:latest というカスタムコンテナイメージをプッシュすることができました。
シェル変数の作成
シェル変数として、Ubuntu に以下の値を作成します。状況により、コンテナ アプリの名前を変える必要があります。
location_name=japaneast
resource_group_name=rg-hello
containerapp_env_name=cae-hello
containerapp_name=ca-hello-jaxrs
container_image_name=app-hello-jaxrs:latest
Azure 環境にサインイン
こちらの関連記事の続きから手順を説明する記事となります。
Azure CLI でログインします。
$ az login
Azure 環境
リソースグループ
リソースグループを作成します。
$ az group create \
--name $resource_group_name \
--location $location_name
コンテナ アプリ環境
コンテナ アプリ環境を作成します。
※ Kubernetes 基盤の環境がベースとなっているので少し時間がかかります。
$ az containerapp env create \
--resource-group $resource_group_name \
--name $containerapp_env_name \
--location $location_name
コンテナ アプリ
コンテナ アプリの作成とデプロイを行います。
$ 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
--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-jaxrs.nicehill-fafa9131.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 を押します。
$ pwd
/var/lib/jetty
$ cd webapps
$ ls -lah
total 6M
drwxr-xr-x 1 jetty jetty 4.0K Aug 1 06:59 .
drwxr-sr-x 1 jetty jetty 4.0K Aug 1 08:47 ..
-rw-r--r-- 1 root root 6.2M Aug 1 06:05 ROOT.war
top コマンドで状況を確認します。
Mem: 11319464K used, 5055120K free, 9384K shrd, 176248K buff, 8251760K cached
CPU: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
Load average: 0.69 0.59 0.36 2/1184 57
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
1 0 jetty S 1712m 10% 3 0% /opt/java/openjdk/bin/java -Djetty.home=/usr/local/jetty -Djetty.base=/var/lib/jetty --class-path /var/lib/jet
50 0 jetty S 1672 0% 3 0% sh
57 50 jetty R 1600 0% 1 0% top
top コマンドで cpu を表示した状況です。
Mem: 11328940K used, 5045644K free, 9384K shrd, 176260K buff, 8252424K cached
CPU0: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
CPU1: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
CPU2: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
CPU3: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
Load average: 0.54 0.56 0.36 3/1184 57
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
1 0 jetty S 1712m 10% 3 0% /opt/java/openjdk/bin/java -Djetty.home=/usr/local/jetty -Djetty.base=/var/lib/jetty --class-path /var/lib/jet
50 0 jetty S 1672 0% 3 0% sh
57 50 jetty R 1604 0% 0 0% top
コンテナの情報を表示してみます。
$ cat /etc/*-release
3.18.2
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.18.2
PRETTY_NAME="Alpine Linux v3.18"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
このコンテナは Alpine Linux をベースに作成されています。つまり、Linux と同じように扱うことができます。
パフォーマンスの計測
コンテナ 環境
項目 | バージョン |
---|---|
Base Image | Alpine Linux v3.18 |
JVM | openjdk version "11.0.20" 2023-07-18 |
Jetty | 10.0.15 |
Jersey (JAX-RS) | 2.39 |
コンテナ リソースの割り当て
項目 | 設定値 |
---|---|
CPU コアの数 | 0.5 |
メモリ サイズ(Gi) | 1Gi |
リクエスト処理完了までの所要時間
No | 状況 | リクエスト所要時間(秒) |
---|---|---|
1 | デプロイ直後 | 2.695762秒 |
2 | 連続して2回目 | 0.189642秒 |
3 | さらに3回目 | 0.173197秒 |
4 | スケールゼロ回復直後 | 15.125714秒 |
5 | 連続して2回目 | 0.176384秒 |
6 | さらに3回目 | 0.195233秒 |
ログ ストリーム:起動時間を表示するログ
状況 | アプリ起動時間(秒) |
---|---|
デプロイ直後 | 6.293秒 |
スケールゼロ回復直後 | 6.412秒 |
2023-08-02T05:11:41.698021210Z 2023-08-02 05:11:41.697:INFO :oejs.Server:main: Started Server@1af2d44a{STARTING}[10.0.15,sto=5000] @6293ms
2023-08-02T05:21:49.498379308Z 2023-08-02 05:21:49.498:INFO :oejs.Server:main: Started Server@1af2d44a{STARTING}[10.0.15,sto=5000] @6412ms
メトリック:CPU使用率
状況 | CPU使用率 |
---|---|
デプロイ後:ピーク値 | 0.36コア |
スケールゼロ回復後:ピーク値 | 0.25コア |
メトリック:メモリ使用量
状況 | メモリ使用量 |
---|---|
デプロイ後:ピーク値 | 98.6MB |
スケールゼロ回復後:ピーク値 | 99.8MB |
アプリケーションがスケールゼロ状態から再びアクティブになった後、リクエストを処理するまでにかなり時間がかかる状況がわかります。ただしスケールゼロ状態は、--min-replicas 1: と設定することにより回避可能です。
まとめ
Azure Container Apps 環境で、Dockerfile からビルドした Java JAX-RS Web サービスのカスタムコンテナイメージを起動することができました。
Maven、Docker、Azure CLI を使って、Java JAX-RS アプリの開発からコンテナイメージの作成、Azure 環境へのデプロイまで、すべてをターミナルから行うことができます。このように、クラウドでのシステム開発に必要なスキルや理解を深めることができます。初めての人でも簡単に手順を追うことができるので、ぜひ挑戦してみてください。
どうでしたか? 検証目的として、Azure Container Apps 環境で、Java JAX-RS Web アプリケーションをコンテナとして手軽に起動することができます。ぜひお試しください。今後も Azure の開発環境などを紹介していきますので、ぜひお楽しみにしてください。
推奨コンテンツ
関連記事