共用方式為


教學課程:使用受控識別從 JAVA Quarkus 容器應用程式連線到 PostgreSQL 資料庫,而不需要祕密

Azure 容器應用程式也為您的應用程式提供受控識別,這是用於保護適用於 PostgreSQL 的 Azure 資料庫和其他 Azure 服務存取權的周全解決方案。 容器應用程式中的受控識別可藉由從應用程式刪除祕密 (例如環境變數中的認證),讓應用程式更加安全。

本教學課程會引導您完成在 Azure 上建置、設定、部署及調整 JAVA 容器應用程式的程序。 在本教學課程結束時,您將有 Quarkus 應用程式,以在容器應用程式上執行的受控識別,將資料儲存在 PostgreSQL 資料庫中。

您將了解:

  • 設定 Quarkus 應用程式,以搭配 PostgreSQL 資料庫使用 Microsoft Entra ID 進行驗證。
  • 建立 Azure 容器登錄,並將 JAVA 應用程式映像推送至其中。
  • 在 Azure 中建立容器應用程式。
  • 在 Azure 中建立 PostgreSQL 資料庫。
  • 使用服務連接器,透過受控識別連線至 PostgreSQL 資料庫。

如果您沒有 Azure 訂用帳戶,請在開始之前先建立 Azure 免費帳戶

1.Prerequisites

2.建立容器登錄庫

使用 az group create 命令來建立資源群組。 Azure 資源群組是在其中部署與管理 Azure 資源的邏輯容器。

下列範例會在美國東部 Azure 區域中建立名為 myResourceGroup 的資源群組。

az group create --name myResourceGroup --location eastus

使用 az acr create 命令建立 Azure Container Registry 執行個體。 登錄名稱在 Azure 內必須是唯一的,包含 5-50 個英數字元。 所有字母都必須以小寫指定。 在以下範例中,已使用 mycontainerregistry007。 請將此更新為唯一的值。

az acr create \
    --resource-group myResourceGroup \
    --name mycontainerregistry007 \
    --sku Basic

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

修改專案

  1. 將必要的相依性新增至專案 BOM 檔案。

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-identity-providers-jdbc-postgresql</artifactId>
        <version>1.0.0-beta.1</version>
    </dependency>
    
  2. 設定 Quarkus 應用程式屬性。

    Quarkus 組態位於 src/main/resources/application.properties 檔案中。 在編輯器中開啟此檔案,並觀察數個預設屬性。 只有在建置和部署應用程式時,才會使用前面加上 %prod 的屬性,例如部署至 Azure App Service。 當應用程式在本地執行時,系統會忽略 %prod 屬性。 同樣地,%dev 屬性會用於 Quarkus 的即時編碼/開發模式,並在持續測試期間使用 %test 屬性。

    刪除 application.properties 中的現有內容,並取代為下列項目,以設定開發、測試和生產模式的資料庫:

    quarkus.package.type=uber-jar
    
    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=${AZURE_CLIENT_NAME}
    %dev.quarkus.datasource.jdbc.url=jdbc:postgresql://${DBHOST}.postgres.database.azure.com:5432/${DBNAME}?\
    authenticationPluginClassName=com.azure.identity.providers.postgresql.AzureIdentityPostgresqlAuthenticationPlugin\
    &sslmode=require\
    &azure.clientId=${AZURE_CLIENT_ID}\
    &azure.clientSecret=${AZURE_CLIENT_SECRET}\
    &azure.tenantId=${AZURE_TENANT_ID}
    
    %prod.quarkus.datasource.username=${AZURE_MI_NAME}
    %prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${DBHOST}.postgres.database.azure.com:5432/${DBNAME}?\
    authenticationPluginClassName=com.azure.identity.providers.postgresql.AzureIdentityPostgresqlAuthenticationPlugin\
    &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-providers-core::jar,\
    com.azure:azure-identity-providers-jdbc-postgresql::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
    

建置 Docker 映像並將其推送至容器登錄

  1. 建置容器映像。

    執行下列命令來建置 Quarkus 應用程式映像。 您必須以登錄登入伺服器的完整名稱標記它。 登入伺服器名稱的格式為 <registry-name>.azurecr.io (必須全部小寫),例如 mycontainerregistry007.azurecr.io。 將名稱取代為您自己的登錄名稱。

    mvnw quarkus:add-extension -Dextensions="container-image-jib"
    mvnw clean package -Pnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true -Dquarkus.container-image.registry=mycontainerregistry007 -Dquarkus.container-image.name=quarkus-postgres-passwordless-app -Dquarkus.container-image.tag=v1
    
  2. 登入登錄。

    推送容器映像之前,您必須先登入登錄。 若要這樣做,請使用 [az acr login][az-acr-login] 命令。 使用 Azure CLI 登入時,只指定登錄資源名稱。 請勿使用完整登入伺服器名稱。

    az acr login --name <registry-name>
    

    完成後,此命令會傳回 Login Succeeded 訊息。

  3. 將映像推送至登錄。

    使用 [docker push][docker-push] 將映像推送到登錄執行個體。 將 mycontainerregistry007 取代為登錄執行個體的登入伺服器名稱。 此範例會建立 quarkus-postgres-passwordless-app 存放庫,其中包含 quarkus-postgres-passwordless-app:v1 映像。

    docker push mycontainerregistry007/quarkus-postgres-passwordless-app:v1
    

