Gpu-Workloads auf AKS mit DCGM-Metriken und KEDA automatisch skalieren

In diesem Artikel erfahren Sie, wie Sie GPU-Workloads auf Azure Kubernetes Service (AKS) mithilfe von GPU-Metriken automatisch skalieren, die vom NVIDIA Data Center GPU Manager (DCGM)-Exporter gesammelt wurden. Diese Metriken werden über Azure Managed Prometheus verfügbar gemacht und von Kubernetes Event-Driven Autocaling (KEDA) genutzt, um Workloads basierend auf der GPU-Auslastung in Echtzeit automatisch zu skalieren. Diese Lösung hilft bei der Optimierung der GPU-Ressourcennutzung und der Steuerung der Betriebskosten, indem die Anwendungsskala dynamisch angepasst wird, um auf die Auslastungsnachfrage zu reagieren.

Prerequisites

  • Azure CLI , Version 2.60.0 oder höher. Führen Sie az --version aus, um die Version zu ermitteln. Wenn Sie eine Installation oder ein Upgrade durchführen müssen, finden Sie weitere Informationen unter Azure CLI installieren.
  • Helm Version 3.17.0 oder höher installiert.
  • kubectl Version 1.28.9 oder höher installiert.
  • NVIDIA GPU-Kontingent in Ihrem Azure-Abonnement. In diesem Beispiel wird die Standard_NC40ads_H100_v5 SKU verwendet, andere NVIDIA H100-VM-SKUs werden jedoch ebenfalls unterstützt.

Bevor Sie fortfahren, stellen Sie sicher, dass Ihr AKS-Cluster mit den folgenden Komponenten konfiguriert ist:

Sie sollten jetzt über Folgendes verfügen:

Erstellen Sie einen neuen KEDA-Scaler mit den Metriken des NVIDIA DCGM Exporters

Zum Erstellen eines KEDA-Scalers benötigen Sie zwei Komponenten:

  1. Der Prometheus-Abfrageendpunkt.
  2. Die vom Benutzer zugewiesene verwaltete Identität.

Den Azure Managed Prometheus-Abfrageendpunkt abrufen

  1. Sie finden diesen Wert im Abschnitt "Übersicht" des Azure Monitor Arbeitsbereichs, der ihrem AKS-Cluster im Azure-Portal zugeordnet ist.

    Screenshot des verwalteten Prometheus-Abfrageendpunkts.

  2. Exportieren Sie den Azure Verwalteten Prometheus-Abfrageendpunkt in eine Umgebungsvariable:

    export PROMETHEUS_QUERY_ENDPOINT="https://example.prometheus.monitor.azure.com"
    

Abrufen der vom Benutzer zugewiesenen verwalteten Identität

Die vom Benutzer zugewiesene verwaltete Identität wurde zuvor nach den KEDA-Integrationsschritten erstellt. Laden Sie diesen Wert bei Bedarf mit dem az identity show Befehl neu:

export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group $RESOURCE_GROUP --name $USER_ASSIGNED_IDENTITY_NAME --query 'clientId' -o tsv)"

Erstellen Sie das KEDA-Scaler-Manifest.

Dieses Manifest erstellt die TriggerAuthentication und ScaledObject für die automatische Skalierung basierend auf der GPU-Auslastung, gemessen anhand der Metrik DCGM_FI_DEV_GPU_UTIL.

Note

In diesem Beispiel wird die Metrik verwendet, die die DCGM_FI_DEV_GPU_UTIL GPU-Auslastung misst. Andere Metriken stehen auch vom DCGM-Exporter je nach Ihren Workloadanforderungen zur Verfügung. Eine vollständige Liste der verfügbaren Metriken finden Sie in der NVIDIA DCGM Exporter-Dokumentation.

Feld Description
metricName Gibt die zu überwachende GPU-Metrik an. DCGM_FI_DEV_GPU_UTIL meldet den Prozentsatz der Zeit, in der die GPU Workloads aktiv verarbeitet. Dieser Wert liegt in der Regel zwischen 0 und 100.
query PromQL-Abfrage, die die durchschnittliche GPU-Auslastung für alle Pods in der Bereitstellung my-gpu-workloadberechnet. Dadurch wird sichergestellt, dass Skalierungsentscheidungen auf der allgemeinen GPU-Nutzung basieren, nicht auf einem einzelnen Pod.
threshold Der Prozentsatz der zieldurchschnittlichen GPU-Auslastung, der die Skalierung auslöst. Wenn der Mittelwert 5 % überschreitet, erhöht der Scaler die Anzahl der Pod-Replikate.
activationThreshold Die minimale durchschnittliche GPU-Auslastung, die zum Aktivieren der Skalierung erforderlich ist. Wenn die Auslastung unter 2%liegt, treten keine Skalierungsaktionen auf, was eine unnötige Skalierung während geringer Aktivitätszeiträume verhindert.
  1. Erstellen Sie das folgende KEDA-Manifest:

    cat <<EOF > keda-gpu-scaler-prometheus.yaml
    apiVersion: keda.sh/v1alpha1
    kind: TriggerAuthentication
    metadata:
      name: azure-managed-prometheus-trigger-auth
    spec:
      podIdentity:
        provider: azure-workload
        identityId: ${USER_ASSIGNED_CLIENT_ID}
    ---
    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: my-gpu-workload
    spec:
      scaleTargetRef:
        name: my-gpu-workload
      minReplicaCount: 1
      maxReplicaCount: 20
      triggers:
        - type: prometheus
          metadata:
            serverAddress: ${PROMETHEUS_QUERY_ENDPOINT}
            metricName: DCGM_FI_DEV_GPU_UTIL
            query: avg(DCGM_FI_DEV_GPU_UTIL{deployment="my-gpu-workload"})
            threshold: '5'
            activationThreshold: '2'
          authenticationRef:
            name: azure-managed-prometheus-trigger-auth
    EOF
    
  2. Wenden Sie dieses Manifest mithilfe des Befehls an kubectl apply :

    kubectl apply -f keda-gpu-scaler-prometheus.yaml
    

