教學課程:在 VNet 中具有適用於 MySQL 的 Azure 資料庫 - 彈性伺服器的 AKS 叢集上部署 Spring Boot 應用程式
適用於:適用於 MySQL 的 Azure 資料庫 - 彈性伺服器
在本教學課程中,您將了解如何在後端使用適用於 MySQL 的 Azure 資料庫彈性伺服器在 Azure Kubernetes Service (AKS) 叢集上部署 Spring Boot 應用程式,並在 Azure 虛擬網路內安全地彼此通訊。
注意
本教學課程假設您對 Kubernetes 概念、Java Spring Boot 和 MySQL 有基本了解。 對於 Spring Boot 應用程式,建議使用 Azure Spring 應用程式。 不過,您仍可使用 Azure Kubernetes Service 作為目的地。 如需建議,請參閱 Java 工作負載目的地指導。
必要條件
- Azure 訂閱 - 如果您沒有 Azure 訂閱,請在開始前建立 Azure 免費帳戶。 目前,Azure 免費帳戶可讓您免費試用「適用於 MySQL 的 Azure 資料庫 - 彈性伺服器」12 個月。 如需詳細資訊,請參閱免費試用適用於 MySQL 的 Azure 資料庫 - 彈性伺服器。
- Azure 命令列介面 (CLI)。
- 支援的 JAVA 開發工具組 版本 8 (包含在 Azure Cloud Shell 中)。
- Apache Maven 建置工具。
- Git 用戶端。
- Docker 用戶端。
建立適用於 MySQL 的 Azure 資料庫彈性伺服器
建立資源群組
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
建立適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體
我們現在會在虛擬網路中建立適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體 (私人存取連線方法)。
針對本教學課程中的所有資源建立 Azure 虛擬網路 vnet-mysqlaksdemo,並為適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體建立子網路 vnet-mysqlaksdemo。
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 命令,在上述建立的子網路中建立適用於 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。
設定要與 Spring Boot 應用程式搭配使用的全新適用於 MySQL 的 Azure 資料庫彈性伺服器資料庫
demo
。az mysql flexible-server db create \ --resource-group rg-mysqlaksdemo \ --server-name mysql-mysqlaksdemo \ --database-name demo
建立 Azure Container Registry
在資源群組中建立私用的 Azure Container Registry。 本教學課程會在稍後的步驟中,將範例應用程式以 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。
設定 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 伺服器不會使用與資料庫相同的日期格式,這會導致錯誤。建立資料庫結構。
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 的 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(); } }
在基本目錄 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 檔案並將其中的
<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>
集合,讓<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 網路功能。
針對 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
取得子網路資源識別碼。
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 服務位址範圍中。 請勿使用您位址範圍中的第一個 IP 位址。 您子網路範圍內的第一個位址會用於 kubernetes.default.svc.cluster.local 位址。
--docker-bridge-address 是 Docker 橋接器網路位址,代表存在於所有 Docker 安裝中的預設 docker0 橋接器網路位址。 您必須選取與網路上其他 CIDR 不衝突的位址空間,包括叢集的服務 CIDR 和 Pod CIDR。
將應用程式部署至 AKS 叢集
移至 Azure 入口網站上的 AKS 叢集資源。
從任何資源檢視中選取 [新增],然後選取 [使用 YAML 新增] (命名空間、工作負載、服務和輸入、儲存體或設定)。
在下列 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
選取 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}]
以下是這些 cURL 要求的螢幕擷取畫面:
您可以透過瀏覽器看到類似輸出:
恭喜! 您已使用位於後端的適用於 MySQL 的 Azure 資料庫彈性伺服器,在 Azure Kubernetes Service (AKS) 上成功部署 Spring Boot 應用程式!
清除資源
若要避免 Azure 費用,您應該清除不需要的資源。 若不再需要叢集,可使用 az group delete 命令來移除資源群組、容器服務和所有相關資源。
az group delete --name rg-mysqlaksdemo
注意
當您刪除叢集時,系統不會移除 AKS 叢集所使用的 Microsoft Entra 服務主體。 如需有關如何移除服務主體的步驟,請參閱 AKS 服務主體的考量和刪除。 如果您使用受控識別,則身分識別會由平台負責管理,您不需要刪除。