使用 Azure Kubernetes 服务 (AKS) 上的 KEDA 加载项和工作负载标识安全地缩放应用程序

本文介绍如何使用 Azure Kubernetes 服务 (AKS) 上的 Kubernetes 事件驱动的自动缩放 (KEDA) 加载项和工作负载标识安全地缩放应用程序。

重要

群集 Kubernetes 版本确定将在 AKS 群集上安装哪些 KEDA 版本。 若要查看哪些 KEDA 版本映射到每个 AKS 版本,请参阅 Kubernetes 组件版本表的“AKS 托管附加产品”列。

对于 GA Kubernetes 版本,AKS 提供对表中相应 KEDA 次要版本的完全支持。 客户支持部门会尽力为 Kubernetes 预览版和最新的 KEDA 修补程序提供部分支持。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

开始之前

创建资源组

  • 使用 az group create 命令创建资源组。 请务必将占位符值替换为你自己的值。

    LOCATION=<azure-region>
    RG_NAME=<resource-group-name>
    
    az group create --name $RG_NAME --location $LOCATION
    

创建 AKS 群集

  1. 使用带有 --enable-workload-identity--enable-keda--enable-oidc-issuer 标志的 az aks create 命令创建启用了 KEDA 加载项、工作负载标识和 OIDC 颁发者的 AKS 群集。 请务必将占位符值替换为你自己的值。

    AKS_NAME=<cluster-name>
    
    az aks create \
        --name $AKS_NAME \
        --resource-group $RG_NAME \
        --enable-workload-identity \
        --enable-oidc-issuer \
        --enable-keda \
        --generate-ssh-keys 
    
  2. 验证部署是否成功,并确保使用 --query 标志设置为 "[workloadAutoScalerProfile, securityProfile, oidcIssuerProfile]"az aks show 命令为群集启用了 KEDA、工作负载标识和 OIDC 颁发者。

    az aks show \
        --name $AKS_NAME \
        --resource-group $RG_NAME \
        --query "[workloadAutoScalerProfile, securityProfile, oidcIssuerProfile]"
    
  3. 使用 az aks get-credentials 命令连接到群集。

    az aks get-credentials \
        --name $AKS_NAME \
        --resource-group $RG_NAME \
        --overwrite-existing
    

创建 Azure 服务总线

  1. 使用 az servicebus namespace create 命令创建 Azure 服务总线命名空间。 请务必将占位符值替换为你自己的值。

    SB_NAME=<service-bus-name>
    SB_HOSTNAME="${SB_NAME}.servicebus.chinacloudapi.cn"
    
    az servicebus namespace create \
        --name $SB_NAME \
        --resource-group $RG_NAME \
        --disable-local-auth
    
  2. 使用 az servicebus queue create 命令创建 Azure 服务总线队列。 请务必将占位符值替换为你自己的值。

    SB_QUEUE_NAME=<service-bus-queue-name>
    
    az servicebus queue create \
        --name $SB_QUEUE_NAME \
        --namespace $SB_NAME \
        --resource-group $RG_NAME
    

