在 Azure Kubernetes Service (AKS) 群集上使用 Open Liberty 或 WebSphere Liberty 手动部署 Java 应用程序

本文提供在 Azure 上运行 Open/WebSphere Liberty 的分步手动指南。

具体而言,本文介绍如何完成以下任务:

  • 在 Open Liberty 或 WebSphere Liberty 运行时运行 Java、Java EE、Jakarta EE 或 MicroProfile 应用程序。
  • 使用 Liberty 容器映像生成应用程序 Docker 映像 az acr build
  • 使用 Liberty Operator 将容器化应用程序部署到 Azure Kubernetes 服务 (AKS) 群集。

Liberty Operator 简化了在 Kubernetes 群集上运行的应用程序的部署和管理。 利用 Open Liberty Operator 或 WebSphere Liberty Operator,还可以执行更高级的操作,例如收集跟踪和转储。

有关可加快 AKS 之旅的自动化程度更高的解决方案,请参阅在 Azure Kubernetes 服务 (AKS) 群集上使用 Open Liberty/WebSphere Liberty 部署 Java 应用程序

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

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

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

先决条件

  • Azure 订阅。 如果还没有 Azure 订阅,可以在开始前创建一个免费帐户
  • 准备安装了 Windows、macOS 或 Linux 的本地计算机。

登录 Azure

如果尚未这样做,请使用 az login 命令登录到 Azure 订阅,并按照屏幕上的指示操作。

az login

注意

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

如果多个 Azure 租户与你的 Azure 凭据关联,必须指定要登录到哪个租户。 可以通过 --tenant 选项执行此操作。 例如,az login --tenant contoso.onmicrosoft.com

创建资源组

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

在位置中创建使用 az group create 命令调用java-liberty-projecteastus2资源组。 此资源组稍后用于创建Azure 容器注册表实例和 AKS 群集。

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

创建容器注册表实例

使用 az acr create 命令以创建容器注册表实例。 以下示例创建名为 youruniqueacrname 的容器注册表实例。 请确保 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",

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

export LOGIN_SERVER=$(az acr show \
    --name $REGISTRY_NAME \
    --query 'loginServer' \
    --output tsv)

创建 AKS 群集

使用 az aks create 命令创建 AKS 群集。 以下示例创建一个名为一个节点的群集 myAKSCluster 。 此命令需要几分钟才能完成。

export CLUSTER_NAME=myAKSCluster
az aks create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-count 1 \
    --generate-ssh-keys \
    --enable-managed-identity

数分钟后,命令完成并返回有关群集的 JSON 格式信息,包括以下内容:

  "nodeResourceGroup": "MC_java-liberty-project_myAKSCluster_eastus2",
  "privateFqdn": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "java-liberty-project",

将容器注册表实例附加到 AKS 群集

运行 az aks update 命令,将容器注册表实例附加到 AKS 群集,以便对 AKS 群集进行身份验证以从容器注册表实例拉取映像,如以下示例所示:

az aks update \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --attach-acr $REGISTRY_NAME

连接到 AKS 群集

若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 若要在本地安装 kubectl,请使用 az aks install-cli 命令,如以下示例所示:

az aks install-cli

若要将 kubectl 配置为连接到 Kubernetes 群集,请使用 az aks get-credentials 命令。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。

az aks get-credentials \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --overwrite-existing \
    --admin

注意

以上命令使用 Kubernetes 配置文件的默认位置,即 ~/.kube/config。 可以使用 --file 为 Kubernetes 配置文件指定不同的位置。

若要验证与群集的连接,请使用 kubectl get 命令返回群集节点列表。

kubectl get nodes

以下示例输出显示在上一步创建的单个节点。 请确保节点的状态为 Ready

NAME                                STATUS   ROLES   AGE     VERSION
aks-nodepool1-xxxxxxxx-yyyyyyyyyy   Ready    <none>  76s     v1.29.9

创建 Azure SQL 数据库

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

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

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

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

