使用 Azure Kubernetes 服务 (AKS) 上的 KEDA 加载项和工作负载标识安全地缩放应用程序
本文介绍如何使用 Azure Kubernetes 服务 (AKS) 上的 Kubernetes 事件驱动的自动缩放 (KEDA) 加载项和工作负载标识安全地缩放应用程序。
重要
群集 Kubernetes 版本确定将在 AKS 群集上安装哪些 KEDA 版本。 若要查看哪些 KEDA 版本映射到每个 AKS 版本,请参阅 Kubernetes 组件版本表的“AKS 托管附加产品”列。
对于 GA Kubernetes 版本,AKS 提供对表中相应 KEDA 次要版本的完全支持。 客户支持部门会尽力为 Kubernetes 预览版和最新的 KEDA 修补程序提供部分支持。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
开始之前
- 需要一个 Azure 订阅。 如果你没有 Azure 订阅,可以创建一个试用版订阅。
- 需要安装 Azure CLI。
- 确保你的防火墙规则配置为允许访问 Kubernetes API 服务器。 有关详细信息,请参阅适用于 Azure Kubernetes 服务 (AKS) 群集的出站网络和 FQDN 规则。
创建资源组
使用
az group create
命令创建资源组。 请务必将占位符值替换为你自己的值。LOCATION=<azure-region> RG_NAME=<resource-group-name> az group create --name $RG_NAME --location $LOCATION
创建 AKS 群集
使用带有
--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
验证部署是否成功,并确保使用
--query
标志设置为"[workloadAutoScalerProfile, securityProfile, oidcIssuerProfile]"
的az aks show
命令为群集启用了 KEDA、工作负载标识和 OIDC 颁发者。az aks show \ --name $AKS_NAME \ --resource-group $RG_NAME \ --query "[workloadAutoScalerProfile, securityProfile, oidcIssuerProfile]"
使用
az aks get-credentials
命令连接到群集。az aks get-credentials \ --name $AKS_NAME \ --resource-group $RG_NAME \ --overwrite-existing
创建 Azure 服务总线
使用
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
使用
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
创建托管标识
使用
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)
使用
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)
使用
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
使用
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
创建角色分配
使用
az identity show
命令并将--query
标志设置为"principalId"
获取托管标识的对象 ID。MI_OBJECT_ID=$(az identity show \ --name $MI_NAME \ --resource-group $RG_NAME \ --query "principalId" \ --output tsv)
使用
az servicebus namespace show
命令并将--query
标志设置为"id"
获取服务总线命名空间资源 ID。SB_ID=$(az servicebus namespace show \ --name $SB_NAME \ --resource-group $RG_NAME \ --query "id" \ --output tsv)
使用
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 运算符上启用工作负载标识
为
keda-operator
ServiceAccount 创建联合凭据后,需要手动重启keda-operator
Pod,以确保将工作负载标识环境变量注入 Pod。kubectl rollout restart deploy keda-operator -n kube-system
确认 keda-operator Pod 重启
kubectl get pod -n kube-system -lapp=keda-operator -w
确认 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
你应该会在“环境”下看到与以下内容类似的输出。
--- 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/ ---
部署包含用户分配的托管标识的客户端 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 工作负载标识进行缩放。 我们将通过部署生成者和使用者工作负载来测试这一点。
为工作负载创建新的 ServiceAccount。
kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: $MI_CLIENT_ID name: $MI_NAME EOF
部署一个作业以发布 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 条消息时横向扩展。
部署一个 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,以使用消息。
验证 KEDA 缩放器是否按预期工作。
kubectl describe scaledjob myconsumer-scaledjob
应看到类似于以下内容的事件。
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 成本。
使用 [
az group delete
][az-group-delete] 命令删除 Azure 资源组及其中所有资源。az group delete --name $RG_NAME --yes --no-wait
后续步骤
本文介绍了如何使用 AKS 中的 KEDA 加载项和工作负载标识安全地缩放应用程序。
有关 KEDA 故障排除的信息,请参阅排查 Kubernetes 事件驱动的自动缩放 (KEDA) 加载项。
若要了解有关 KEDA 的详细信息,请参阅上游 KEDA 文档。