チュートリアル: VNet 内で Azure Database for MySQL - フレキシブル サーバーを使用して Spring Boot アプリケーションを AKS クラスターにデプロイする

適用対象: Azure Database for MySQL - フレキシブル サーバー

このチュートリアルでは、Azure 仮想ネットワーク内で互いに安全に通信している Azure Database for MySQL フレキシブル サーバーをバックエンドで使用して、Azure Kubernetes Service (AKS) クラスターに Spring Boot アプリケーションをデプロイする方法について説明します。

Note

このチュートリアルでは、Kubernetes の概念、Java Spring Boot、MySQL の基本的な理解を前提としています。 Spring Boot アプリケーションの場合は、Azure Spring Apps を使うことをお勧めします。 ただし、その場合でもデプロイ先として Azure Kubernetes Services を使うことはできます。 アドバイスについては、Java ワークロード宛先ガイダンスに関する記事を参照してください。

前提条件

Azure Database for MySQL フレキシブル サーバーを作成する

リソース グループを作成する

Azure リソース グループは、Azure リソースが展開され管理される論理グループです。 az group create コマンドを実行して、eastus の場所に rg-mysqlaksdemo というリソース グループを作成しましょう。

  1. コマンド プロンプトを開きます。
  2. Azure アカウントにサインインします。
    az login
    
  3. Azure サブスクリプションを選択します。
    az account set -s <your-subscription-ID>
    
  4. リソース グループを作成します。
    az group create --name rg-mysqlaksdemo --location eastus
    

Azure Database for MySQL フレキシブル サーバー インスタンスを作成する

次に、仮想ネットワーク内に Azure Database for MySQL フレキシブル サーバー インスタンスを作成します (プライベート アクセス接続方法)。

  1. このチュートリアルのすべてのリソースに対して 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 
    
  2. 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 日間のバックアップ保有期間の Azure Database for MySQL フレキシブル サーバーを、eastus リージョンおよび指定されたサブネット subnet-mysql に作成しました。 このサブネットには他のリソースがデプロイされていない必要があります。これは、Microsoft.DBforMySQL/flexibleServers に委任されます。

  3. 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 にプッシュします。」に進みます。

  1. 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 など、お好みのテキスト エディターを使用します。

  2. 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 サーバーではデータベースと同じ日付形式が使用されず、エラーが発生します。

  3. データベース スキーマを作成します。

    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);
    
  4. 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();
        }
    }
    
  5. 基本ディレクトリ 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"]
    
  6. 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>
    
  7. 以下の例に示すように 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ネットワークを使用するに関するページを参照してください。

  1. 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
    
  2. サブネット リソース ID を取得します。

    SUBNET_ID=$(az network vnet subnet show --resource-group rg-mysqlaksdemo --vnet-name vnet-mysqlaksdemo --name subnet-aks --query id -o tsv)
    
  3. 仮想ネットワークに 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 クラスターにアプリケーションをデプロイする

  1. Azure portal で AKS クラスター リソースに移動します。

  2. いずれかのリソース ビュー ([名前空間]、[ワークロード]、[サービスとイングレス]、[ストレージ]、または [構成]) から [追加] および [YAML で追加] を選択します。

    Azure portal 上の Azure Kubernetes Service リソース ビューを示すスクリーンショット。

  3. 次の 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
    
  4. YAML エディターの下部にある [追加] を選択してアプリケーションをデプロイします。

    [YAML で追加] エディターを示すスクリーンショット。

  5. YAML ファイルが追加されると、リソース ビューアーに Spring Boot アプリケーションが表示されます。 外部サービスに含まれているリンクされた外部 IP アドレスをメモします。

    Azure Kubernetes クラスター サービス 外部 IP の Azure portal でのビューを示すスクリーンショット。

アプリケーションをテストする

アプリケーションをテストするには、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}]

この cURL 要求のスクリーンショットを次に示します。cURL 要求のコマンド ライン出力を示すスクリーンショット。

ブラウザーから同様の出力が表示されます。ブラウザー要求の出力を示すスクリーンショット。

お疲れさまでした。 バックエンドで 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 はプラットフォームによって管理されるので、削除する必要はありません。

次のステップ