你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
教程:使用托管标识从 Java Quarkus 容器应用连接到 PostgreSQL 数据库,而无需使用机密
Azure 容器应用为应用提供托管标识,这是一项统包解决方案,可以确保安全地访问 Azure Database for PostgreSQL 和其他 Azure 服务。 容器应用中的托管标识可以让应用更安全,因为不需在应用中存储机密,例如环境变量中的凭据。
本教程将指导你完成在 Azure 上生成、配置、部署和缩放 Java 容器应用的过程。 在本教程结束时,你将有一个 Quarkus 应用程序,该应用程序在 PostgreSQL 数据库中存储数据,并在容器应用上运行一个托管标识。
要学习的知识:
- 将 Quarkus 应用配置为使用 Microsoft Entra ID 和 PostgreSQL 数据库进行身份验证。
- 创建 Azure 容器注册表并向其推送 Java 应用映像。
- 在 Azure 中创建容器应用。
- 在 Azure 中创建 PostgreSQL 数据库。
- 使用服务连接器通过托管标识连接到 PostgreSQL 数据库。
如果没有 Azure 订阅,请在开始之前创建一个 Azure 免费帐户。
1.先决条件
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 容器注册表实例,并使用 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. 克隆示例应用并准备容器映像
本教程使用示例 Fruits 列表应用,该应用的 Web UI 可以调用 Azure Database for PostgreSQL 支持的 Quarkus REST API。 GitHub 上提供了该应用的代码。 如需详细了解如何使用 Quarkus 和 PostgreSQL 编写 Java 应用,请参阅 Quarkus Hibernate ORM with Panache 指南 和 Quarkus 数据源指南。
在终端中运行以下命令,以克隆示例存储库并设置示例应用环境。
git clone https://github.com/quarkusio/quarkus-quickstarts
cd quarkus-quickstarts/hibernate-orm-panache-quickstart
修改项目
向项目 BOM 文件中添加所需的依赖项。
<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 应用服务时。 当应用程序在本地运行时, 将忽略%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][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
。 - name → PostgreSQL 数据库服务器名称。 此名称必须在整个 Azure 中唯一(服务器终结点将变为
https://<name>.postgres.database.azure.com
)。 允许的字符有A
-Z
、0
-9
和-
。 良好的模式是结合使用公司名称和服务器标识符。 (msdocs-quarkus-postgres-webapp-db
) - location → 使用用于 Web 应用的同一个位置。 如果它不起作用,请更换到其他位置。
- public-access →
None
,即,将服务器设置为不使用防火墙规则的公共访问模式。 将在后面的步骤中创建规则。 - sku-name → 定价层和计算配置的名称,例如
Standard_B1ms
。 有关详细信息,请参阅 Azure Database for PostgreSQL 定价。 - 层级 →服务器的计算层。 有关详细信息,请参阅 Azure Database for PostgreSQL 定价。
- 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)
当新网页显示水果列表时,表明应用使用了托管标识连接到数据库。 现在应该可以像以前一样编辑水果列表了。
清理资源
在前面的步骤中,你在资源组中创建了 Azure 资源。 如果认为将来不需要这些资源,请在 Cloud Shell 中运行以下命令删除资源组:
az group delete --name myResourceGroup
此命令可能需要花费一点时间运行。
后续步骤
在开发人员指南中详细了解如何在 Azure 上运行 Java 应用。