创建托管标识

  1. 使用 az identity create 命令创建托管标识。 请务必将占位符值替换为你自己的值。

    MI_NAME=<managed-identity-name>
    
    MI_CLIENT_ID=$(az identity create \
        --name $MI_NAME \
        --resource-group $RG_NAME \
        --query "clientId" \
        --output tsv)
    
  2. 使用 az aks show 命令并将 --query 标志设置为 oidcIssuerProfile.issuerUrl 获取 OIDC 颁发者 URL。

    AKS_OIDC_ISSUER=$(az aks show \
        --name $AKS_NAME \
        --resource-group $RG_NAME \
        --query oidcIssuerProfile.issuerUrl \
        --output tsv)
    
  3. 使用 az identity federated-credential create 命令在托管标识与工作负载使用的命名空间和服务帐户之间创建联合凭据。 请务必将占位符值替换为你自己的值。

    FED_WORKLOAD=<federated-credential-workload-name>
    
    az identity federated-credential create \
        --name $FED_WORKLOAD \
        --identity-name $MI_NAME \
        --resource-group $RG_NAME \
        --issuer $AKS_OIDC_ISSUER \
        --subject system:serviceaccount:default:$MI_NAME \
        --audience api://AzureADTokenExchange
    
  4. 使用 az identity federated-credential create 命令在托管标识与 keda-operator 使用的命名空间和服务帐户之间创建第二个联合凭据。 请务必将占位符值替换为你自己的值。

    FED_KEDA=<federated-credential-keda-name>
    
    az identity federated-credential create \
        --name $FED_KEDA \
        --identity-name $MI_NAME \
        --resource-group $RG_NAME \
        --issuer $AKS_OIDC_ISSUER \
        --subject system:serviceaccount:kube-system:keda-operator \
        --audience api://AzureADTokenExchange
    

创建角色分配

  1. 使用 az identity show 命令并将 --query 标志设置为 "principalId" 获取托管标识的对象 ID。

    MI_OBJECT_ID=$(az identity show \
        --name $MI_NAME \
        --resource-group $RG_NAME \
        --query "principalId" \
        --output tsv)
    
  2. 使用 az servicebus namespace show 命令并将 --query 标志设置为 "id" 获取服务总线命名空间资源 ID。

    SB_ID=$(az servicebus namespace show \
        --name $SB_NAME \
        --resource-group $RG_NAME \
        --query "id" \
        --output tsv)
    
  3. 使用 az role assignment create 命令将 Azure 服务总线数据所有者角色分配给托管标识。

    az role assignment create \
        --role "Azure Service Bus Data Owner" \
        --assignee-object-id $MI_OBJECT_ID \
        --assignee-principal-type ServicePrincipal \
        --scope $SB_ID
    

在 KEDA 运算符上启用工作负载标识

  1. keda-operator ServiceAccount 创建联合凭据后,需要手动重启 keda-operator Pod,以确保将工作负载标识环境变量注入 Pod。

    kubectl rollout restart deploy keda-operator -n kube-system
    
  2. 确认 keda-operator Pod 重启

    kubectl get pod -n kube-system -lapp=keda-operator -w
    
  3. 确认 keda-operator Pod 已完成滚动后,按 Ctrl+c 中断上一个监视命令,然后确认已注入工作负载标识环境变量。

    KEDA_POD_ID=$(kubectl get po -n kube-system -l app.kubernetes.io/name=keda-operator -ojsonpath='{.items[0].metadata.name}')
    kubectl describe po $KEDA_POD_ID -n kube-system
    
  4. 你应该会在“环境”下看到与以下内容类似的输出。

    ---
    AZURE_CLIENT_ID:
    AZURE_TENANT_ID:               xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
    AZURE_FEDERATED_TOKEN_FILE:    /var/run/secrets/azure/tokens/azure-identity-token
    AZURE_AUTHORITY_HOST:          https://login.partner.microsoftonline.cn/
    ---
    
  5. 部署包含用户分配的托管标识的客户端 ID 的 KEDA TriggerAuthentication 资源。

    kubectl apply -f - <<EOF
    apiVersion: keda.sh/v1alpha1
    kind: TriggerAuthentication
    metadata:
      name: azure-servicebus-auth
      namespace: default  # this must be same namespace as the ScaledObject/ScaledJob that will use it
    spec:
      podIdentity:
        provider:  azure-workload
        identityId: $MI_CLIENT_ID
    EOF
    

    注意

    有了 TriggerAuthentication 后,KEDA 将能够通过工作负载标识进行身份验证。 评估缩放触发器时,keda-operator Pod 使用 identityId 对 Azure 资源进行身份验证。

将消息发布到 Azure 服务总线

