将 Spring Boot 应用程序与 Azure Cosmos DB for NoSQL 和 Azure Kubernetes 服务配合使用

注意

对于 Spring Boot 应用程序,我们建议使用 Azure Spring Apps。 但是,你仍然可以使用 Azure Kubernetes 服务作为目标。 请参阅 Java 工作负荷目标指南以获取建议。

在本教程中,你将设置并部署一个 Spring Boot 应用程序,该应用程序公开 REST API 以对 Azure Cosmos DB(NoSQL 帐户 API)中的数据执行 CRUD作。 将应用程序打包为 Docker 映像,将其推送到 Azure 容器注册表,部署到 Azure Kubernetes 服务并测试应用程序。

先决条件

创建 Azure 服务

在本部分中,你将创建本教程所需的 Azure 服务。

  • Azure Cosmos DB
  • Azure 容器注册表
  • Azure Kubernetes 服务

为本教程中使用的 Azure 资源创建资源组

  1. 使用 Azure CLI 登录到 Azure 帐户:

    az login
    
  2. 选择自己的 Azure 订阅:

    az account set -s <enter subscription ID>
    
  3. 创建资源组。

    az group create --name=cosmosdb-springboot-aks-rg --location=chinaeast
    

    注意

    cosmosdb-springboot-aks-rg 替换为资源组的唯一名称。

创建 Azure Cosmos DB for NoSQL 数据库帐户

通过 Azure CLI 使用此命令创建 Azure Cosmos DB for NoSQL 数据库帐户

az cosmosdb create --name <enter account name> --resource-group <enter resource group name>

使用 Azure CLI 创建专用 Azure 容器注册表

注意

用注册表的唯一名称替换 cosmosdbspringbootregistry

az acr create --resource-group cosmosdb-springboot-aks-rg --location chinaeast \
    --name cosmosdbspringbootregistry --sku Basic

使用 Azure CLI 在 AKS 上创建 Kubernetes 群集

  1. 以下命令在 cosmosdb-springboot-aks-rg 资源组中创建 Kubernetes 群集,该群集以 cosmosdb-springboot-aks 作为群集名称,并附加 Azure 容器注册表 (ACR)

    az aks create \
        --resource-group cosmosdb-springboot-aks-rg \
        --name cosmosdb-springboot-aks \
        --node-count 1 \
        --generate-ssh-keys \
        --attach-acr cosmosdbspringbootregistry \
        --dns-name-prefix=cosmosdb-springboot-aks-app
    

    注意

    此命令可能需要一段时间才能完成。

  2. 如果尚未安装 kubectl,可以使用 Azure CLI 进行安装。

    az aks install-cli
    
  3. 获取 Azure Kubernetes 服务群集的访问凭据。

    az aks get-credentials --resource-group=cosmosdb-springboot-aks-rg --name=cosmosdb-springboot-aks
    
    kubectl get nodes
    

构建应用程序

  1. 克隆应用程序并更改到正确的目录中。

    git clone https://github.com/Azure-Samples/cosmosdb-springboot-aks.git
    
    cd cosmosdb-springboot-aks
    
  2. 使用 Maven 生成应用程序。 在此步骤结束时,应在 target 文件夹中创建了应用程序 JAR 文件。

    ./mvnw install
    

在本地运行应用程序

