4
1

Azure Container Apps (ACA) に Spring Boot Webサービスをデプロイする (Docker Hub カスタムコンテナイメージ)

Last updated at Posted at 2023-03-06

Azure Container Apps (ACA) に Spring Boot Webサービスをデプロイする (Docker Hub カスタムコンテナイメージ)

こんにちは、@studio_meowtoon です。今回は、Azure Container Apps 環境で Spring Boot Web アプリケーションをコンテナとして起動する方法を紹介します。
spring-boot_on_azure-container-apps.png

目的

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 のアカウントを作成します。

こちらを展開してご覧いただけます。

https://hub.docker.com/signup

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 環境

リソースグループ

リソースグループを作成します。

Microsoft.Resources/resourceGroups
$ 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 基盤の環境がベースとなっているので少し時間がかかります。

Microsoft.App/managedEnvironments
$ 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 の部分はご自身のコンテナリポジトリに読み替えて下さい。

Microsoft.App/containerApps
$ 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 の確認

image.png
image.png

ここまでの作業で、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 サービスのカスタムコンテナイメージを起動することができました。

MavenDockerAzure CLI を使って、Spring Boot アプリの開発からコンテナイメージの作成、Azure 環境へのデプロイまで、すべてをターミナルから行うことができます。このように、クラウドでのシステム開発に必要なスキルや理解を深めることができます。初めての人でも簡単に手順を追うことができるので、ぜひ挑戦してみてください。

どうでしたか? 検証目的として、WSL Ubuntu で、Spring Boot Web アプリケーションを Azure Container Apps 環境でコンテナとして手軽に起動することができます。ぜひお試しください。今後も Azure の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

比較してみよう

今回と同じ仕様を実装する記事がご確認いただけます。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1