4.在 Azure 上建立容器應用程式

  1. 執行下列命令來建立容器應用程式執行個體。 請確定您將環境變數的值取代為您想要使用的實際名稱和位置。

    RESOURCE_GROUP="myResourceGroup"
    LOCATION="eastus"
    CONTAINERAPPS_ENVIRONMENT="my-environment"
    
    az containerapp env create \
        --resource-group $RESOURCE_GROUP \
        --name $CONTAINERAPPS_ENVIRONMENT \
        --location $LOCATION
    
  2. 執行下列命令,以您的應用程式映像建立容器應用程式。 以您的值取代預留位置。 若要尋找容器登錄管理員帳戶詳細資料,請參閱使用 Azure Container Registry 進行驗證

    CONTAINER_IMAGE_NAME=quarkus-postgres-passwordless-app:v1
    REGISTRY_SERVER=mycontainerregistry007
    REGISTRY_USERNAME=<REGISTRY_USERNAME>
    REGISTRY_PASSWORD=<REGISTRY_PASSWORD>
    
    az containerapp create \
        --resource-group $RESOURCE_GROUP \
        --name my-container-app \
        --image $CONTAINER_IMAGE_NAME \
        --environment $CONTAINERAPPS_ENVIRONMENT \
        --registry-server $REGISTRY_SERVER \
        --registry-username $REGISTRY_USERNAME \
        --registry-password $REGISTRY_PASSWORD
    

5.使用身分識別連線建立並連線 PostgreSQL 資料庫

接下來,建立 PostgreSQL 資料庫,並設定您的容器應用程式,以使用系統指派的受控識別連線到 PostgreSQL 資料庫。 Quarkus 應用程式會連線到此資料庫,並在執行時儲存其資料,讓您無論在哪執行應用程式,皆可保存應用程式狀態。

  1. 建立資料庫服務。

    DB_SERVER_NAME='msdocs-quarkus-postgres-webapp-db'
    ADMIN_USERNAME='demoadmin'
    ADMIN_PASSWORD='<admin-password>'
    
    az postgres flexible-server create \
        --resource-group $RESOURCE_GROUP \
        --name $DB_SERVER_NAME \
        --location $LOCATION \
        --admin-user $DB_USERNAME \
        --admin-password $DB_PASSWORD \
        --sku-name GP_Gen5_2
    

    上述 Azure CLI 命令中會使用下列參數:

    • resource-group → 使用您在建立 Web 應用程式時所使用的相同資源群組名稱,例如 msdocs-quarkus-postgres-webapp-rg

    • 名稱 → PostgreSQL 資料庫伺服器名稱。 此名稱在所有 Azure 中都是唯一的 (伺服器端點會成為 https://<name>.postgres.database.azure.com)。 有效字元:A-Z0-9-。 良好的模式是使用您的公司名稱和伺服器識別碼的組合。 },msdocs-quarkus-postgres-webapp-db

    • 位置 → 使用用於 Web 應用程式的相同位置。

    • admin-user → 系統管理員帳戶的使用者名稱。 不能是 azure_superuseradminadministratorrootguestpublic。 例如,demoadmin 是可行的。

    • admin-password → 管理員使用者的密碼。 其必須包含 8 到 128 個字元,且來自下列類別的其中三個類別:英文大寫字母、英文小寫字母、數字及非英數字元。

      重要

      建立使用者名稱或密碼時不會使用 $ 字元。 稍後在本教學課程中,您將使用這些值來建立環境變數,其中 $ 字元在用來執行 JAVA 應用程式的 Linux 容器內具有特殊意義。

    • public-accessNone 會以沒有防火牆規則的公用存取模式設定伺服器。 將會在稍後的步驟中建立規則。

    • sku-name → 定價層和計算設定的名稱。例如,GP_Gen5_2。 如需詳細資訊,請參閱適用於 PostgreSQL 的 Azure 資料庫定價

  2. 使用下列命令在 PostgreSQL 服務內建立名為 fruits 的資料庫:

    az postgres flexible-server db create \
        --resource-group $RESOURCE_GROUP \
        --server-name $DB_SERVER_NAME \
        --database-name fruits
    
  3. 安裝 Azure CLI 的服務連接器無密碼延伸模組:

    az extension add --name serviceconnector-passwordless --upgrade
    
  4. 使用連線命令,使用系統指派的受控識別,將資料庫連線到容器應用程式。

    az containerapp connection create postgres-flexible \
        --resource-group $RESOURCE_GROUP \
        --name my-container-app \
        --target-resource-group $RESOURCE_GROUP \
        --server $DB_SERVER_NAME \
        --database fruits \
        --managed-identity
    

6.檢閱您的變更

您可以使用下列命令來尋找應用程式 URL (FQDN):

az containerapp list --resource-group $RESOURCE_GROUP

當新的網頁顯示 Fruits 清單時,表示應用程式正使用受控識別連線到資料庫。 您現在應該能夠如以往一樣編輯 Fruits 清單。

清除資源

在上述步驟中,您已建立資源群組中的 Azure 資源。 如果您在未來不需要這些資源,請在 Cloud Shell 中執行下列命令,刪除資源群組:

az group delete --name myResourceGroup

此命令可能會花一分鐘執行。

下一步

在開發人員指南中深入了解如何在 Azure 上執行 JAVA 應用程式。