你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将 AWS 事件驱动的工作流 (EDW) 工作负载部署到 Azure

在本文中,将 AWS EDW 工作负载部署到 Azure。

登录 Azure

  1. 使用 az login 命令登录到 Azure。

    az login
    
  2. 如果你的 Azure 帐户有多个订阅,请确保选择正确的订阅。 使用 az account list 命令列出订阅的名称和 ID。

    az account list --query "[].{id: id, name:name }" --output table
    
  3. 使用 az account set 命令选择特定订阅。

    az account set --subscription $subscriptionId
    

EDW 工作负载部署脚本

查看文件 deployment/environmentVariables.sh 中的环境变量,然后使用 GitHub 存储库deployment/infra/ 目录中的 deploy.sh 脚本将应用程序部署到 Azure。

该脚本首先检查是否安装了所有必备工具。 否则,脚本将终止并显示一条错误消息,告知你缺少哪些先决条件。 如果发生这种情况,请查看先决条件,安装任何缺少的工具,然后再次运行脚本。 必须在 Azure 订阅中注册 AKS 节点自动预配 (NAP) 功能标志。 如果尚未注册,脚本将执行 Azure CLI 命令来注册功能标志。

该脚本将部署状态记录在名为 deploy.state 的文件中,该文件位于 deployment 目录中。 部署应用时,可以使用此文件设置环境变量。

当脚本执行命令来配置工作流的基础结构时,它会检查每个命令是否成功执行。 如果发生任何问题,将显示错误消息,并停止执行。

脚本在运行时显示日志。 可以使用以下命令将日志信息输出重定向并保存到 logs 目录中的 install.log 文件,从而保留日志:

mkdir ./logs
./deployment/infra/deploy.sh | tee ./logs/install.log

有关详细信息,请参阅 GitHub 存储库中的 ./deployment/infra/deploy.sh 脚本。

工作负荷资源

部署脚本创建以下 Azure 资源:

  • Azure 资源组:存储部署脚本创建的资源的 Azure 资源组

  • Azure 存储帐户:Azure 存储帐户,其中包含生成者应用发送消息并由使用者应用读取的队列,以及使用者应用存储已处理消息的表。

  • Azure 容器注册表:容器注册表为部署重构的使用者应用代码的容器提供存储库。

  • Azure Kubernetes 服务 (AKS) 群集:AKS 群集为使用者应用容器提供 Kubernetes 业务流程,并启用了以下功能:

    • 节点自动预配 (NAP):在 AKS 上实现 Karpenter 节点自动缩放程序。
    • Kubernetes 事件驱动的自动缩放 (KEDA)KEDA 支持基于事件的 Pod 缩放,例如超过指定的队列深度阈值。
    • 工作负载标识:允许将基于角色的访问策略附加到 Pod 标识,以提高安全性。
    • 附加的 Azure 容器注册表:此功能允许 AKS 群集从指定 ACR 实例的存储库中拉取映像。
  • 应用程序和系统节点池:该脚本还会在 AKS 群集中创建应用程序和系统节点池,该群集有一个污点可防止在系统节点池中调度应用程序 Pod。

  • AKS 群集托管标识:脚本将 acrPull 角色分配给此托管标识,这有助于访问附加的 Azure 容器注册表以拉取映像。

  • 工作负载标识:脚本分配“存储队列数据参与者”和“存储表数据参与者”角色来提供对此托管标识的基于角色的访问控制 (RBAC) 访问权限,该标识与用作部署使用者应用容器的 Pod 的标识的 Kubernetes 服务帐户相关联。

  • 两个联合凭据:一个凭据允许托管标识实现 Pod 标识,另一个凭据用于 KEDA 操作员服务帐户,以提供对 KEDA 缩放程序的访问权限,从而收集控制 Pod 自动缩放所需的指标。

验证部署并运行工作负载