Testen der neuen Skalierungsfunktionen

  1. Erstellen Sie eine Beispielworkload, die GPU-Ressourcen in Ihrem AKS-Cluster verbraucht. Sie können mit dem folgenden Beispiel beginnen:

    cat <<EOF > my-gpu-workload.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-gpu-workload
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-gpu-workload
      template:
        metadata:
          labels:
            app: my-gpu-workload
        spec:
          tolerations:
            - key: "sku"
              operator: "Equal"
              value: "gpu"
              effect: "NoSchedule"
          containers:
            - name: my-gpu-workload
              image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
              command: ["/bin/sh"]
              args: ["-c", "while true; do python /app/main.py --max_steps=500; done"]
              resources:
                limits:
                  nvidia.com/gpu: 1
    EOF
    
  2. Wenden Sie dieses Bereitstellungsmanifest mithilfe des kubectl apply Befehls an:

    kubectl apply -f my-gpu-workload.yaml
    

    Note

    Wenn derzeit keine GPU-Knoten verfügbar sind, verbleibt der Pod in einem Pending Zustand, bis ein Knoten bereitgestellt wird, und zeigt die folgende Meldung an:

    Events:
      Type     Reason            Age    From                Message
      ----     ------            ----   ----                -------
      Warning  FailedScheduling  3m19s  default-scheduler   0/2 nodes are available: 2 Insufficient nvidia.com/gpu. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod.
    

    Die Cluster-Autoskaler starten und stellen schließlich einen neuen GPU-Knoten bereit:

    Normal   TriggeredScaleUp  2m43s  cluster-autoscaler  pod triggered scale-up: [{aks-gpunp-36854149-vmss 0->1 (max: 2)}]
    

    Note

    Je nach Größe der bereitgestellten GPU-SKU kann die Knotenbereitstellung mehrere Minuten dauern.

  3. Um den Fortschritt zu überprüfen, überprüfen Sie die HpA-Ereignisse (Horizontal Pod Autoscaler) mithilfe des kubectl describe Befehls:

    kubectl describe hpa my-gpu-workload
    

    Die Ausgabe sollte wie folgt aussehen:

    Conditions:
      Type            Status  Reason            Message
      ----            ------  ------            -------
      AbleToScale     True    ReadyForNewScale  recommended size matches current size
      ScalingActive   True    ValidMetricFound  the HPA successfully calculated a replica count from external metric s0-prometheus(&LabelSelector{MatchLabels:map[string]string{scaledobject.keda.sh/name: my-gpu-workload}})
      ScalingLimited  True    TooFewReplicas    the desired replica count is less than the minimum replica count
    
  4. Vergewissern Sie sich, dass der GPU-Knoten hinzugefügt wurde und der Pod mit dem kubectl get Befehl ausgeführt wird:

    kubectl get nodes
    

    Die Ausgabe sollte wie folgt aussehen:

    NAME                                STATUS   ROLES    AGE     VERSION
    aks-gpunp-36854149-vmss000005       Ready    <none>   4m36s   v1.31.7
    aks-nodepool1-34179260-vmss000002   Ready    <none>   26h     v1.31.7
    aks-nodepool1-34179260-vmss000003   Ready    <none>   26h     v1.31.7
    

GPU-Knotenpool herunterskalieren

Wenn Sie den GPU-Knotenpool herunterskalieren möchten, löschen Sie die Workloadbereitstellung mit dem kubectl delete Befehl:

kubectl delete deployment my-gpu-workload

Note

Sie können den Knotenpool so konfigurieren, dass er auf null herunterskaliert wird, indem Sie die Cluster-Autoskalierung aktivieren und beim Erstellen des Knotenpools min-count auf 0 setzen. Beispiel:

az aks nodepool add \
 --resource-group myResourceGroup \
 --cluster-name myAKSCluster \
 --name gpunp \
 --node-count 1 \
 --node-vm-size Standard_NC40ads_H100_v5 \
 --node-taints sku=gpu:NoSchedule \
 --enable-cluster-autoscaler \
 --min-count 0 \
 --max-count 3

Nächste Schritte

  • Stellen Sie eine Multiinstanz-GPU (MIG)-Workload auf AKS bereit.
  • Erkunden Sie KAITO auf AKS für KI-Ableitungen und Feinabstimmungen.
  • Erfahren Sie mehr über Ray-Cluster auf AKS.