Share via


教學課程:在具有 適用於 MySQL 的 Azure 資料庫 的 AKS 叢集上部署 Spring Boot 應用程式 - VNet 中的彈性伺服器

適用於:適用於 MySQL 的 Azure 資料庫 - 彈性伺服器

在本教學課程中,您將瞭解如何在 Azure Kubernetes Service (AKS) 叢集部署 Spring Boot 應用程式,並在後端具有 適用於 MySQL 的 Azure 資料庫 彈性伺服器,安全地在 Azure 虛擬網路彼此通訊。

注意

本教學課程假設對 Kubernetes 概念、Java Spring Boot 和 MySQL 有基本的瞭解。 對於 Spring Boot 應用程式,建議使用 Azure Spring 應用程式。 不過,您仍然可以使用 Azure Kubernetes Services 作為目的地。 如需建議,請參閱 Java工作負載目的地指引

必要條件

建立適用於 MySQL 的 Azure 資料庫彈性伺服器

建立資源群組

Azure 資源群組是部署及管理 Azure 資源所在的邏輯群組。 讓我們使用eastus位置中的 az group create 命令,建立資源群組 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
    

建立 適用於 MySQL 的 Azure 資料庫 彈性伺服器實例

我們現在會在虛擬網路中建立 適用於 MySQL 的 Azure 資料庫 彈性伺服器實例(私人存取連線方法)。

  1. 針對本教學課程中的所有資源建立 Azure 虛擬網路 vnet-mysqlaksdemo,併為 適用於 MySQL 的 Azure 資料庫 彈性伺服器實例建立子網子網 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 命令,在上述建立的子網中建立 適用於 MySQL 的 Azure 資料庫 彈性伺服器實例 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
    

    您現在已在 eastus 區域中建立 適用於 MySQL 的 Azure 資料庫 彈性伺服器實例,其中包含高載 B1MS 計算、32 GB 記憶體、7 天的備份保留期間,以及提供的子網 subnet-mysql。 此子網不應部署任何其他資源,且會委派給 Microsoft.DBforMySQL/flexibleServers。

  3. 設定新的 適用於 MySQL 的 Azure 資料庫 彈性伺服器資料庫demo,以搭配 Spring Boot 應用程式使用。

    az mysql flexible-server db create \
    --resource-group rg-mysqlaksdemo \
    --server-name mysql-mysqlaksdemo \
    --database-name demo
    

建立 Azure Container Registry

在資源群組中建立私人 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. 將 Spring Boot 設定為使用 適用於 MySQL 的 Azure 資料庫 彈性伺服器。

    開啟 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 表示 Spring Boot 會在每次啟動伺服器時,使用 schema.sql 我們稍後建立的檔案自動產生資料庫架構。 這非常適合用於測試,但請記住,這會在每次重新啟動時刪除您的數據,因此這不應該用於生產環境!

    注意

    我們會附加 ?serverTimezone=UTC 至組態屬性 spring.datasource.url,以告訴 JDBC 驅動程式在連線到資料庫時使用 UTC 日期格式(或國際標準時間)。 否則,我們的 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 的 Java 程式代碼來儲存和擷取 MySQL 伺服器的數據。 在 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. 在基底目錄中 建立新的 Dockerfile springboot-mysql-aks ,並複製此代碼段。

    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檔案,並使用 Azure Container Registry 的登錄名稱和最新版本jib-maven-plugin的 ,更新 <properties> pom.xml 檔案中的集合。 注意:如果您的 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. <plugins>更新 pom.xml 檔案中的集合,使 有一個<plugin>元素包含 的專案jib-maven-plugin,如下所示。 請注意,我們使用的是 Microsoft Container Registry (MCR): 的基底映射, mcr.microsoft.com/java/jdk:8-zulu-alpine其中包含正式支援的 Azure JDK。 如需其他具有正式支援的 JDK 的 MCR 基底映像,請參閱 Docker 中

    <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 叢集建立子網 子網 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. 取得子網資源標識碼。

    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 服務位址範圍中。 請勿使用您位址範圍中的第一個 IP 位址。 您子網路範圍內的第一個位址會用於 kubernetes.default.svc.cluster.local 位址。

    • --docker-bridge-address 是 Docker 網橋網路位址,代表所有 Docker 安裝中存在的預設 docker0 網橋網路位址。 您必須挑選不會與網路上其餘的 CIDR 相撞的地址空間,包括叢集的服務 CIDR 和 Pod CIDR。

將應用程式部署至 AKS 叢集

  1. 移至 Azure 入口網站 上的 AKS 叢集資源。

  2. 從任何資源檢視中選取 [新增] 和 [使用 YAML 新增] (命名空間、工作負載、服務和輸入、儲存體 或組態)。

    螢幕快照,顯示 Azure 入口網站 上的 Azure Kubernetes Service 資源檢視。

  3. 貼上下列 YAML。 取代 適用於 MySQL 的 Azure 資料庫 彈性伺服器管理員使用者名稱和密碼的值。

    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 入口網站 檢視的螢幕快照。

測試應用程式

您可使用 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 Kubernetes Service (AKS) 叢集上成功部署 Spring Boot 應用程式,並在後端 適用於 MySQL 的 Azure 資料庫 彈性伺服器!

清除資源

若要避免 Azure 費用,您應該清除不需要的資源。 不再需要叢集時,請使用 az group delete 命令來移除資源群組、容器服務和所有相關資源。

az group delete --name rg-mysqlaksdemo

注意

當您刪除叢集時,系統不會移除 AKS 叢集所使用的 Microsoft Entra 服務主體。 如需有關如何移除服務主體的步驟,請參閱 AKS 服務主體的考量和刪除。 如果您使用受控識別,則身分識別會由平台負責管理,您不需要刪除。

下一步