部署脚本完成后,可以在 AKS 群集上部署工作负载。

  1. 使用以下命令设置用于收集和更新 ./deployment/environmentVariables.sh 环境变量的源:

    source ./deployment/environmentVariables.sh
    
  2. 需要 ./deployment/deploy.state 文件中的信息来为部署中创建的资源的名称设置环境变量。 使用以下 cat 命令显示文件的内容:

    cat ./deployment/deploy.state
    

    输出应显示以下变量:

    SUFFIX=
    RESOURCE_GROUP=
    AZURE_STORAGE_ACCOUNT_NAME=
    AZURE_QUEUE_NAME=
    AZURE_COSMOSDB_TABLE=
    AZURE_CONTAINER_REGISTRY_NAME=
    AKS_MANAGED_IDENTITY_NAME=
    AKS_CLUSTER_NAME=
    WORKLOAD_MANAGED_IDENTITY_NAME=
    SERVICE_ACCOUNT=
    FEDERATED_IDENTITY_CREDENTIAL_NAME=
    KEDA_SERVICE_ACCT_CRED_NAME=
    
  3. 使用以下命令读取文件并为部署脚本创建的 Azure 资源的名称创建环境变量:

    while IFS= read -r; line do \
    echo "export $line" \
    export $line; \
    done < ./deployment/deploy.state
    
  4. 使用 az aks get-credentials 命令获取 AKS 群集凭据。

    az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKS_CLUSTER_NAME
    
  5. 使用 kubectl get 命令验证 KEDA 运算符 Pod 是否在 AKS 群集上的 kube-system 命名空间中运行。

    kubectl get pods --namespace kube-system | grep keda
    

    输出应类似于以下示例输出:

    屏幕截图显示命令的示例响应,用于验证 KEDA 运算符 Pod 是否正在运行。

生成模拟负载

现在,使用生成者应用生成模拟负载,将消息填充到队列中。

  1. 在单独的终端窗口中,导航到项目目录。

  2. 使用上一节中的步骤设置环境变量。 1. 请使用以下命令运行生成者应用:

    python3 ./app/keda/aqs-producer.py
    
  3. 应用开始发送消息后,切换回另一个终端窗口。

  4. 使用以下命令将使用者应用容器部署到 AKS 群集:

    chmod +x ./deployment/keda/deploy-keda-app-workload-id.sh
    ./deployment/keda/deploy-keda-app-workload-id.sh
    

    部署脚本 (deploy-keda-app-workload-id.sh) 对应用程序清单 YAML 规范执行模板化,以将环境变量传递给 Pod。 查看此脚本的以下摘录:

    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: $AQS_TARGET_DEPLOYMENT
      namespace: $AQS_TARGET_NAMESPACE
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aqs-reader
      template:
        metadata:
          labels:
            app: aqs-reader
            azure.workload.identity/use: "true"
        spec:
          serviceAccountName: $SERVICE_ACCOUNT
          containers:
          - name: keda-queue-reader
            image: ${AZURE_CONTAINER_REGISTRY_NAME}.azurecr.io/aws2azure/aqs-consumer
            imagePullPolicy: Always
            env:
            - name: AZURE_QUEUE_NAME
              value: $AZURE_QUEUE_NAME
            - name: AZURE_STORAGE_ACCOUNT_NAME
              value: $AZURE_STORAGE_ACCOUNT_NAME
            - name: AZURE_TABLE_NAME
              value: $AZURE_TABLE_NAME
            resources:
              requests:
                memory: "64Mi"
                cpu: "250m"
              limits:
                memory: "128Mi"
                cpu: "500m"
    EOF
    

    spec/template 部分中的 azure.workload.identity/use 标签是部署的 Pod 模板。 将标签设置为 true 将指定正在使用工作负载标识。 Pod 规范中的 serviceAccountName 指定要与工作负载标识关联的 Kubernetes 服务帐户。 虽然 Pod 规范包含专用存储库中映像的引用,但没有指定 imagePullSecret

  5. 使用 kubectl get 命令验证脚本已成功运行。

    kubectl get pods --namespace $AQS_TARGET_NAMESPACE
    

    输出中应会显示单个 Pod。

  6. 验证是否已创建 Karpenter 节点池。 使用 kubectl get nodepool 命令执行此操作。 命令响应如下所示:

    显示 Karpenter 节点池创建示例的屏幕截图。

    使用 kubectl describe nodepool 命令验证默认节点池是否为 Karpenter 节点池。 在命令响应中,可以验证节点池是否为 Karpenter 节点池。 你应看到与下面类似的内容:

    显示节点池响应的屏幕截图,包括标记为 karpenter 的 API 版本。

使用 k9s 监视 Pod 和节点的横向扩展

