在 Azure 容器应用上使用 Open Liberty 或 WebSphere Liberty 部署 Java 应用程序。

本文介绍如何在 Azure 容器应用中运行 Open Liberty 或 WebSphere Liberty。 你将在本文中进行以下活动:

  • 在 Open Liberty 或 WebSphere Liberty 运行时运行 Java、Java EE、Jakarta EE 或 MicroProfile 应用程序。
  • 使用 Liberty 容器映像构建应用程序 Docker 映像。
  • 将容器化应用程序部署到 Azure 容器应用。

有关 Open Liberty 的详细信息,请参阅 Open Liberty 项目页。 有关 IBM WebSphere Liberty 的详细信息,请参阅 WebSphere Liberty 产品页

本文旨在帮助你快速进行部署。 在进入生产环境之前,应探索 Tuning Liberty

如果您有兴趣就您的迁移方案向负责开发 Azure 上 WebSphere 解决方案的工程团队提供反馈或者与他们密切合作,请填写这份关于 WebSphere 迁移 的简短 调查,并提供您的联系信息。 项目经理、架构师和工程师团队会及时与你联系,以开展密切合作。

先决条件

  • Azure 订阅。 如果您没有 Azure 订阅,请在开始之前创建一个 免费账户
  • 准备安装了 Windows 或 Unix 之类操作系统(如 Ubuntu、macOS 或适用于 Linux 的 Windows 子系统)的本地计算机。
  • 安装 Azure CLI 2.62.0 或更高版本,以运行 Azure CLI 命令。
  • 安装 Java SE 实现版本 17 - 例如,Microsoft 版 OpenJDK
  • 安装 Maven 3.9.8 或更高版本。
  • 确保已安装 Git

登录 Azure

使用 az login 命令登录到 Azure 订阅,并按照屏幕上的说明进行操作。

az login

注意

可以在 PowerShell 中运行大多数 Azure CLI 命令,就像在 Bash 中一样。 仅当使用变量时才存在差异。 在以下各节中,需要时将在不同的选项卡中解决差异。

如果多个 Azure 租户与你的 Azure 凭据关联,必须指定要登录到哪个租户。 可以使用 --tenant 选项来指定租户,例如 az login --tenant contoso.onmicrosoft.com

如果在一个租户内有多个订阅,请确保使用 az account set --subscription <subscription-id> 登录要使用的订阅。

创建资源组

Azure 资源组是用于部署和管理 Azure 资源的逻辑组。

使用 eastus2 位置中的 az group create 命令创建名为 java-liberty-project 的资源组。 此资源组稍后用于创建 Azure 容器注册表 (ACR) 实例和 Azure 容器应用实例。

export RESOURCE_GROUP_NAME=java-liberty-project
az group create --name $RESOURCE_GROUP_NAME --location eastus2

创建 ACR 实例

使用 az acr create 命令创建 ACR 实例。 以下示例创建了一个名为 youruniqueacrname 的 ACR 实例。 确保 youruniqueacrname 在 Azure 中是唯一的。

注意

本文使用容器注册表的建议无密码身份验证机制。 在使用 az acr credential show 获取用户名和密码后,仍然可以在 docker login 中使用用户名和密码。 使用用户名和密码的安全性低于无密码身份验证。

export REGISTRY_NAME=youruniqueacrname
az acr create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $REGISTRY_NAME \
    --sku Basic

过了一会儿,你应该会看到一个包含以下行的 JSON 输出:

"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"resourceGroup": "java-liberty-project",

接下来,使用以下命令检索容器注册表实例的登录服务器。 稍后将应用程序映像部署到 Azure 容器应用时,你需要此值。

export ACR_LOGIN_SERVER=$(az acr show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $REGISTRY_NAME \
    --query 'loginServer' \
    --output tsv)

创建环境

Azure 容器应用中的环境围绕一组容器应用创建安全边界。 部署到相同环境的容器应用部署在同一虚拟网络中,并将日志写入同一个 Log Analytics 工作区。 使用 az containerapp env create 命令创建环境。 以下示例会创建一个名为 youracaenvname 的环境。

export ACA_ENV=youracaenvname
az containerapp env create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $ACA_ENV

如果系统要求你安装扩展,请回答 Y

过了一会儿,你应该会看到一个包含以下行的 JSON 输出:

"provisioningState": "Succeeded",
"type": "Microsoft.App/managedEnvironments"
"resourceGroup": "java-liberty-project",

在 Azure SQL 数据库中创建单一数据库

在本部分中,将在 Azure SQL 数据库中创建单个数据库,以便与应用一起使用。

首先,使用以下命令设置与数据库相关的环境变量。 将 <your-unique-sql-server-name> 替换为 Azure SQL Database 服务器的唯一名称。