若要在 Azure Kubernetes 服务中运行应用程序,请跳过本部分,并前往向 Azure 容器注册表推送 Docker 映像

  1. 运行应用程序之前,请使用 Azure Cosmos DB 帐户的详细信息更新 application.properties 文件。

    azure.cosmos.uri=https://<enter Azure Cosmos DB db account name>.cosmos.azure.cn:443/
    azure.cosmos.key=<enter Azure Cosmos DB db primary key>
    azure.cosmos.database=<enter Azure Cosmos DB db database name>
    azure.cosmos.populateQueryMetrics=false
    

    注意

    启动应用程序后,会自动创建数据库和容器(调用 users)。

  2. 在本地运行应用程序。

    java -jar target/*.jar
    

向 Azure 容器注册表推送 Docker 映像

  1. 生成 Docker 映像

    docker build -t cosmosdbspringbootregistry.azurecr.cn/spring-cosmos-app:v1 .
    

    注意

    cosmosdbspringbootregistry 替换为 Azure 容器注册表的名称

  2. 登录到 Azure 容器注册表。

    az acr login -n cosmosdbspringbootregistry
    
  3. 将映像推送到 Azure 容器注册表并列出该映像。

    docker push cosmosdbspringbootregistry.azurecr.cn/spring-cosmos-app:v1
    
    az acr repository list --name cosmosdbspringbootregistry --output table
    

将应用程序部署到 Azure Kubernetes 服务

  1. 使用 Azure Cosmos DB 设置的详细信息编辑 Secret 中的 app.yaml

    ...
    apiVersion: v1
    kind: Secret
    metadata:
      name: app-config
    type: Opaque
    stringData:
      application.properties: |
        azure.cosmos.uri=https://<enter Azure Cosmos DB db account name>.cosmos.azure.cn:443/
        azure.cosmos.key=<enter Azure Cosmos DB db primary key>
        azure.cosmos.database=<enter Azure Cosmos DB db database name>
        azure.cosmos.populateQueryMetrics=false
    ...
    

    注意

    启动应用程序后,会自动创建数据库和容器(users)。

  2. 部署到 Kubernetes 并等待 Pod 转换为 Running 状态:

    kubectl apply -f deploy/app.yaml
    
    kubectl get pods -l=app=spring-cosmos-app -w
    

    注意

    可以使用 kubectl logs -f $(kubectl get pods -l=app=spring-cosmos-app -o=jsonpath='{.items[0].metadata.name}') -c spring-cosmos-app 检查应用程序日志

访问应用程序

如果应用程序在 Kubernetes 中运行,并且想要通过端口 8080在本地访问它,请运行以下命令:

kubectl port-forward svc/spring-cosmos-app-internal 8080:8080

通过调用 REST 终结点来测试应用程序。 还可以导航到 Azure 门户中 Azure Cosmos DB 帐户的 Data Explorer 菜单,然后访问 users 容器以确认操作结果。

  1. 创建新用户

    curl -i -X POST -H "Content-Type: application/json" -d '{"email":"john.doe@foobar.com", "firstName": "John", "lastName": "Doe", "city": "NYC"}' http://localhost:8080/users
    
    curl -i -X POST -H "Content-Type: application/json" -d '{"email":"mr.jim@foobar.com", "firstName": "mr", "lastName": "jim", "city": "Seattle"}' http://localhost:8080/users
    

    如果操作成功,应会获取 HTTP 201 响应。

  2. 更新用户

    curl -i -X POST -H "Content-Type: application/json" -d '{"email":"john.doe@foobar.com", "firstName": "John", "lastName": "Doe", "city": "Dallas"}' http://localhost:8080/users
    
  3. 列出所有用户

    curl -i http://localhost:8080/users
    
  4. 获取现有用户

    curl -i http://localhost:8080/users/john.doe@foobar.com
    

    应会获取包含用户详细信息的 JSON 有效负载。 例如:

    {
      "email": "john.doe@foobar.com",
      "firstName": "John",
      "lastName": "Doe",
      "city": "Dallas"
    }
    
  5. 尝试获取不存在的用户

    curl -i http://localhost:8080/users/not.there@foobar.com
    

    应会收到 HTTP 404 响应。

  6. 替换用户

    curl -i -X PUT -H "Content-Type: application/json" -d '{"email":"john.doe@foobar.com", "firstName": "john", "lastName": "doe","city": "New Jersey"}' http://localhost:8080/users/
    
  7. 尝试替换不存在的用户

    curl -i -X PUT -H "Content-Type: application/json" -d '{"email":"not.there@foobar.com", "firstName": "john", "lastName": "doe","city": "New Jersey"}' http://localhost:8080/users/
    

    应会收到 HTTP 404 响应。

  8. 删除用户

    curl -i -X DELETE http://localhost:8080/users/mr.jim@foobar.com
    
  9. 删除不存在的用户

    curl -X DELETE http://localhost:8080/users/go.nuts@foobar.com
    

    应会收到 HTTP 404 响应。

使用公共 IP 地址访问应用程序(可选)

在 Azure Kubernetes 服务中创建类型类型的 LoadBalancer 服务会导致预配 Azure 负载均衡器。 然后,可以使用其公共 IP 地址访问应用程序。

  1. 创建 LoadBalancer 类型的 Kubernetes 服务

    注意

    此步骤创建具有公共 IP 地址的 Azure 负载均衡器。

    kubectl apply -f deploy/load-balancer-service.yaml
    
  2. 等待创建 Azure 负载均衡器。 在此之前, EXTERNAL-IP Kubernetes 服务的运行仍处于 <pending> 状态。

    kubectl get service spring-cosmos-app -w
    
    NAME                TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
    spring-cosmos-app   LoadBalancer   10.0.68.83   <pending>     8080:31523/TCP   6s
    

    注意

    CLUSTER-IP 值在案例中可能有所不同

  3. Azure 负载均衡器创建完成后, EXTERNAL-IP 即可使用。

    NAME                TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
    spring-cosmos-app   LoadBalancer   10.0.68.83   20.81.108.180   8080:31523/TCP   18s
    

    注意

    EXTERNAL-IP 值在案例中可能有所不同

  4. 使用公共 IP 地址

    kubectl watch终止进程,并使用公共 IP 地址和端口curl重复上述8080命令。 例如,若要列出所有用户:

     curl -i http://20.81.108.180:8080/users
    

    注意

    20.81.108.180 替换为环境的公共 IP 地址

用于此应用程序的 Kubernetes 资源

下面是有关用于此应用程序的 Kubernetes 资源的一些要点:

  • Spring Boot 应用程序是一项 Kubernetes Deployment,它基于 Azure 容器注册表中的 Docker 映像

  • Azure Cosmos DB 配置装载在application.properties/config 路径上的 中。

  • 可以使用 Kubernetes 实现此装载,而 Kubernetes Volume 又引用了随应用程序一起创建的 Kubernetes 机密。 可以运行以下命令以确认此文件存在于应用程序容器中:

    kubectl exec -it $(kubectl get pods -l=app=spring-cosmos-app -o=jsonpath='{.items[0].metadata.name}') -c spring-cosmos-app -- cat /config/application.properties
    
  • 此应用程序的运行情况探测和就绪情况探测配置即为将 Spring Boot 应用程序部署到 Kubernetes 环境时由 Spring Boot 执行器提供的 HTTP 终结点 - /actuator/health/liveness/actuator/health/readiness

  • 可以创建 ClusterIP 服务,以在 Kubernetes 群集内部访问 Spring Boot 应用程序的 REST 终结点。

  • 可以创建 LoadBalancer 服务,以通过公共 IP 地址访问应用程序。

清理资源

执行完应用和 Azure Cosmos DB 帐户的操作以后,可以删除所创建的 Azure 资源,以免产生更多费用。 若要删除资源,请执行以下操作:

  1. 在 Azure 门户的“搜索”栏中,搜索并选择“资源组”。

  2. 从列表中选择为本快速入门创建的资源组。

    选择要删除的资源组

  3. 在资源组“概览”页上,选择“删除资源组”。

    删除资源组

  4. 在下一窗口中输入要删除的资源组的名称,然后选择“删除”。

后续步骤