在 Azure Kubernetes Service 叢集上使用 Quarkus 部署 Java 應用程式
本文說明如何使用簡單的 CRUD 應用程式,快速在 Azure Kubernetes Service (AKS) 上部署 Red Hat Quarkus。 該應用程式是具有 JavaScript 前端和 REST 端點的「待辦事項清單」。 適用於 PostgreSQL 的 Azure 資料庫提供應用程式的持續性層。 本文說明如何在本地測試應用程式,並將其部署至 AKS。
必要條件
- 如果您沒有 Azure 訂用帳戶,請在開始之前先建立 Azure 免費帳戶。
- Azure Cloud Shell 已預先安裝上述全部必要條件。 如需詳細資訊,請參閱 Azure Cloud Shell 快速入門。
- 如果您在本地執行本指南中的命令 (而不是使用 Azure Cloud Shell),請完成下列步驟:
- 使用已安裝類似 Unix 的作業系統 (例如 Ubuntu、macOS 或 Windows 子系統 Linux 版) 準備本機電腦。
- 安裝 Java SE 實作 (例如 OpenJDK 的 Microsoft 組建)。
- 安裝 Maven 3.5.0 或更新版本。
- 為您的作業系統安裝 Docker 或 Podman。
- 安裝 jq。
- 安裝 cURL。
- 安裝 Quarkus CLI。
- 適用於 Unix 的 Azure CLI 環境。 本文只需要 Azure CLI 的 Bash 變體。
- 本文需要使用至少 Azure CLI 2.31.0 版。 如果您是使用 Azure Cloud Shell,就已安裝最新版本。
建立應用程式專案
使用下列命令複製本文的範例 Java 專案。 此範例位於 GitHub 上。
git clone https://github.com/Azure-Samples/quarkus-azure
cd quarkus-azure
git checkout 2023-07-17
cd aks-quarkus
如果您看到有關處於中斷連結的 HEAD 狀態的訊息,則可安全地略過此訊息。 由於本文不需要任何認可,因此中斷連結的 HEAD 狀態沒有問題。
在本地測試 Quarkus 應用程式
本節中的步驟說明如何在本地執行應用程式。
Quarkus 支援在開發和測試模式中自動佈建未設定的服務。 Quarkus 將這項功能稱為開發服務。 假設您包含 Quarkus 功能,例如連線到資料庫服務。 您想要測試應用程式,但尚未完整設定實際資料庫的連線。 Quarkus 會自動啟動相關服務的虛設常式版本,並將您的應用程式連線到這個版本。 如需詳細資訊,請參閱Quarkus 文件中的開發服務概觀。
請確定您的容器環境 Docker 或 Podman 正在執行,並使用下列命令進入 Quarkus 開發模式:
quarkus dev
您可以使用 mvn quarkus:dev
(而不是 quarkus dev
) 完成與 Maven 相同的動作。
系統可能會詢問您是否要傳送 Quarkus 開發模式使用量的遙測資料。 如果是,請按照您的意願回答。
Quarkus 開發模式可讓您在背景編譯時啟用即時重新載入。 如果您修改應用程式原始碼的任何層面並重新整理瀏覽器,您可以看到變更。 如果編譯或部署發生任何問題,會顯示錯誤頁面告知您。 Quarkus 開發模式會接聽連接埠 5005 上的調試程式。 如果您要等候偵錯工具在執行之前附加,請在命令列上傳遞 -Dsuspend
。 如果您根本不想要除錯程式,您可以使用 -Ddebug=false
。
輸出看起來會如下列範例所示:
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
INFO [io.quarkus] (Quarkus Main Thread) quarkus-todo-demo-app-aks 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.2.0.Final) started in 3.377s. Listening on: http://localhost:8080
INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx]
--
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
在 Quarkus 開發模式執行所在的終端上按下 w。 w 鍵會開啟預設網頁瀏覽器以顯示 Todo
應用程式。 您也可以直接在 http://localhost:8080
存取應用程式 GUI。
請嘗試在待辦事項清單中選取一些待辦事項項目。 UI 會指出具有刪除線文字樣式的選取範圍。 您也可以輸入 Verify Todo apps 並按下 ENTER,將新的待辦事項項目新增至待辦事項清單,如下列螢幕擷取畫面所示:
存取 RESTful API (/api
) 以取得儲存在本地 PostgreSQL 資料庫中的全部待辦事項項目:
curl --verbose http://localhost:8080/api | jq .
輸出看起來會如下列範例所示:
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /api HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-length: 664
< Content-Type: application/json;charset=UTF-8
<
{ [664 bytes data]
100 664 100 664 0 0 13278 0 --:--:-- --:--:-- --:--:-- 15441
* Connection #0 to host localhost left intact
[
{
"id": 1,
"title": "Introduction to Quarkus Todo App",
"completed": false,
"order": 0,
"url": null
},
{
"id": 2,
"title": "Quarkus on Azure App Service",
"completed": false,
"order": 1,
"url": "https://learn.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin"
},
{
"id": 3,
"title": "Quarkus on Azure Container Apps",
"completed": false,
"order": 2,
"url": "https://learn.microsoft.com/en-us/training/modules/deploy-java-quarkus-azure-container-app-postgres/"
},
{
"id": 4,
"title": "Quarkus on Azure Functions",
"completed": false,
"order": 3,
"url": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-quarkus"
},
{
"id": 5,
"title": "Verify Todo apps",
"completed": false,
"order": 5,
"url": null
}
]
按下 q 以結束 Quarkus 開發模式。
建立 Azure 資源以執行 Quarkus 應用程式
本節中的步驟說明如何建立下列 Azure 資源來執行 Quarkus 範例應用程式:
- 適用於 PostgreSQL 的 Azure 資料庫
- Azure Container Registry (ACR)
- Azure Kubernetes Service (AKS)
其中有些資源在 Azure 訂用帳戶的範圍內必須有唯一的名稱。 若要確保此唯一性,您可以使用縮寫、序列、日期、尾碼模式。 若要套用此模式,請列出您的縮寫、某些序號、今天的日期,以及某種資源特定的後綴來命名資源,例如, rg
「資源群組」。 使用下列命令來定義一些環境變數以供稍後使用:
export UNIQUE_VALUE=<your unique value, such as ejb010717>
export RESOURCE_GROUP_NAME=${UNIQUE_VALUE}rg
export LOCATION=<your desired Azure region for deploying your resources. For example, eastus>
export REGISTRY_NAME=${UNIQUE_VALUE}reg
export DB_SERVER_NAME=${UNIQUE_VALUE}db
export CLUSTER_NAME=${UNIQUE_VALUE}aks
export AKS_NS=${UNIQUE_VALUE}ns
建立適用於 PostgreSQL 的 Azure 資料庫
Azure Database for PostgreSQL 是一種受控服務,可以用來在 Azure 雲端執行、管理和調整高可用性的 PostgreSQL 資料庫。 本節將引導您前往個別的快速入門,說明如何建立適用於 PostgreSQL 的 Azure 資料庫伺服器並連線。 不過,您遵循快速入門中的步驟時,您必須使用下表中的設定來自訂範例 Quarkus 應用程式的資料庫部署。 在 Azure 入口網站中填寫欄位時,以實際值取代環境變數。
設定 | 值 | Description |
---|---|---|
資源群組 | ${RESOURCE_GROUP_NAME} |
選取 [新建] 部署會建立這個新的資源群組。 |
伺服器名稱 | ${DB_SERVER_NAME} |
此值構成資料庫伺服器主機名的一部分。 |
Location | ${LOCATION} |
從下拉式清單中選取位置。 記下位置。 您必須針對您建立的其他 Azure 資源使用這個相同的位置。 |
管理員使用者名稱 | quarkus | 範例程式碼假設這個值。 |
密碼 | Secret123456 | 範例程式碼假設這個值。 |
考量到這些值替代,請遵循快速入門:使用 Azure 入口網站建立適用於 PostgreSQL 的 Azure 資料庫伺服器中的步驟,持續直到 [設定防火牆規則] 區段為止。 然後,在 [設定防火牆規則] 區段中,務必針對 [允許存取 Azure 服務] 選取 [是],然後選取 [儲存]。 如果您忽略這樣做,您的 Quarkus 應用程式就無法存取資料庫,而且完全無法啟動。
完成快速入門中的步驟,並透過一節完成之後,包括允許存取 Azure 服務的步驟,請返回本文。
在 PostgreSQL 中建立待辦事項資料庫
您先前建立的 PostgreSQL 伺服器是空的。 其中未包含任何可供 Quarkus 應用程式使用的資料庫。 使用下列命令建立名為 todo
的新資料庫:
az postgres db create \
--resource-group ${RESOURCE_GROUP_NAME} \
--name todo \
--server-name ${DB_SERVER_NAME}
您必須使用 todo
做為資料庫的名稱,因為範例程式碼假設使用該資料庫名稱。
如果該命令成功,輸出會類似下列範例:
{
"charset": "UTF8",
"collation": "English_United States.1252",
"id": "/subscriptions/REDACTED/resourceGroups/ejb010718rg/providers/Microsoft.DBforPostgreSQL/servers/ejb010718db/databases/todo",
"name": "todo",
"resourceGroup": "ejb010718rg",
"type": "Microsoft.DBforPostgreSQL/servers/databases"
}
建立 Microsoft Azure Container Registry 執行個體
由於 Quarkus 是雲端原生技術,因此對於建立在 Kube 中執行的容器提供內建支援。 Kube 完全相依於容器登錄,這會從中尋找要執行的容器映像。 AKS 具有 Azure Container Registry (ACR) 的內建支援。
使用 az acr create 命令建立 ACR 執行個體。 下列範例會建立以環境變數 ${REGISTRY_NAME}
的值為名稱的 ACR 執行個體:
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--location ${LOCATION} \
--name $REGISTRY_NAME \
--sku Basic \
--admin-enabled
在短時間內,您應該會看到包括下列幾行的 JSON 輸出:
"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"resourceGroup": "<YOUR_RESOURCE_GROUP>",
將您的 Docker 連線到 ACR 執行個體
登入 ACR 執行個體。 登入可讓您推送映像。 執行下列命令來驗證連線:
export LOGIN_SERVER=$(az acr show \
--name $REGISTRY_NAME \
--query 'loginServer' \
--output tsv)
echo $LOGIN_SERVER
export USER_NAME=$(az acr credential show \
--name $REGISTRY_NAME \
--query 'username' \
--output tsv)
echo $USER_NAME
export PASSWORD=$(az acr credential show \
--name $REGISTRY_NAME \
--query 'passwords[0].value' \
--output tsv)
echo $PASSWORD
docker login $LOGIN_SERVER -u $USER_NAME -p $PASSWORD
如果您使用 Podman 而非 Docker,請對命令進行必要的變更。
如果您已成功登入 ACR 執行個體,您應該會在命令輸出的結尾看到 Login Succeeded
。
建立 AKS 叢集
使用 az aks create 命令來建立 AKS 叢集。 下列範例會對於一個節點建立以環境變數 ${CLUSTER_NAME}
的值為名稱的叢集。 叢集會連線到您在上一個步驟中建立的 ACR 執行個體。 此命令需要幾分鐘才能完成。
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--location ${LOCATION} \
--name $CLUSTER_NAME \
--attach-acr $REGISTRY_NAME \
--node-count 1 \
--generate-ssh-keys \
--enable-managed-identity
在幾分鐘之後,此命令就會完成,並以 JSON 格式傳回叢集的相關資訊,包括下列輸出:
"nodeResourceGroup": "MC_<your resource_group_name>_<your cluster name>_<your region>",
"privateFqdn": null,
"provisioningState": "Succeeded",
"resourceGroup": "<your resource group name>",
連線到 AKS 叢集
若要管理 Kubernetes 叢集,您會使用 kubectl
,即 Kubernetes 命令列用戶端。 如果您使用 Azure Cloud Shell,則 kubectl
已安裝。 若要在本地安裝 kubectl
,請使用 az aks install-cli 命令,如下列範例所示:
az aks install-cli
如需 kubectl
的詳細資訊,請參閱 Kube 文件中的命令行工具 (kubectl)。
若要設定 kubectl
以連線到 Kubernetes 叢集,請使用 az aks get-credentials 命令,如下列範例所示。 此命令會下載憑證並設定 Kubernetes CLI 以供使用。
az aks get-credentials \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--overwrite-existing \
--admin
成功的輸出包含類似下列範例的文字:
Merged "ejb010718aks-admin" as current context in /Users/edburns/.kube/config
您可能會發現將 k
的別名設定為 kubectl
很有用。 若是如此,請使用下列命令:
alias k=kubectl
若要驗證叢集的連線,請使用 kubectl get
命令傳回叢集節點的清單,如下列範例所示:
kubectl get nodes
下列輸出範例會顯示上一個步驟中建立的單一節點。 請確定節點的狀態為 Ready:
NAME STATUS ROLES AGE VERSION
aks-nodepool1-xxxxxxxx-yyyyyyyyyy Ready agent 76s v1.23.8
在 AKS 中建立新的命名空間
使用下列命令,在 Quarkus 應用程式的 Kube 服務中建立新的命名空間:
kubectl create namespace ${AKS_NS}
輸出看起來會如下列範例所示:
namespace/<your namespace> created
自訂雲端原生設定
Quarkus 是雲端原生技術,可讓您自動設定標準 Kube、Red Hat OpenShift 和 Knative 的資源。 如需詳細資訊,請參閱 Quarkus Kube 指南、Quarkus OpenShift 指南和 Quarkus Knative 指南。 開發人員可以套用產生的資訊清單,將應用程式部署至目標 Kube 叢集。
若要產生適當的 Kube 資源,請使用下列命令在本地終端中新增 quarkus-kubernetes
和 container-image-jib
延伸模組:
quarkus ext add kubernetes container-image-jib
Quarkus 會修改 POM,以確保這些延伸模組會列為 <dependencies>
。 如果系統要求您安裝名為 JBang
的項目,請回答是,並允許安裝。
輸出看起來會如下列範例所示:
[SUCCESS] ✅ Extension io.quarkus:quarkus-kubernetes has been installed
[SUCCESS] ✅ Extension io.quarkus:quarkus-container-image-jib has been installed
若要驗證已新增延伸模組,您可以執行 git diff
並檢查輸出。
Quarkus 是雲端原生技術,支援組態設定檔的概念。 Quarkus 具有下列三個內建設定檔:
dev
- 在開發模式中啟動test
- 在執行測試時啟動prod
- 未在開發或測試模式中執行時的預設設定檔
Quarkus 會視需要支援任意數目的具名設定檔。
本節中的其餘步驟會引導您取消註解和自訂 src/main/resources/application.properties 檔案中的值。 移除前置的 #
,確定以 # %prod.
開頭的全部行都會取消註解。
prod.
前置詞表示這些屬性在 prod
設定檔中執行時為作用中。 如需設組態設定檔的詳細資訊,請參閱 Quarkus 文件。
資料庫設定
新增下列資料庫組態變數。 將 <DB_SERVER_NAME_VALUE>
的值取代為 ${DB_SERVER_NAME}
環境變數的實際值。
# Database configurations
%prod.quarkus.datasource.db-kind=postgresql
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://<DB_SERVER_NAME_VALUE>.postgres.database.azure.com:5432/todo
%prod.quarkus.datasource.jdbc.driver=org.postgresql.Driver
%prod.quarkus.datasource.username=quarkus@<DB_SERVER_NAME_VALUE>
%prod.quarkus.datasource.password=Secret123456
%prod.quarkus.hibernate-orm.database.generation=drop-and-create
Kubernetes 設定
新增下列 Kube 組態變數。 務必將 service-type
設定為 load-balancer
,以便在外部存取應用程式。
# AKS configurations
%prod.quarkus.kubernetes.deployment-target=kubernetes
%prod.quarkus.kubernetes.service-type=load-balancer
容器映像設定
Quarkus 是雲端原生技術,支援產生與 Docker 和 Podman 相容的 OCI 容器映像。 新增下列容器映像變數。 將 <LOGIN_SERVER_VALUE>
和 <USER_NAME_VALUE>
的值分別取代為 ${LOGIN_SERVER}
和 ${USER_NAME}
環境變數實際值的值。
# Container Image Build
%prod.quarkus.container-image.build=true
%prod.quarkus.container-image.registry=<LOGIN_SERVER_VALUE>
%prod.quarkus.container-image.group=<USER_NAME_VALUE>
%prod.quarkus.container-image.name=todo-quarkus-aks
%prod.quarkus.container-image.tag=1.0
建置容器映像並將其推送至 ACR
現在,使用下列命令建置應用程式本身。 此命令會使用 Kube 和 Jib 延伸模組來建置容器映像。
quarkus build --no-tests
輸出應該以 BUILD SUCCESS
結尾。 Kube 資訊清單檔案會在 target/kubernetes 中產生,如下列範例所示:
tree target/kubernetes
target/kubernetes
├── kubernetes.json
└── kubernetes.yml
0 directories, 2 files
您可以驗證容器映像是否也 使用 docker
或 podman
命令列 (CLI) 產生。 輸出大致如下列範例所示:
docker images | grep todo
<LOGIN_SERVER_VALUE>/<USER_NAME_VALUE>/todo-quarkus-aks 1.0 b13c389896b7 18 minutes ago 420MB
使用下列命令將容器映像推送至 ACR:
export TODO_QUARKUS_TAG=$(docker images | grep todo-quarkus-aks | head -n1 | cut -d " " -f1)
echo ${TODO_QUARKUS_TAG}
docker push ${TODO_QUARKUS_TAG}:1.0
輸出應類似下列範例:
The push refers to repository [<LOGIN_SERVER_VALUE>/<USER_NAME_VALUE>/todo-quarkus-aks]
dfd615499b3a: Pushed
56f5cf1aa271: Pushed
4218d39b228e: Pushed
b0538737ed64: Pushed
d13845d85ee5: Pushed
60609ec85f86: Pushed
1.0: digest: sha256:0ffd70d6d5bb3a4621c030df0d22cf1aa13990ca1880664d08967bd5bab1f2b6 size: 1995
既然您已將應用程式推送至 ACR,您可以告訴 AKS 執行應用程式。
將 Quarkus 應用程式部署至 AKS
本節中的步驟說明如何在您建立的 Azure 資源上執行 Quarkus 範例應用程式。
使用 kubectl apply 將 Quarkus 應用程式部署至 AKS
在命令行上使用 kubectl
部署 Kube 資源,如下列範例所示:
kubectl apply -f target/kubernetes/kubernetes.yml -n ${AKS_NS}
輸出看起來會如下列範例所示:
deployment.apps/quarkus-todo-demo-app-aks created
使用下列命令驗證應用程式正在執行:
kubectl -n $AKS_NS get pods
如果 STATUS
欄位的值顯示 Running
以外的任何項目,請先進行疑難排解並解決問題,然後再繼續。 這可能有助於使用下列命令來檢查 Pod 記錄:
kubectl -n $AKS_NS logs $(kubectl -n $AKS_NS get pods | grep quarkus-todo-demo-app-aks | cut -d " " -f1)
使用下列命令取得 EXTERNAL-IP
以存取待辦事項應用程式:
kubectl get svc -n ${AKS_NS}
輸出看起來會如下列範例所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
quarkus-todo-demo-app-aks LoadBalancer 10.0.236.101 20.12.126.200 80:30963/TCP 37s
您可以使用下列命令,將 EXTERNAL-IP
的值儲存為環境變數的完整 URL:
export QUARKUS_URL=http://$(kubectl get svc -n ${AKS_NS} | grep quarkus-todo-demo-app-aks | cut -d " " -f10)
echo $QUARKUS_URL
將新的網頁瀏覽器開啟為 ${QUARKUS_URL}
的值。 然後,使用文字 Deployed the Todo app to AKS
新增待辦事項項目。 此外,請選取 Introduction to Quarkus Todo App
項目以便完成。
存取 RESTful API (/api
) 以取得儲存在 Azure PostgreSQL 資料庫中的全部待辦事項項目,如下列範例所示:
curl --verbose ${QUARKUS_URL}/api | jq .
輸出看起來會如下列範例所示:
* Connected to 20.237.68.225 (20.237.68.225) port 80 (#0)
> GET /api HTTP/1.1
> Host: 20.237.68.225
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-length: 828
< Content-Type: application/json;charset=UTF-8
<
[
{
"id": 2,
"title": "Quarkus on Azure App Service",
"completed": false,
"order": 1,
"url": "https://learn.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin"
},
{
"id": 3,
"title": "Quarkus on Azure Container Apps",
"completed": false,
"order": 2,
"url": "https://learn.microsoft.com/en-us/training/modules/deploy-java-quarkus-azure-container-app-postgres/"
},
{
"id": 4,
"title": "Quarkus on Azure Functions",
"completed": false,
"order": 3,
"url": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-quarkus"
},
{
"id": 5,
"title": "Deployed the Todo app to AKS",
"completed": false,
"order": 5,
"url": null
},
{
"id": 1,
"title": "Introduction to Quarkus Todo App",
"completed": true,
"order": 0,
"url": null
}
]
使用 Azure Cloud Shell 驗證資料庫已更新
選取 Cloud Shell 圖示,在 Azure 入口網站中開啟 Azure Cloud Shell,如下列螢幕擷取畫面所示:
在本地執行下列命令,並將結果貼到 Azure Cloud Shell 中:
echo psql --host=${DB_SERVER_NAME}.postgres.database.azure.com --port=5432 --username=quarkus@${DB_SERVER_NAME} --dbname=todo
系統詢問密碼時,請使用您在建立資料庫時使用的值。
使用下列查詢來取得全部待辦事項項目:
select * from todo;
輸出看起來應該類似下列範例,而且應該在先前顯示的待辦事項應用程式 GUI 中包含相同的項目:
如果您在輸出中看到 MORE
,請輸入 q 以結束呼叫器。
輸入 \q 以結束 psql
程式並返回 Cloud Shell。
清除資源
若要避免 Azure 費用,您應該清除不需要的資源。 如果不再需要叢集,請使用 az group delete 命令移除資源群組、容器服務、容器登錄及所有相關資源。
git reset --hard
docker rmi ${TODO_QUARKUS_TAG}:1.0
docker rmi postgres
az group delete --name $RESOURCE_GROUP_NAME --yes --no-wait
您也可以使用 docker rmi
刪除 Quarkus 開發模式產生的容器映像 postgres
和 testcontainers
。