教學課程:使用受控識別從 JAVA Quarkus 容器應用程式連線到 PostgreSQL 資料庫,而不需要祕密
Azure 容器應用程式也為您的應用程式提供受控識別,這是用於保護適用於 PostgreSQL 的 Azure 資料庫和其他 Azure 服務存取權的周全解決方案。 容器應用程式中的受控識別可藉由從應用程式刪除祕密 (例如環境變數中的認證),讓應用程式更加安全。
本教學課程會引導您完成在 Azure 上建置、設定、部署及調整 JAVA 容器應用程式的程序。 在本教學課程結束時,您會有Quarkus應用程式,以在 Container Apps 上執行的受控識別,將數據儲存在PostgreSQL資料庫中。
您將學到:
- 設定 Quarkus 應用程式,以搭配 PostgreSQL 資料庫使用 Microsoft Entra ID 進行驗證。
- 建立 Azure 容器登錄,並將 JAVA 應用程式映像推送至其中。
- 在 Azure 中建立容器應用程式。
- 在 Azure 中建立 PostgreSQL 資料庫。
- 使用服務連接器,透過受控識別連線至 PostgreSQL 資料庫。
如果您沒有 Azure 訂用帳戶,請在開始之前先建立 Azure 免費帳戶。
1.Prerequisites
2.建立容器登錄庫
使用 az group create 命令來建立資源群組。 Azure 資源群組是在其中部署與管理 Azure 資源的邏輯容器。
下列範例會在美國東部 Azure 區域中建立名為 myResourceGroup
的資源群組。
RESOURCE_GROUP="myResourceGroup"
LOCATION="eastus"
az group create --name $RESOURCE_GROUP --location $LOCATION
使用 az acr create 命令建立 Azure Container Registry 實例,並使用 az acr show 命令擷取其登入伺服器。 登錄名稱在 Azure 內必須是唯一的,且包含 5-50 個英數字元。 所有字母都必須以小寫指定。 在以下範例中,已使用 mycontainerregistry007
。 請將此更新為唯一的值。
REGISTRY_NAME=mycontainerregistry007
az acr create \
--resource-group $RESOURCE_GROUP \
--name $REGISTRY_NAME \
--sku Basic
REGISTRY_SERVER=$(az acr show \
--name $REGISTRY_NAME \
--query 'loginServer' \
--output tsv | tr -d '\r')
3.複製範例應用程式並準備容器映像
本教學課程將使用具有 Web UI 的 Fruits 清單應用程式範例,此 UI 可用來呼叫由適用於 PostgreSQL 的 Azure 資料庫支援的 Quarkus REST API。 您可在 GitHub 上找到應用程式的程式碼。 若要深入瞭解如何使用 Quarkus 和 PostgreSQL 撰寫 JAVA 應用程式,請參閱 Quarkus Hibernate ORM 搭配 Panache 指南 和 Quarkus 資料來源指南。
在您的終端機中執行下列命令,即可複製範例存放庫並設定範例應用程式環境。
git clone https://github.com/quarkusio/quarkus-quickstarts
cd quarkus-quickstarts/hibernate-orm-panache-quickstart
修改專案
將必要的相依性新增至專案的 POM 檔案。
<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity-extensions</artifactId> <version>1.1.20</version> </dependency>
設定 Quarkus 應用程式屬性。
Quarkus 組態位於 src/main/resources/application.properties 檔案中。 在編輯器中開啟此檔案,並觀察數個預設屬性。 只有在建置和部署應用程式時,才會使用前面加上
%prod
的屬性,例如部署至 Azure App Service。 當應用程式在本地執行時,系統會忽略%prod
屬性。 同樣地,%dev
屬性會用於 Quarkus 的即時編碼/開發模式,並在持續測試期間使用%test
屬性。刪除 application.properties 中的現有內容,並取代為下列項目,以設定開發、測試和生產模式的資料庫:
quarkus.hibernate-orm.database.generation=drop-and-create quarkus.datasource.db-kind=postgresql quarkus.datasource.jdbc.max-size=8 quarkus.datasource.jdbc.min-size=2 quarkus.hibernate-orm.log.sql=true quarkus.hibernate-orm.sql-load-script=import.sql quarkus.datasource.jdbc.acquisition-timeout = 10 %dev.quarkus.datasource.username=${CURRENT_USERNAME} %dev.quarkus.datasource.jdbc.url=jdbc:postgresql://${AZURE_POSTGRESQL_HOST}:${AZURE_POSTGRESQL_PORT}/${AZURE_POSTGRESQL_DATABASE}?\ authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin\ &sslmode=require %prod.quarkus.datasource.username=${AZURE_POSTGRESQL_USERNAME} %prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${AZURE_POSTGRESQL_HOST}:${AZURE_POSTGRESQL_PORT}/${AZURE_POSTGRESQL_DATABASE}?\ authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin\ &sslmode=require %dev.quarkus.class-loading.parent-first-artifacts=com.azure:azure-core::jar,\ com.azure:azure-core-http-netty::jar,\ io.projectreactor.netty:reactor-netty-core::jar,\ io.projectreactor.netty:reactor-netty-http::jar,\ io.netty:netty-resolver-dns::jar,\ io.netty:netty-codec::jar,\ io.netty:netty-codec-http::jar,\ io.netty:netty-codec-http2::jar,\ io.netty:netty-handler::jar,\ io.netty:netty-resolver::jar,\ io.netty:netty-common::jar,\ io.netty:netty-transport::jar,\ io.netty:netty-buffer::jar,\ com.azure:azure-identity::jar,\ com.azure:azure-identity-extensions::jar,\ com.fasterxml.jackson.core:jackson-core::jar,\ com.fasterxml.jackson.core:jackson-annotations::jar,\ com.fasterxml.jackson.core:jackson-databind::jar,\ com.fasterxml.jackson.dataformat:jackson-dataformat-xml::jar,\ com.fasterxml.jackson.datatype:jackson-datatype-jsr310::jar,\ org.reactivestreams:reactive-streams::jar,\ io.projectreactor:reactor-core::jar,\ com.microsoft.azure:msal4j::jar,\ com.microsoft.azure:msal4j-persistence-extension::jar,\ org.codehaus.woodstox:stax2-api::jar,\ com.fasterxml.woodstox:woodstox-core::jar,\ com.nimbusds:oauth2-oidc-sdk::jar,\ com.nimbusds:content-type::jar,\ com.nimbusds:nimbus-jose-jwt::jar,\ net.minidev:json-smart::jar,\ net.minidev:accessors-smart::jar,\ io.netty:netty-transport-native-unix-common::jar,\ net.java.dev.jna:jna::jar
建置 Docker 映像並將其推送至容器登錄
建置容器映像。
執行下列命令來建置 Quarkus 應用程式映像。 您必須以登錄登入伺服器的完整名稱標記它。
CONTAINER_IMAGE=${REGISTRY_SERVER}/quarkus-postgres-passwordless-app:v1 mvn quarkus:add-extension -Dextensions="container-image-jib" mvn clean package -Dquarkus.container-image.build=true -Dquarkus.container-image.image=${CONTAINER_IMAGE}
登入登錄。
推送容器映像之前,您必須先登入登錄。 若要這樣做,請使用 [az acr login][az-acr-login] 命令。
az acr login --name $REGISTRY_NAME
完成後,此命令會傳回
Login Succeeded
訊息。將映像推送至登錄。
使用
docker push
將映像推送至登錄實例。 此範例會建立quarkus-postgres-passwordless-app
存放庫,其中包含quarkus-postgres-passwordless-app:v1
映像。docker push $CONTAINER_IMAGE
4.在 Azure 上建立容器應用程式
執行下列命令來建立容器應用程式執行個體。 請確定您將環境變數的值取代為您想要使用的實際名稱和位置。
CONTAINERAPPS_ENVIRONMENT="my-environment" az containerapp env create \ --resource-group $RESOURCE_GROUP \ --name $CONTAINERAPPS_ENVIRONMENT \ --location $LOCATION
執行下列命令,以您的應用程式映像建立容器應用程式:
APP_NAME=my-container-app az containerapp create \ --resource-group $RESOURCE_GROUP \ --name $APP_NAME \ --image $CONTAINER_IMAGE \ --environment $CONTAINERAPPS_ENVIRONMENT \ --registry-server $REGISTRY_SERVER \ --registry-identity system \ --ingress 'external' \ --target-port 8080 \ --min-replicas 1
注意
選項
--registry-username
和--registry-password
仍受到支援,但不建議使用,因為使用身分識別系統更安全。
5.使用身分識別連線建立並連線 PostgreSQL 資料庫
接下來,建立 PostgreSQL 資料庫,並設定您的容器應用程式,以使用系統指派的受控識別連線到 PostgreSQL 資料庫。 Quarkus 應用程式會連線到此資料庫,並在執行時儲存其數據,無論您在何處執行應用程式,都保存應用程式狀態。
建立資料庫服務。
DB_SERVER_NAME='msdocs-quarkus-postgres-webapp-db' az postgres flexible-server create \ --resource-group $RESOURCE_GROUP \ --name $DB_SERVER_NAME \ --location $LOCATION \ --public-access None \ --sku-name Standard_B1ms \ --tier Burstable \ --active-directory-auth Enabled
注意
選項
--admin-user
和--admin-password
仍受到支援,但不建議使用,因為使用身分識別系統更安全。上述 Azure CLI 命令中會使用下列參數:
- resource-group →使用您建立 Web 應用程式的相同資源組名,例如
msdocs-quarkus-postgres-webapp-rg
。 - 名稱 → PostgreSQL 資料庫伺服器名稱。 此名稱在所有 Azure 中都是唯一的 (伺服器端點會成為
https://<name>.postgres.database.azure.com
)。 有效字元:A
-Z
、0
-9
和-
。 良好的模式是使用您的公司名稱和伺服器識別碼的組合。 (msdocs-quarkus-postgres-webapp-db
) - 位置 → 使用用於 Web 應用程式的相同位置。 如果無法運作,請變更為不同的位置。
- public-access →
None
會以沒有防火牆規則的公用存取模式設定伺服器。 規則會在稍後的步驟中建立。 - sku-name →定價層和計算組態的名稱,例如 。
Standard_B1ms
如需詳細資訊,請參閱適用於 PostgreSQL 的 Azure 資料庫定價。 - tier →伺服器的計算層。 如需詳細資訊,請參閱適用於 PostgreSQL 的 Azure 資料庫定價。
- active-directory-auth →
Enabled
啟用Microsoft Entra 驗證。
- resource-group →使用您建立 Web 應用程式的相同資源組名,例如
使用下列命令在 PostgreSQL 服務內建立名為
fruits
的資料庫:DB_NAME=fruits az postgres flexible-server db create \ --resource-group $RESOURCE_GROUP \ --server-name $DB_SERVER_NAME \ --database-name $DB_NAME
安裝 Azure CLI 的服務連接器無密碼延伸模組:
az extension add --name serviceconnector-passwordless --upgrade --allow-preview true
使用連線命令,使用系統指派的受控識別,將資料庫連線到容器應用程式。
az containerapp connection create postgres-flexible \ --resource-group $RESOURCE_GROUP \ --name $APP_NAME \ --target-resource-group $RESOURCE_GROUP \ --server $DB_SERVER_NAME \ --database $DB_NAME \ --system-identity \ --container $APP_NAME
6.檢閱您的變更
您可以使用下列命令來尋找應用程式 URL (FQDN):
echo https://$(az containerapp show \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--query properties.configuration.ingress.fqdn \
--output tsv)
當新的網頁顯示 Fruits 清單時,表示應用程式正使用受控識別連線到資料庫。 您現在應該能夠如以往一樣編輯 Fruits 清單。
清除資源
在上述步驟中,您已建立資源群組中的 Azure 資源。 如果您在未來不需要這些資源,請在 Cloud Shell 中執行下列命令,刪除資源群組:
az group delete --name myResourceGroup
此命令可能會花一分鐘執行。
下一步
在開發人員指南中深入了解如何在 Azure 上執行 JAVA 應用程式。