Share via


教學課程:使用受控識別從 JAVA Quarkus 容器應用程式連線至 Postgre SQL 資料庫不含秘密

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

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

您將學到的內容:

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

如果您沒有 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,其會呼叫由 適用於 PostgreSQL 的 Azure 資料庫 支援的 Quarkus REST API。 App 的程式碼可在 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 服務。 當應用程式在本機執行時, %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. 執行下列命令來建立 Container Apps 實例。 請確定您將環境變數的值取代為您想要使用的實際名稱和位置。

    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 資料庫並連接具有身分識別連線能力

接下來,建立 Postgre SQL 資料庫並設定容器應用程式,以使用系統指派的受控識別連線到 Postgre SQL 資料庫。 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

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

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

  • 系統管理員使用者 →系統管理員帳戶的使用者名稱。 它不能是 azure_superuser 、、 adminadministratorrootguest 、 或 public 。 例如, demoadmin 沒問題。

  • 系統管理員密碼 →系統管理員使用者的密碼。 它必須包含下列三個類別的 8 到 128 個字元:英文大寫字母、英文小寫字母、數位和非英數位元。

    重要

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

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

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

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

    az postgres flexible-server db create \
        --resource-group $RESOURCE_GROUP \
        --server-name $DB_SERVER_NAME \
        --database-name fruits
    
  2. 安裝 Azure CLI 的服務連線或 無密碼擴充功能:

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

    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

當新的網頁顯示您的水果清單時,您的應用程式會使用受控識別連線到資料庫。 您現在應該能夠像以前一樣編輯水果清單。

清除資源

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

az group delete --name myResourceGroup

此命令可能需要一分鐘的時間才能執行。

下一步

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