此时,一切都已配置好,可以使用 KEDA 和 Microsoft Entra 工作负载标识进行缩放。 我们将通过部署生成者和使用者工作负载来测试这一点。

  1. 为工作负载创建新的 ServiceAccount。

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        azure.workload.identity/client-id: $MI_CLIENT_ID
      name: $MI_NAME
    EOF
    
  2. 部署一个作业以发布 100 条消息。

    kubectl apply -f - <<EOF
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: myproducer
    spec:
      template:
        metadata:
          labels:
            azure.workload.identity/use: "true"
        spec:
          serviceAccountName: $MI_NAME
          containers:
          - image: ghcr.io/azure-samples/aks-app-samples/servicebusdemo:latest
            name: myproducer
            resources: {}
            env:
            - name: OPERATION_MODE
              value: "producer"
            - name: MESSAGE_COUNT
              value: "100"
            - name: AZURE_SERVICEBUS_QUEUE_NAME
              value: $SB_QUEUE_NAME
            - name: AZURE_SERVICEBUS_HOSTNAME
              value: $SB_HOSTNAME
          restartPolicy: Never
    EOF
    

从 Azure 服务总线中使用消息

现在,我们已将消息发布到 Azure 服务总线队列,接下来将部署 ScaledJob 以使用消息。 此 ScaledJob 将使用 KEDA TriggerAuthentication 资源通过工作负载标识对 Azure 服务总线队列进行身份验证,并在每处理 10 条消息时横向扩展。

  1. 部署一个 ScaledJob 资源以使用消息。 缩放触发器将配置为每 10 条消息进行一次横向扩展。 KEDA 缩放器将创建 10 个作业以使用 100 条消息。

    kubectl apply -f - <<EOF
    apiVersion: keda.sh/v1alpha1
    kind: ScaledJob
    metadata:
      name: myconsumer-scaledjob
    spec:
      jobTargetRef:
        template:
          metadata:
            labels:
              azure.workload.identity/use: "true"
          spec:
            serviceAccountName: $MI_NAME
            containers:
            - image: ghcr.io/azure-samples/aks-app-samples/servicebusdemo:latest
              name: myconsumer
              env:
              - name: OPERATION_MODE
                value: "consumer"
              - name: MESSAGE_COUNT
                value: "10"
              - name: AZURE_SERVICEBUS_QUEUE_NAME
                value: $SB_QUEUE_NAME
              - name: AZURE_SERVICEBUS_HOSTNAME
                value: $SB_HOSTNAME
            restartPolicy: Never
      triggers:
      - type: azure-servicebus
        metadata:
          queueName: $SB_QUEUE_NAME
          namespace: $SB_NAME
          messageCount: "10"
        authenticationRef:
          name: azure-servicebus-auth
    EOF
    

    注意

    ScaledJob 会在发生缩放事件时创建 Kubernetes 作业资源,因此在创建资源时需要传入作业模板。 创建新作业时,将使用工作负载标识位部署 Pod,以使用消息。

  2. 验证 KEDA 缩放器是否按预期工作。

    kubectl describe scaledjob myconsumer-scaledjob
    
  3. 应看到类似于以下内容的事件。

    Events:
    Type     Reason              Age   From           Message
    ----     ------              ----  ----           -------
    Normal   KEDAScalersStarted  10m   scale-handler  Started scalers watch
    Normal   ScaledJobReady      10m   keda-operator  ScaledJob is ready for scaling
    Warning  KEDAScalerFailed    10m   scale-handler  context canceled
    Normal   KEDAJobsCreated     10m   scale-handler  Created 10 jobs
    

清理资源

验证部署成功后,可以清理资源以避免产生 Azure 成本。

  1. 使用 [az group delete][az-group-delete] 命令删除 Azure 资源组及其中所有资源。

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

后续步骤

本文介绍了如何使用 AKS 中的 KEDA 加载项和工作负载标识安全地缩放应用程序。

有关 KEDA 故障排除的信息,请参阅排查 Kubernetes 事件驱动的自动缩放 (KEDA) 加载项

若要了解有关 KEDA 的详细信息,请参阅上游 KEDA 文档