export SQL_SERVER_NAME=<your-unique-sql-server-name>
export DB_NAME=demodb

接下来,使用以下命令在 Azure SQL 数据库中创建单一数据库,并将当前登录用户设置为 Microsoft Entra 管理员。有关详细信息,请参阅快速入门:创建单一数据库 - Azure SQL 数据库

export ENTRA_ADMIN_NAME=$(az account show --query user.name --output tsv)

az sql server create \
    --name $SQL_SERVER_NAME \
    --resource-group $RESOURCE_GROUP_NAME \
    --enable-ad-only-auth \
    --external-admin-principal-type User \
    --external-admin-name $ENTRA_ADMIN_NAME \
    --external-admin-sid $(az ad signed-in-user show --query id --output tsv)
az sql db create \
    --resource-group $RESOURCE_GROUP_NAME \
    --server $SQL_SERVER_NAME \
    --name $DB_NAME \
    --edition GeneralPurpose \
    --compute-model Serverless \
    --family Gen5 \
    --capacity 2

然后,使用以下命令将本地 IP 地址添加到 Azure SQL 数据库服务器防火墙规则,以允许本地计算机稍后连接到数据库进行本地测试。

export AZ_LOCAL_IP_ADDRESS=$(curl -s https://whatismyip.akamai.com)
az sql server firewall-rule create \
    --resource-group $RESOURCE_GROUP_NAME \
    --server $SQL_SERVER_NAME \
    --name AllowLocalIP \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS

注意

你可以为安全注意事项创建禁用 SQL 身份验证的 Azure SQL Server。 仅 Microsoft Entra ID 用于向服务器进行身份验证。 如果需要启用 SQL 身份验证,请参阅 az sql server create

配置并生成应用程序映像

要在 Azure 容器应用上部署和运行 Liberty 应用程序,请使用 Open Liberty 容器映像WebSphere Liberty 容器映像将应用程序容器化为 Docker 映像。

按照本部分中的步骤将示例应用程序部署到 Liberty 运行时。 这些步骤使用 Maven。

查看应用程序

使用以下命令准备本指南的示例代码。 该示例位于 GitHub 上。

git clone https://github.com/Azure-Samples/open-liberty-on-aca.git
cd open-liberty-on-aca
export BASE_DIR=$PWD
git checkout 20241118

如果你看到一条关于处于 detached HEAD 状态的消息,可以放心忽略此消息。 这只标识你签出了一个标签。

本文使用 java-app。 下面是应用程序重要文件的文件结构:

java-app
├─ src/main/
│  ├─ liberty/config/
│  │  ├─ server.xml
│  ├─ java/
│  ├─ resources/
│  ├─ webapp/
├─ Dockerfile
├─ Dockerfile-wlp
├─ pom.xml
├─ pom-azure-identity.xml

目录 javaresourceswebapp 包含示例应用程序的源代码。 代码声明并使用名为 jdbc/JavaEECafeDB 的数据源。

java-app 根目录中,有两个文件用于使用 Open Liberty 或 WebSphere Liberty 创建应用程序映像。

liberty/config 目录中,server.xml 文件用于配置 Open Liberty 和 WebSphere Liberty 群集的数据库连接。 它定义用于连接到 Azure SQL 数据库的变量 azure.sql.connectionstring

pom.xml 文件是 Maven 项目对象模型 (POM) 文件,其中包含项目的配置信息。 pom-azure-identity.xml 文件声明 azure-identity 依赖项,该依赖项用于使用 Microsoft Entra ID 向 Azure 服务进行身份验证。

注意

此示例使用 azure-identity 库通过 Microsoft Entra 身份验证向 Azure SQL 数据库进行身份验证,出于安全考虑建议这样做。 如果需要在库应用程序中使用 SQL 身份验证,请参阅通过 JDBC 实现的关系数据库连接

构建项目

使用以下命令生成应用程序:

cd $BASE_DIR/java-app
mvn clean install
mvn dependency:copy-dependencies -f pom-azure-identity.xml -DoutputDirectory=target/liberty/wlp/usr/shared/resources

如果构建成功,应在构建结束时看到类似于以下内容的输出。

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.651 s
[INFO] Finished at: 2023-10-26T18:58:40-04:00
[INFO] ------------------------------------------------------------------------

如果没有看到此输出,请先排除故障并解决问题,然后再继续。

在本地测试项目

现在,可以在部署到 Azure 前使用以下步骤在本地运行并测试项目。 为方便起见,使用 liberty-maven-plugin。 如需详细了解 liberty-maven-plugin,请参阅使用 Maven 构建 Web 应用程序。 对于你的应用程序,可以使用任何其他机制(例如本地 IDE)执行类似操作。

注意

如果选择了“无服务器”数据库部署,请验证 SQL 数据库是否未进入暂停模式。 执行验证的一种方法是按照 快速入门中所述登录到数据库查询编辑器:使用 Azure 门户查询编辑器(预览版)查询 Azure SQL 数据库

  1. 使用 liberty:run 启动应用程序。

    cd $BASE_DIR/java-app
    
    # The value of environment variable AZURE_SQL_CONNECTIONSTRING is read by the configuration variable azure.sql.connectionstring in server.xml.
    export AZURE_SQL_CONNECTIONSTRING="jdbc:sqlserver://$SQL_SERVER_NAME.database.windows.net:1433;databaseName=$DB_NAME;authentication=ActiveDirectoryDefault"
    mvn liberty:run
    
  2. 验证应用程序是否按预期运行。 如果成功,你应该会在命令输出中看到类似于 [INFO] [AUDIT ] CWWKZ0001I: Application javaee-cafe started in 11.086 seconds. 的消息。 在浏览器中访问 http://localhost:9080/,验证应用程序是否可访问,并且所有功能都正常工作。

  3. Ctrl+C 可停止。 如果要求你终止批处理作业,请选择 Y

完成后,使用以下命令删除允许本地 IP 地址访问 Azure SQL 数据库的防火墙规则:

az sql server firewall-rule delete \
    --resource-group $RESOURCE_GROUP_NAME \
    --server $SQL_SERVER_NAME \
    --name AllowLocalIP

生成 Azure 容器应用部署的映像

现在可以运行 az acr build 命令来生成映像,如以下示例所示:

cd $BASE_DIR/java-app

az acr build \
    --registry ${REGISTRY_NAME} \
    --image javaee-cafe:v1 \
    .

az acr build 命令会将 Dockerfile 中指定的工件上传到容器注册表实例,构建镜像,并将其存储在容器注册表实例中。

将应用程序部署到 Azure 容器应用

使用以下命令创建一个 Azure 容器应用实例,以便在从 ACR 中提取映像后运行应用。 此示例创建名为 youracainstancename的 Azure 容器应用实例:

export ACA_NAME=youracainstancename
az containerapp create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $ACA_NAME \
    --image ${ACR_LOGIN_SERVER}/javaee-cafe:v1 \
    --environment $ACA_ENV \
    --registry-server $ACR_LOGIN_SERVER \
    --registry-identity system \
    --target-port 9080 \
    --ingress 'external' \
    --min-replicas 1

成功的输出是一个包含属性 "type": "Microsoft.App/containerApps" 的 JSON 对象。

然后,按照以下步骤使用服务连接器将 Azure SQL Database 服务器连接到容器应用:

  1. 此示例使用服务连接器来帮助连接到数据库。 有关服务连接器的详细信息,请参阅什么是服务连接器? 使用以下命令安装 Azure CLI 的无密码扩展:

    az extension add --name serviceconnector-passwordless --upgrade --allow-preview true
    
  2. 通过连接命令使用系统分配的托管标识将数据库连接到容器应用:

    az containerapp connection create sql \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $ACA_NAME \
        --target-resource-group $RESOURCE_GROUP_NAME \
        --server $SQL_SERVER_NAME \
        --database $DB_NAME \
        --system-identity \
        --container $ACA_NAME \
        --client-type java
    

    成功的输出是一个包含属性 "type": "microsoft.servicelinker/linkers" 的 JSON 对象。

注意

服务连接器会在容器应用中创建一个机密,其中包含 AZURE_SQL_CONNECTIONSTRING 的值,这是 Azure SQL 数据库的无密码连接字符串。 有关详细信息,请参阅将 Azure SQL 数据库与服务连接器集成用户分配的托管标识部分中的示例值。

测试应用程序

使用以下命令获取完全限定的 URL 以访问应用程序:

echo https://$(az containerapp show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $ACA_NAME \
    --query properties.configuration.ingress.fqdn \
    --output tsv)

若要访问和测试应用程序,请打开 URL 的 Web 浏览器。 以下屏幕截图显示正在运行的应用程序:

显示已成功部署在 Azure 容器应用上的 Java Liberty 应用程序的屏幕截图。

清理资源

若要避免 Azure 费用,应清除不需要的资源。 不再需要群集时,请使用 az group delete 命令删除资源组、容器注册表、容器应用、数据库服务器和所有相关资源。

az group delete --name $RESOURCE_GROUP_NAME --yes --no-wait

后续步骤

可以从本指南中使用的参考资料中了解到更多信息:

要了解在 Azure 上运行 WebSphere 产品的选项,请参阅在 Azure 上运行 WebSphere 系列产品的解决方案有哪些?