Share via


在 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 的 Azure CLI 環境。 本文只需要 Azure CLI 的 Bash 變體。
    • 開發人員應該安裝 Azure CLI,並使用 az login 命令以互動方式登入 Azure,然後在程式碼中使用 DefaultAzureCredential。
      az login
      
    • 本文需要使用至少 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 開發模式執行所在的終端上按下 ww 鍵會開啟預設網頁瀏覽器以顯示 Todo 應用程式。 您也可以直接在 http://localhost:8080 存取應用程式 GUI。

Todo 範例應用程式的螢幕快照。

請嘗試在待辦事項清單中選取一些待辦事項項目。 UI 會指出具有刪除線文字樣式的選取範圍。 您也可以輸入 Verify Todo apps 並按下 ENTER,將新的待辦事項項目新增至待辦事項清單,如下列螢幕擷取畫面所示:

已新增專案之 Todo 範例應用程式的螢幕快照。

存取 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-kubernetescontainer-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

您可以驗證容器映像是否也 使用 dockerpodman 命令列 (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 項目以便完成。

在 AKS 中執行的 Todo 範例應用程式的螢幕快照。

存取 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,如下列螢幕擷取畫面所示:

醒目提示 Cloud Shell 按鈕的 Azure 入口網站 螢幕快照。

在本地執行下列命令,並將結果貼到 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 中包含相同的項目:

查詢輸出作為 ASCII 資料表的螢幕快照。

如果您在輸出中看到 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 開發模式產生的容器映像 postgrestestcontainers

下一步