可以使用各种工具来验证部署到 AKS 的应用的操作,包括 Azure 门户和 k9s。 有关 k9s 的详细信息,请参阅 k9s 概述

  1. 使用 k9s 安装概述中环境的相应指南在 AKS 群集上安装 k9s。

  2. 创建两个窗口,一个显示 Pod 视图,另一个窗口显示 AQS_TARGET_NAMESPACE 环境变量中指定的命名空间中的节点视图(默认值为 aqs-demo),并在每个窗口中启动 k9s。

    此时会看到如下所示的内容:

    屏幕截图显示两个窗口的 K9s 视图示例。

  3. 确认使用者应用容器已安装并在 AKS 群集上运行后,通过运行缩放对象安装脚本 (keda-scaleobject-workload-id.sh),安装 KEDA 用于 Pod 自动缩放的 ScaledObject 并触发身份验证。 使用以下命令:

    chmod +x ./deployment/keda/keda-scaleobject-workload-id.sh
    ./deployment/keda/keda-scaleobject-workload-id.sh
    

    该脚本还会执行模板化,以在需要时注入环境变量。 查看此脚本的以下摘录:

    cat <<EOF | kubectl apply -f -
    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: aws2az-queue-scaleobj
      namespace: ${AQS_TARGET_NAMESPACE}
    spec:
      scaleTargetRef:
        name: ${AQS_TARGET_DEPLOYMENT}     #K8s deployement to target
      minReplicaCount: 0  # We don't want pods if the queue is empty nginx-deployment
      maxReplicaCount: 15 # We don't want to have more than 15 replicas
      pollingInterval: 30 # How frequently we should go for metrics (in seconds)
      cooldownPeriod:  10 # How many seconds should we wait for downscale
      triggers:
      - type: azure-queue
        authenticationRef:
          name: keda-az-credentials
        metadata:
          queueName: ${AZURE_QUEUE_NAME}
          accountName: ${AZURE_STORAGE_ACCOUNT_NAME}
          queueLength: '5'
          activationQueueLength: '20' # threshold for when the scaler is active
          cloud: AzurePublicCloud
    ---
    apiVersion: keda.sh/v1alpha1
    kind: TriggerAuthentication
    metadata:
      name: keda-az-credentials
      namespace: $AQS_TARGET_NAMESPACE
    spec:
      podIdentity:
        provider: azure-workload
        identityId: '${workloadManagedIdentityClientId}'
    EOF
    

    清单描述了两个资源:TriggerAuthentication 对象,该对象向 KEDA 指定缩放对象使用 Pod 标识进行身份验证,identityID 属性,该属性指用作工作负载标识的托管标识。

    正确安装缩放对象且 KEDA 检测到超出缩放阈值时,它将开始调度 pod。 如果使用 k9s,应会看到如下内容:

    屏幕截图显示调度 Pod 的 K9s 视图示例。

    如果你允许生成者使用足够的消息填充队列,那么 KEDA 可能需要调度比节点要提供的 Pod 更多的 Pod。 为了适应这一情况,Karpenter 将启动调度节点。 如果使用 k9s,应会看到如下内容:

    屏幕截图显示调度节点的 K9s 视图示例。

    在这两个映像中,请注意名称包含 aks-default 的节点数如何从一个节点增加到三个节点。 如果阻止生成者应用将消息放在队列上,最终使用者会将队列深度降低到阈值以下,KEDA 和 Karpenter 都将缩小。 如果使用 k9s,应会看到如下内容:

    屏幕截图显示减少了队列深度的 K9s 视图示例。

  4. 最后,可以使用 kubectl get events 命令查看 Karpenter 自动缩放活动,如下所示:

    显示 kubectl 命令示例的屏幕截图。

清理资源

可以在 GitHub 存储库中使用清理脚本 (/deployment/infra/cleanup.sh),以删除创建的所有资源。

后续步骤

有关在 AKS 中开发和运行应用程序的详细信息,请参阅以下资源:

供稿人

Microsoft 会维护本文。 本系列文章为以下参与者的原创作品:

  • Ken Kilty | 首席 TPM
  • Russell de Pina | 首席 TPM
  • Jenny Hayes | 高级内容开发人员
  • Carol Smith | 高级内容开发人员
  • Erin Schaffer | 内容开发人员 2