export ENTRA_ADMIN_NAME=$(az ad signed-in-user show --query userPrincipalName --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 了解详细信息。

使用服务连接器在 AKS 中创建服务连接

运行以下命令,通过服务连接器使用 Microsoft Entra Workload ID 在 AKS 群集与 SQL 数据库之间创建连接。 有关详细信息,请参阅使用服务连接器在 AKS 中创建服务连接(预览版)。

# Register the Service Connector and Kubernetes Configuration resource providers
az provider register --namespace Microsoft.ServiceLinker --wait
az provider register --namespace Microsoft.KubernetesConfiguration --wait

# Install the Service Connector passwordless extension
az extension add --name serviceconnector-passwordless --upgrade --allow-preview true

# Retrieve the AKS cluster and Azure SQL Server resource IDs
export AKS_CLUSTER_RESOURCE_ID=$(az aks show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --query id \
    --output tsv)
export AZURE_SQL_SERVER_RESOURCE_ID=$(az sql server show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $SQL_SERVER_NAME \
    --query id \
    --output tsv)

# Create a user-assigned managed identity used for workload identity
export USER_ASSIGNED_IDENTITY_NAME=workload-identity-uami
az identity create \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${USER_ASSIGNED_IDENTITY_NAME}

# Retrieve the user-assigned managed identity resource ID
export UAMI_RESOURCE_ID=$(az identity show \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${USER_ASSIGNED_IDENTITY_NAME} \
    --query id \
    --output tsv)

# Create a service connection between your AKS cluster and your SQL database using Microsoft Entra Workload ID
az aks connection create sql \
    --connection akssqlconn \
    --client-type java \
    --source-id $AKS_CLUSTER_RESOURCE_ID \
    --target-id $AZURE_SQL_SERVER_RESOURCE_ID/databases/$DB_NAME \
    --workload-identity $UAMI_RESOURCE_ID

注意

它被重新建议使用 Microsoft Entra 工作负荷 ID 来保护对Azure SQL 数据库的访问,而无需使用 SQL 身份验证。 如果需要使用 SQL 身份验证,请忽略本节中的上述步骤,并使用用户名和密码连接到Azure SQL 数据库。

获取服务连接器创建的 servcie 帐户和机密

若要向Azure SQL 数据库进行身份验证,需要获取服务连接器创建的服务帐户和机密。 按照“更新容器”部分进行操作。 使用提供的 YAML 示例代码片段直接创建部署,并执行以下步骤:

  1. 从示例 Kubernetes 部署 YAML 中的突出显示部分复制 serviceAccountNamesecretRef.name 值,如以下示例所示:

    serviceAccountName: <service-account-name>
    containers:
    - name: raw-linux
       envFrom:
          - secretRef:
             name: <secret-name>
    
  2. 替换 <service-account-name><secret-name> 替换为在上一步中复制的值,以定义以下环境变量:

    export SERVICE_ACCOUNT_NAME=<service-account-name>
    export SECRET_NAME=<secret-name>
    

    下一部分中使用这些值将 Liberty 应用程序部署到 AKS 群集。

注意

服务连接器创建的机密包含AZURE_SQL_CONNECTIONSTRING一个密码免费连接字符串Azure SQL 数据库。 有关详细信息,请参阅用户分配的托管标识身份验证的示例值

安装 Open Liberty Operator

在本部分中,将在 AKS 群集上安装 Open Liberty 运算符来托管 Liberty 应用程序。

通过运行以下命令安装 Open Liberty Operator

# Install cert-manager Operator
CERT_MANAGER_VERSION=v1.11.2
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml

# Install Open Liberty Operator
export OPERATOR_VERSION=1.4.0
mkdir -p overlays/watch-all-namespaces
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/overlays/watch-all-namespaces/olo-all-namespaces.yaml -q -P ./overlays/watch-all-namespaces
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/overlays/watch-all-namespaces/cluster-roles.yaml -q -P ./overlays/watch-all-namespaces
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/overlays/watch-all-namespaces/kustomization.yaml -q -P ./overlays/watch-all-namespaces
mkdir base
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/base/kustomization.yaml -q -P ./base
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/base/open-liberty-crd.yaml -q -P ./base
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/base/open-liberty-operator.yaml -q -P ./base
wget https://raw.githubusercontent.com/OpenLiberty/open-liberty-operator/main/deploy/releases/${OPERATOR_VERSION}/kustomize/base/open-liberty-roles.yaml -q -P ./base
kubectl create namespace open-liberty
kubectl apply --server-side -k overlays/watch-all-namespaces

配置并生成应用程序映像

若要在 AKS 群集上部署并运行 Liberty 应用程序,请使用 Open Liberty 容器映像WebSphere Liberty 容器映像将应用程序容器化为 Docker 映像。

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

签出应用程序

克隆本指南的示例代码。 该示例位于 GitHub 上。 存储库中有一些示例。 本文使用 java-app 示例。 接下来会显示重要文件。

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

如果看到消息显示正处于“拆离的 HEAD”状态,可以放心地忽略此消息。 这只标识你签出了一个标签。

java-app
├─ src/main/
│  ├─ aks/
│  │  ├─ openlibertyapplication-passwordless-db.yaml
│  ├─ docker/
│  │  ├─ Dockerfile
│  │  ├─ Dockerfile-wlp
│  ├─ liberty/config/
│  │  ├─ server.xml
│  ├─ java/
│  ├─ resources/
│  ├─ webapp/
├─ pom.xml
├─ pom-azure-identity.xml

目录“java”、“resources”和“webapp”包含示例应用程序的源代码 。 代码声明并使用名为 jdbc/JavaEECafeDB 的数据源。

aks 目录中,文件 openlibertyapplication-passwordless-db.yaml 用于部署应用程序映像。 在 docker 目录中,有两个文件用于使用 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库对Azure SQL 数据库使用 Microsoft Entra 身份验证进行身份验证,建议出于安全考虑。 如果需要在 Liberty 应用程序中使用 SQL 身份验证,请参阅 JDBC 的关系数据库连接了解详细信息。

生成项目

收集必要的属性后,可以生成应用程序。 项目的 POM 文件从环境中读取多个变量。 在 Maven 生成中,这些变量用于填充位于 src/main/aks 中的 YAML 文件中的值。 如果需要,可以在 Maven 外部为应用程序执行类似操作。

cd $BASE_DIR/java-app

# The following variables are used for deployment file generation into target/
export LOGIN_SERVER=${LOGIN_SERVER}
export SC_SERVICE_ACCOUNT_NAME=${SERVICE_ACCOUNT_NAME}
export SC_SECRET_NAME=${SECRET_NAME}

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

在本地测试项目

现在可以在部署到 Azure 之前,在本地运行和测试项目。 为方便起见,使用 liberty-maven-plugin。 如需详细了解 liberty-maven-plugin,请参阅使用 Maven 构建 Web 应用程序。 对于你的应用程序,可以使用任何其他机制(例如本地 IDE)执行类似操作。 还可以考虑使用用于容器开发的 liberty:devc 选项。 可以在 Liberty 文档中详细了解 liberty:devc

注意

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

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

    cd $BASE_DIR/java-app
    
    # The value of environment variable AZURE_SQL_CONNECTIONSTRING is read by 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] CWWKZ0003I: The application javaee-cafe updated in 1.930 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

为 AKS 部署生成映像

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

cd $BASE_DIR/java-app/target

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

az acr build 命令将 Dockerfile 中指定的项目上传到容器注册表实例,生成映像,并将其存储在容器注册表实例中。

将应用程序部署到 AKS 群集

使用以下步骤在 AKS 群集上部署 Liberty 应用程序:

  1. 通过运行以下命令应用部署文件:

    cd $BASE_DIR/java-app/target
    
    # Apply deployment file
    kubectl apply -f openlibertyapplication-passwordless-db.yaml
    
  2. 通过运行以下命令确定是否创建了 OpenLibertyApplication 实例:

    kubectl get openlibertyapplication javaee-cafe-cluster
    

    应会看到与如下示例类似的输出:

    NAME                  IMAGE                                        EXPOSED   RECONCILED   RESOURCESREADY   READY   WARNING   AGE
    javaee-cafe-cluster   jiangma102924acr.azurecr.io/javaee-cafe:v1             True         True             True              57s
    
  3. 运行以下命令,确定 Operator 创建的部署是否已准备就绪:

    kubectl get deployment javaee-cafe-cluster --watch
    

    应会看到与如下示例类似的输出:

    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    javaee-cafe-cluster         0/3     3            0           20s
    
  4. 等到在 READY 列下方看到 3/3,在 AVAILABLE 列下方看到 3,然后使用 Ctrl+C 停止 kubectl 监视进程。

测试应用程序

在应用程序运行时,Kubernetes 负载均衡器服务会将向 Internet 公开应用程序前端。 此进程可能需要一段时间才能完成。

要监视进度,请使用带有 --watch 参数的 kubectl get service 命令,如以下示例所示:

kubectl get service javaee-cafe-cluster --watch

应会看到与如下示例类似的输出:

NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
javaee-cafe-cluster         LoadBalancer   10.0.251.169   52.152.189.57   80:31732/TCP     68s

EXTERNAL-IP 地址从挂起更改为实际的公共 IP 地址后,使用 Ctrl+C 停止 kubectl 监视进程。

如果在执行本节和上一节中的步骤之间经过了一段时间,请确保数据库处于活动状态(如有必要)。 请参阅关于数据库暂停的之前注释。

打开 Web 浏览器访问服务的外部 IP 地址(上面示例中的 52.152.189.57),以查看应用程序主页。 如果页面加载不正确,那是因为应用正在启动。 可以等待一段时间,稍后刷新页面。 你应该会看到应用程序副本的 Pod 名称显示在该页面的左上角。 请等待几分钟并刷新该页面,以查看由于 AKS 群集提供的负载均衡而显示的不同的 Pod 名称。

Java Liberty 应用程序已成功部署在 AKS 上。

注意

目前,该应用程序不使用 HTTPS。 我们建议你使用自己的证书启用 TLS。 有关详细信息,请参阅将 TLS 用于 Azure Kubernetes 服务 (AKS) 上的入口控制器

清理资源

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

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

后续步骤

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

若要将 Azure Cache for Redis 整合到 Java 应用中,请参阅在 Java 中将 Azure Cache for Redis 与 Reis Redis 客户端配合使用

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