チュートリアル: VNet 内で Azure Database for MySQL - フレキシブル サーバーを使用して Spring Boot アプリケーションを AKS クラスターにデプロイする
このチュートリアルでは、バックエンドの Azure Database for MySQL - フレキシブル サーバーを使って Azure Kubernetes Service (AKS) クラスターに Spring Boot アプリケーションをデプロイし、Azure 仮想ネットワーク内で相互に安全な通信が行われるようにする方法について説明します。
Note
このチュートリアルでは、Kubernetes の概念、Java Spring Boot、MySQL の基本的な理解を前提としています。 Spring Boot アプリケーションの場合は、Azure Spring Apps を使うことをお勧めします。 ただし、その場合でもデプロイ先として Azure Kubernetes Services を使うことはできます。 アドバイスについては、Java ワークロード宛先ガイダンスに関する記事を参照してください。
前提条件
- Azure サブスクリプション Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。 現在、Azure 無料アカウントがあれば、Azure Database for MySQL - フレキシブル サーバーを 12 か月間無料でお試しいただけます。 詳細については、「Azure 無料アカウントを使用して Azure Database for MySQL - フレキシブル サーバーを無料で試す」を参照してください。
- Azure コマンド ライン インターフェイス (CLI)。
- サポートされている Java 開発キット、バージョン 8 (Azure Cloud Shell に含まれます)。
- Apache Maven ビルド ツール。
- Git クライアント。
- Docker クライアント。
Azure Database for MySQL フレキシブル サーバーを作成する
リソース グループを作成する
Azure リソース グループは、Azure リソースが展開され管理される論理グループです。 az group create コマンドを実行して、eastus の場所に rg-mysqlaksdemo というリソース グループを作成しましょう。
コマンド プロンプトを開きます。
Azure アカウントにサインインします。
az login
Azure サブスクリプションを選択します。
az account set -s <your-subscription-ID>
リソース グループを作成します。
az group create --name rg-mysqlaksdemo --location eastus
Azure Database for MySQL フレキシブル サーバー インスタンスを作成する
次に、仮想ネットワーク内に Azure Database for MySQL フレキシブル サーバー インスタンスを作成します (プライベート アクセス接続方法)。
このチュートリアルのすべてのリソース用の Azure 仮想ネットワーク vnet-mysqlaksdemo と、Azure Database for MySQL フレキシブル サーバーインスタンス用のサブネット subnet-mysql を作成します。
az network vnet create \ --resource-group rg-mysqlaksdemo \ --name vnet-mysqlaksdemo \ --address-prefixes 155.55.0.0/16 \ --subnet-name subnet-mysql \ --subnet-prefix 155.55.1.0/24
az mysql flexible-server create コマンドを使って、上で作成したサブネットに Azure Database for MySQL フレキシブル サーバー インスタンス mysql-mysqlaksdemo を作成します。 管理者のユーザー名とパスワードの値を置き換えます。
az mysql flexible-server create \ --name mysql-mysqlaksdemo \ --resource-group rg-mysqlaksdemo \ --location eastus \ --admin-user <your-admin-username> \ --admin-password <your-admin-password> \ --vnet vnet-mysqlaksdemo \ --subnet subnet-mysql
これで、バースト可能な B1MS コンピューティング、32 GB のストレージ、7 日間のバックアップ保持期間を使用し、指定したサブネット subnet-mysql 内に存在する Azure Database for MySQL フレキシブル サーバー インスタンスが、eastus リージョンに作成しました。 このサブネットには他のリソースがデプロイされていない必要があります。これは、Microsoft.DBforMySQL/flexibleServers に委任されます。
Spring Boot アプリケーションで使用する、新しい Azure Database for MySQL フレキシブル サーバー データベース
demo
を構成します。az mysql flexible-server db create \ --resource-group rg-mysqlaksdemo \ --server-name mysql-mysqlaksdemo \ --database-name demo
Azure コンテナー レジストリを作成する
リソース グループ内に、プライベートな Azure コンテナー レジストリを作成します。 このチュートリアルでは、後の手順で、このレジストリに Docker イメージとしてサンプル アプリをプッシュします。 mysqlaksdemoregistry
を、レジストリの一意の名前に置き換えます。
az acr create --resource-group rg-mysqlaksdemo \
--location eastus \
--name mysqlaksdemoregistry \
--sku Basic
アプリケーションをコーディングする
このセクションでは、デモ アプリケーションをコーディングします。 高速化する場合は、https://github.com/Azure-Samples/tutorial-springboot-mysql-aks で利用可能なコーディングされたアプリケーションをダウンロードし、次のセクション「イメージをビルドして ACR にプッシュします。」に進みます。
Spring Initializr を使用してアプリケーションを生成します。
curl https://start.spring.io/starter.tgz \ -d dependencies=web,data-jdbc,mysql \ -d baseDir=springboot-mysql-aks \ -d bootVersion=2.5.6.RELEASE \ -d artifactId=springboot-mysql-aks \ -d description="Spring Boot on AKS connecting to Azure DB for MySQL" \ -d javaVersion=1.8 | tar -xzvf -
基本 Spring Boot アプリケーションは
springboot-mysql-aks
フォルダー内に生成されます。次の手順では VSCode や任意の IDE など、お好みのテキスト エディターを使用します。
Azure Database for MySQL フレキシブル サーバーを使うように Spring Boot を構成します。
src/main/resources/application.properties ファイルを開き、以下のスニペットを追加します。 このコードは、Kubernetes マニフェスト ファイルからデータベース ホスト、データベース名、ユーザー名、パスワードを読み取ります。
logging.level.org.springframework.jdbc.core=DEBUG spring.datasource.url=jdbc:mysql://${DATABASE_HOST}:3306/${DATABASE_NAME}?serverTimezone=UTC spring.datasource.username=${DATABASE_USERNAME} spring.datasource.password=${DATABASE_PASSWORD} spring.datasource.initialization-mode=always
警告
構成プロパティ
spring.datasource.initialization-mode=always
は、サーバーが起動されるたびに、schema.sql
ファイル (後ほど作成します) を使用して、Spring Boot がデータベース スキーマを自動的に生成することを意味します。 これはテストには適していますが、再起動するたびにデータが削除されるため、運用環境では使用しないでください。注意
構成プロパティ
spring.datasource.url
に?serverTimezone=UTC
を追加して、データベースへの接続時に UTC 日付形式 (協定世界時) を使用するように JDBC ドライバーに指示します。 そうしないと、Java サーバーではデータベースと同じ日付形式が使用されず、エラーが発生します。データベース スキーマを作成します。
Spring Boot は、データベース スキーマを作成するために
src/main/resources/schema.sql
を自動的に実行します。 このファイルを次の内容で作成します。DROP TABLE IF EXISTS todo; CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
Java Spring Boot アプリケーションをコーディングします。
JDBC を使用して MySQL サーバーにデータを格納および取得する Java コードを追加します。
DemoApplication
クラスの横に新しいTodo
Java クラスを作成し、以下のコードを追加します。package com.example.springbootmysqlaks; import org.springframework.data.annotation.Id; public class Todo { public Todo() { } public Todo(String description, String details, boolean done) { this.description = description; this.details = details; this.done = done; } @Id private Long id; private String description; private String details; private boolean done; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } public boolean isDone() { return done; } public void setDone(boolean done) { this.done = done; } }
このクラスは、先ほど作成した
todo
テーブルにマップされるドメイン モデルです。このクラスを管理するには、リポジトリが必要です。 同じパッケージ内に新しい
TodoRepository
インターフェイスを定義します。package com.example.springbootmysqlaks; import org.springframework.data.repository.CrudRepository; public interface TodoRepository extends CrudRepository<Todo, Long> { }
このリポジトリは、Spring Data JDBC によって管理されるリポジトリです。
データを格納および取得できるコントローラーを作成して、アプリケーションを完成させます。 同じパッケージに
TodoController
クラスを実装し、次のコードを追加します。package com.example.springbootmysqlaks; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/") public class TodoController { private final TodoRepository todoRepository; public TodoController(TodoRepository todoRepository) { this.todoRepository = todoRepository; } @PostMapping("/") @ResponseStatus(HttpStatus.CREATED) public Todo createTodo(@RequestBody Todo todo) { return todoRepository.save(todo); } @GetMapping("/") public Iterable<Todo> getTodos() { return todoRepository.findAll(); } }
基本ディレクトリ springboot-mysql-aks に新しい Dockerfile を作成し、このコード スニペットをコピーします。
FROM openjdk:8-jdk-alpine RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG DEPENDENCY=target/dependency COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib COPY ${DEPENDENCY}/META-INF /app/META-INF COPY ${DEPENDENCY}/BOOT-INF/classes /app ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.springbootmysqlaks.DemoApplication"]
pom.xml ファイルに移動し、pom.xml ファイル内の
<properties>
コレクションを、Azure Container Registry のレジストリ名とjib-maven-plugin
の最新バージョンで更新します。 注: ACR 名に大文字が含まれている場合は、必ず小文字に変換してください。<properties> <docker.image.prefix>mysqlaksdemoregistry.azurecr.io</docker.image.prefix> <jib-maven-plugin.version>3.1.4</jib-maven-plugin.version> <java.version>1.8</java.version> </properties>
以下の例に示すように pom.xml ファイルの
<plugins>
コレクションを更新し、jib-maven-plugin
のエントリが含まれる<plugin>
要素が存在するようにします。 ここでは Microsoft Container Registry (MCR) の基本イメージmcr.microsoft.com/java/jdk:8-zulu-alpine
を使っており、それには公式にサポートされている Azure 用の JDK が含まれます。 正式にサポートされている JDK を含むその他の MCR 基本イメージについては、「Docker Hub」を参照してください。<plugin> <artifactId>jib-maven-plugin</artifactId> <groupId>com.google.cloud.tools</groupId> <version>${jib-maven-plugin.version}</version> <configuration> <from> <image>mcr.microsoft.com/java/jdk:8-zulu-alpine</image> </from> <to> <image>${docker.image.prefix}/${project.artifactId}</image> </to> </configuration> </plugin>
イメージをビルドして ACR にプッシュします。
コマンド プロンプトで springboot-mysql-aks フォルダーに移動し、次のコマンドを実行して、最初に Azure Container Registry の既定の名前を設定し (それ以外の場合は、az acr login
で名前を指定する必要があります)、イメージをビルドしてから、イメージをレジストリにプッシュします。
この手順の実行中に、Docker デーモンが実行されていることを確認します。
az config set defaults.acr=mysqlaksdemoregistry
az acr login && mvn compile jib:build
AKS で Kubernetes クラスターを作成する
次に、仮想ネットワーク vnet-mysqlaksdemo に AKS クラスターを作成します。
このチュートリアルでは、AKS でAzure CNI ネットワークを使用します。 代わりに kubenet ネットワークを構成する場合は、AKS で kubenetネットワークを使用するに関するページを参照してください。
AKS クラスターが使用するサブネット subnet-aks を作成します。
az network vnet subnet create \ --resource-group rg-mysqlaksdemo \ --vnet-name vnet-mysqlaksdemo \ --name subnet-aks \ --address-prefixes 155.55.2.0/24
サブネット リソース ID を取得します。
SUBNET_ID=$(az network vnet subnet show --resource-group rg-mysqlaksdemo --vnet-name vnet-mysqlaksdemo --name subnet-aks --query id -o tsv)
仮想ネットワークに AKS クラスターを作成し、Azure Container Registry (ACR) mysqlaksdemoregistry を接続します。
az aks create \ --resource-group rg-mysqlaksdemo \ --name aks-mysqlaksdemo \ --network-plugin azure \ --service-cidr 10.0.0.0/16 \ --dns-service-ip 10.0.0.10 \ --docker-bridge-address 172.17.0.1/16 \ --vnet-subnet-id $SUBNET_ID \ --attach-acr mysqlaksdemoregistry \ --dns-name-prefix aks-mysqlaksdemo \ --generate-ssh-keys
クラスター作成プロセスの一部として、次の IP アドレス範囲も定義します。
--service-cidr は、AKS クラスター内の内部サービスに IP アドレスを割り当てるために使用します。 次の要件を満たす任意のプライベート アドレス範囲を使用できます。
- クラスターの仮想ネットワークの IP アドレス範囲に含まれていてはなりません
- クラスターの仮想ネットワークがピアリングする他の仮想ネットワークと重複していてはなりません
- オンプレミスのどの IP アドレスとも重複していてはなりません
- 169.254.0.0/16、172.30.0.0/16、 172.31.0.0/16、192.0.2.0/24 の範囲内にあってはなりません
--dns-service-ip アドレスはクラスターの DNS サービスの IP アドレスです。 [Kubernetes service address range](Kubernetes サービス アドレスの範囲) 内に含まれるアドレスを指定する必要があります。 アドレス範囲内の最初の IP アドレスは使用しないでください。 サブネット範囲の最初のアドレスは、kubernetes.default.svc.cluster.local アドレスに使用されます。
--docker-bridge-address は、すべての Docker インストールに存在する既定の docker0 ブリッジのネットワーク アドレスを表す Docker ブリッジのネットワーク アドレスです。 ネットワーク上の残りの CIDR と競合しないアドレス空間を選択する必要があります。これには、クラスターのサービス CIDR とポッド CIDR が含まれます。
AKS クラスターにアプリケーションをデプロイする
Azure portal で AKS クラスター リソースに移動します。
いずれかのリソース ビュー ([名前空間]、[ワークロード]、[サービスとイングレス]、[ストレージ]、または [構成]) から [追加] および [YAML で追加] を選択します。
次の YAML を貼り付けます。 Azure Database for MySQL フレキシブル サーバー管理者のユーザー名とパスワードを、実際の値に置き換えてください。
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-mysql-aks spec: replicas: 1 selector: matchLabels: app: springboot-mysql-aks template: metadata: labels: app: springboot-mysql-aks spec: containers: - name: springboot-mysql-aks image: mysqlaksdemoregistry.azurecr.io/springboot-mysql-aks:latest env: - name: DATABASE_HOST value: "mysql-mysqlaksdemo.mysql.database.azure.com" - name: DATABASE_USERNAME value: "<your-admin-username>" - name: DATABASE_PASSWORD value: "<your-admin-password>" - name: DATABASE_NAME value: "demo" --- apiVersion: v1 kind: Service metadata: name: springboot-mysql-aks spec: type: LoadBalancer ports: - port: 80 targetPort: 8080 selector: app: springboot-mysql-aks
YAML エディターの下部にある [追加] を選択してアプリケーションをデプロイします。
YAML ファイルが追加されると、リソース ビューアーに Spring Boot アプリケーションが表示されます。 外部サービスに含まれているリンクされた外部 IP アドレスをメモします。
アプリケーションをテストする
アプリケーションをテストするには、cURL を使用します。
まず、次のコマンドを使用して、データベースに新しい "todo" 項目を作成します。
curl --header "Content-Type: application/json" \
--request POST \
--data '{"description":"configuration","details":"congratulations, you have deployed your application correctly!","done": "true"}' \
http://<AKS-service-external-ip>
次に、新しい cURL 要求を使用するか、ブラウザーにクラスターの 外部 IP を入力して、データを取得します。
curl http://<AKS-service-external-ip>
このコマンドを実行すると、作成した項目を含む "todo" 項目の一覧が返されます。
[{"id":1,"description":"configuration","details":"congratulations, you have deployed your application correctly!","done":true}]
お疲れさまでした。 バックエンドで Azure Database for MySQL フレキシブル サーバーを使って、Spring Boot アプリケーションを Azure Kubernetes Service (AKS) クラスターに正常にデプロイしました。
リソースのクリーンアップ
Azure の課金を回避するには、不要なリソースをクリーンアップする必要があります。 クラスターが必要なくなったら、az group delete コマンドを使って、リソース グループ、コンテナー サービス、およびすべての関連リソースを削除してください。
az group delete --name rg-mysqlaksdemo
Note
クラスターを削除したとき、AKS クラスターで使用される Microsoft Entra サービス プリンシパルは削除されません。 サービス プリンシパルを削除する手順については、AKS のサービス プリンシパルに関する考慮事項と削除に関するページを参照してください。 マネージド ID を使用した場合、ID はプラットフォームによって管理されるので、削除する必要はありません。