Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Configurer la mise à l'échelle automatique avec des métriques GPU

Dernière mise à jour :Aug 26, 2026

Utilisez Kubernetes Custom Metrics et Managed Service for Prometheus pour collecter les métriques GPU et mettre à l'échelle automatiquement vos conteneurs avec HPA.

Prérequis

Un nœud GPU est ajouté à votre cluster ou un cluster GPU dédié est créé.

Fonctionnement

Les GPU accélèrent le calcul dans des scénarios tels que l'entraînement et l'inférence de modèles d'apprentissage profond. La mise à l'échelle automatique basée sur des métriques GPU, telles que l'utilisation et la mémoire, permet d'optimiser les coûts.

Par défaut, Kubernetes Horizontal Pod Autoscaler (HPA) utilise les métriques CPU et mémoire. Pour les métriques GPU, Prometheus Adapter récupère les données depuis Managed Service for Prometheus et les expose via l'API Custom Metrics. HPA met ensuite à l'échelle les charges de travail en fonction de l'utilisation du GPU, de l'utilisation de la mémoire et d'autres indicateurs. Le schéma suivant illustre ce processus.

image

Étape 1 : Déployer Prometheus et l'adaptateur de métriques

  1. Activez la surveillance Prometheus pour votre cluster.

    Remarque

    Ignorez cette étape si Prometheus a été installé lors de la création du cluster.

  2. Sur la page Clusters, cliquez sur le nom de votre cluster. Dans le volet de navigation de gauche, cliquez sur Operations > Prometheus Monitoring.

  3. Sur la page Clusters, cliquez sur le nom de votre cluster. Dans le volet de navigation de gauche, cliquez sur Applications > Helm.

  4. Dans le volet de navigation de gauche, choisissez Managed Service for Prometheus > Instances.

  5. Installez et configurez ack-alibaba-cloud-metrics-adapter.

    1. Obtenez l'URL de l'API HTTP

    1. Connectez-vous à la console ARMS.

    2. Sélectionnez la région de votre cluster ACK. Cliquez sur l'instance cible.

    3. Sur la page Settings, dans l'onglet Settings, copiez l'adresse du réseau interne à partir de HTTP API Address (Grafana Read Address).

    2. Configurez l'URL Prometheus

    1. Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Marketplace > Marketplace.

    2. Sur la page Marketplace, cliquez sur l'onglet App Catalog. Recherchez et cliquez sur ack-alibaba-cloud-metrics-adapter.

    3. Sur la page ack-alibaba-cloud-metrics-adapter, cliquez sur Deploy.

    4. Dans l'assistant Basic Information, sélectionnez votre cluster et votre namespace. Cliquez sur Next.

    5. Dans l'assistant Parameters, sélectionnez une Chart Version. Dans la section Parameters, définissez le paramètre url avec l'URL de l'API HTTP copiée. Cliquez sur OK.

Étape 2 : Configurer les règles de l'adaptateur

1. Interroger les métriques GPU

Pour connaître les métriques GPU disponibles, consultez les descriptions des métriques de surveillance.

2. Configurer les règles de l'adaptateur

  1. Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Dans la liste Helm, recherchez ack-alibaba-cloud-metrics-adapter. Dans la colonne Actions, cliquez sur Update. Ajoutez les rules suivantes au champ custom.

    Cliquez pour afficher les règles

    - metricsQuery: avg(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
      resources:
        overrides:
          NodeName:
            resource: node
      seriesQuery: DCGM_FI_DEV_GPU_UTIL{} # GPU utilization.
    - metricsQuery: avg(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
      resources:
        overrides:
          NamespaceName:
            resource: namespace
          NodeName:
            resource: node
          PodName:
            resource: pod
      seriesQuery: DCGM_CUSTOM_PROCESS_SM_UTIL{} # Container GPU utilization.
    - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
      resources:
        overrides:
          NodeName:
            resource: node
      seriesQuery: DCGM_FI_DEV_FB_USED{} # GPU memory usage.
    - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
      resources:
        overrides:
          NamespaceName:
            resource: namespace
          NodeName:
            resource: node
          PodName:
            resource: pod
      seriesQuery: DCGM_CUSTOM_PROCESS_MEM_USED{} # Container GPU memory usage.
    - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) / sum(DCGM_CUSTOM_CONTAINER_MEM_ALLOCATED{}) by (<<.GroupBy>>)
      name:
        as: ${1}_GPU_MEM_USED_RATIO
        matches: ^(.*)_MEM_USED
      resources:
        overrides:
          NamespaceName:
            resource: namespace
          PodName:
            resource: pod
      seriesQuery: DCGM_CUSTOM_PROCESS_MEM_USED{NamespaceName!="",PodName!=""}  # Container GPU memory utilization.

    Configuration complète après ajout des règles :

    Chart Url  https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/ack-alibaba-cloud-metrics-adapter-1.3.2.tgz
      adapter:
        rules:
          custom:
          - metricsQuery: sum(&lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;}) by (&lt;&lt;.GroupBy&gt;&gt;)
            name:
              as: ${1}_bytes_per_second
              matches: ^(.*)_bytes
            resources:
              overrides:
                namespace:
                  resource: namespace
                pod:
                  resource: pod
            seriesQuery: container_memory_working_set_bytes{namespace!="",pod!=""}
          - metricsQuery: sum(rate(&lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;}[1m])) by (&lt;&lt;.GroupBy&gt;&gt;)
            name:
              as: ${1}_core_per_second
              matches: ^(.*)_seconds_total
            resources:
              overrides:
                namespace:
                  resource: namespace
                pod:
                  resource: pod
            seriesQuery: container_cpu_usage_seconds_total{namespace!="",pod!=""}
          - metricsQuery: &lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;}
            resources:
              overrides:
                NodeName:
                  resource: node
            seriesQuery: DCGM_FI_DEV_GPU_UTIL{} # GPU utilization.
          - metricsQuery: &lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;}
            resources:
              overrides:
                NamespaceName:
                  resource: namespace
                NodeName:
                  resource: node
                PodName:
                  resource: pod
            seriesQuery: DCGM_CUSTOM_PROCESS_SM_UTIL{} # Container GPU utilization.
          - metricsQuery: &lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;}
            resources:
              overrides:
                NodeName:
                  resource: node
            seriesQuery: DCGM_FI_DEV_FB_USED{} # GPU memory usage.
          - metricsQuery: &lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;}
            resources:
              overrides:
                NamespaceName:
                  resource: namespace
                NodeName:
                  resource: node
                PodName:
                  resource: pod
            seriesQuery: DCGM_CUSTOM_PROCESS_MEM_USED{} # Container GPU memory usage.
          - metricsQuery: sum(&lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;})by(&lt;&lt;.GroupBy&gt;&gt;) / sum(DCGM_CUSTOM_CONTAINER_MEM_ALLOCATED{})by(&lt;&lt;.GroupBy&gt;&gt;)
            name:
              as: ${1}_GPU_MEM_USED_RATIO
              matches: ^(.*)_MEM_USED
            resources:
              overrides:
                NamespaceName:
                  resource: namespace
                PodName:
                  resource: pod
            seriesQuery: DCGM_CUSTOM_PROCESS_MEM_USED{NamespaceName!="",PodName!=""}  # Container GPU memory utilization.
          default: false
        enabled: true
        logLevel: 5

    Vérifiez la configuration. La sortie doit contenir des métriques telles que DCGM_FI_DEV_GPU_UTIL, DCGM_CUSTOM_PROCESS_SM_UTIL, DCGM_FI_DEV_FB_USED et DCGM_CUSTOM_PROCESS_MEM_USED. L'exemple suivant met en évidence DCGM_CUSTOM_PROCESS_SM_UTIL ; votre sortie réelle peut varier.

    Cliquez pour afficher l'exemple de sortie

    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1"

    Sortie attendue : Le tableau resources contient les métriques DCGM_CUSTOM_PROCESS_SM_UTIL.

    {
      "kind": "APIResourceList",
      "apiVersion": "v1",
      "groupVersion": "custom.metrics.k8s.io/v1beta1",
      "resources": [
        {
          "name": "nodes/DCGM_CUSTOM_PROCESS_SM_UTIL",
          "singularName": "",
          "namespaced": false,
          "kind": "MetricValueList",
          "verbs": [
            "get"
          ]
        },
        {
          "name": "pods/DCGM_CUSTOM_PROCESS_SM_UTIL",
          "singularName": "",
          "namespaced": true,
          "kind": "MetricValueList",
          "verbs": [
            "get"
          ]
        },
        {
          "name": "namespaces/DCGM_CUSTOM_PROCESS_SM_UTIL",
          "singularName": "",
          "namespaced": false,
          "kind": "MetricValueList",
          "verbs": [
            "get"
          ]
        },
        {
          "name": "DCGM_CUSTOM_PROCESS_GPU_MEM_USED_RATIO",
          "singularName": "",
          "namespaced": false,
          "kind": "MetricValueList",
          "verbs": [
            "get"
          ]
        }
      ]
    }

Étape 3 : Mettre en œuvre la mise à l'échelle automatique

Testez la mise à l'échelle automatique en déployant un service d'inférence GPU, en exécutant un test de charge et en observant le comportement de mise à l'échelle basé sur le GPU.

1. Déployer le service d'inférence

  1. Déployez le service d'inférence.

    Cliquez pour afficher les détails de la commande

    cat <<EOF | kubectl create -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: bert-intent-detection
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: bert-intent-detection
      template:
        metadata:
          labels:
            app: bert-intent-detection
        spec:
          containers:
          - name: bert-container
            image: registry.cn-hangzhou.aliyuncs.com/ai-samples/bert-intent-detection:1.0.1
            ports:
            - containerPort: 80
            resources:
              limits:
                nvidia.com/gpu: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: bert-intent-detection-svc
      labels:
        app: bert-intent-detection
    spec:
      selector:
        app: bert-intent-detection
      ports:
      - protocol: TCP
        name: http
        port: 80
        targetPort: 80
      type: LoadBalancer
    EOF
  2. Vérifiez le statut des Pods et du Service.

    • Vérifiez le statut du Pod.

      kubectl get pods -o wide

      Sortie attendue :

      NAME                                    READY   STATUS    RESTARTS   AGE     IP           NODE                        NOMINATED NODE   READINESS GATES
      bert-intent-detection-7b486f6bf-f****   1/1     Running   0          3m24s   10.15.1.17   cn-beijing.192.168.94.107   <none>           <none>

      Un Pod est déployé sur le nœud GPU 192.168.94.107.

    • Vérifiez le statut du Service.

      kubectl get svc bert-intent-detection-svc

      Sortie attendue :

      NAME                        TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
      bert-intent-detection-svc   LoadBalancer   172.16.186.159   47.95.XX.XX   80:30118/TCP   5m1s

      La sortie affiche le nom du service, confirmant que le Service a été déployé avec succès.

  3. Connectez-vous au nœud GPU 192.168.94.107 via SSH et vérifiez l'utilisation du GPU.

    nvidia-smi

    Sortie attendue :

    Wed Feb 16 11:48:07 2022
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 450.102.04   Driver Version: 450.102.04   CUDA Version: 11.0     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |                               |                      |               MIG M. |
    |===============================+======================+======================|
    |   0  Tesla V100-SXM2...  On   | 00000000:00:07.0 Off |                    0 |
    | N/A   32C    P0    55W / 300W |  15345MiB / 16160MiB |      0%      Default |
    |                               |                      |                  N/A |
    +-------------------------------+----------------------+----------------------+
    +-----------------------------------------------------------------------------+
    | Processes:                                                                  |
    |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
    |        ID   ID                                                   Usage      |
    |=============================================================================|
    |    0   N/A  N/A   2305118      C   python                          15343MiB |
    +-----------------------------------------------------------------------------+

    La sortie indique que le service d'inférence s'exécute sur le GPU. L'utilisation du GPU est de 0 % car aucune requête n'a encore été reçue.

  4. Vérifiez le déploiement du service d'inférence.

    curl -v  "http://47.95.XX.XX/predict?query=Music"

    Sortie attendue :

    *   Trying 47.95.XX.XX...
    * TCP_NODELAY set
    * Connected to 47.95.XX.XX (47.95.XX.XX) port 80 (#0)
    > GET /predict?query=Music HTTP/1.1
    > Host: 47.95.XX.XX
    > User-Agent: curl/7.64.1
    > Accept: */*
    >
    * HTTP 1.0, assume close after body
    < HTTP/1.0 200 OK
    < Content-Type: text/html; charset=utf-8
    < Content-Length: 9
    < Server: Werkzeug/1.0.1 Python/3.6.9
    < Date: Wed, 16 Feb 2022 03:52:11 GMT
    <
    * Closing connection 0
    PlayMusic # Intent recognition result.

    Un code d'état 200 avec un résultat de reconnaissance d'intention confirme le déploiement réussi.

2. Configurer le HPA

Cet exemple déclenche une mise à l'échelle horizontale lorsque l'utilisation du GPU par le Pod dépasse 20 %. Le tableau suivant répertorie les métriques prises en charge par HPA.

Métrique

Description

Unité

DCGM_FI_DEV_GPU_UTIL

  • Utilisation de la carte GPU.

  • Cette métrique s'applique uniquement à la planification GPU dédiée.

    Important

    Dans les scénarios de GPU partagé, NVIDIA fournit uniquement l'utilisation au niveau de la carte, et non des métriques par application. L'exécution de nvidia-smi dans un Pod affiche l'utilisation de l'ensemble de la carte.

%

DCGM_FI_DEV_FB_USED

  • Utilisation de la mémoire de la carte GPU.

  • Cette métrique s'applique uniquement à la planification GPU dédiée.

MiB

DCGM_CUSTOM_PROCESS_SM_UTIL

Utilisation du GPU par le conteneur.

%

DCGM_CUSTOM_PROCESS_MEM_USED

Utilisation de la mémoire GPU par le conteneur.

MiB

DCGM_CUSTOM_PROCESS_GPU_MEM_USED_RATIO

Taux d'utilisation de la mémoire GPU par le conteneur.

Taux d'utilisation de la mémoire GPU par le conteneur = Mémoire GPU réellement utilisée par le conteneur / Mémoire GPU allouée au conteneur

%

  1. Déployez le HPA.

    Version du cluster ≥ 1,23

    cat <<EOF | kubectl create -f -
    apiVersion: autoscaling/v2  # Use the autoscaling/v2 HPA configuration.
    kind: HorizontalPodAutoscaler
    metadata:
      name: gpu-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: bert-intent-detection
      minReplicas: 1
      maxReplicas: 10
      metrics:
      - type: Pods
        pods:
          metric:
            name: DCGM_CUSTOM_PROCESS_SM_UTIL
          target:
            type: Utilization
            averageValue: 20 # Triggers a scale-out when the container's GPU utilization exceeds 20%.
    EOF

    Version du cluster < 1,23

    cat <<EOF | kubectl create -f -
    apiVersion: autoscaling/v2beta1  # Use the autoscaling/v2beta1 HPA configuration.
    kind: HorizontalPodAutoscaler
    metadata:
      name: gpu-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: bert-intent-detection
      minReplicas: 1
      maxReplicas: 10
      metrics:
      - type: Pods
        pods:
          metricName: DCGM_CUSTOM_PROCESS_SM_UTIL # GPU utilization of the Pod.
          targetAverageValue: 20 # Triggers a scale-out when the container's GPU utilization exceeds 20%.
    EOF
  2. Vérifiez le statut du HPA.

    kubectl get hpa

    Sortie attendue :

    NAME      REFERENCE                          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    gpu-hpa   Deployment/bert-intent-detection   0/20      1         10        1          74s

    TARGETS affiche 0/20, ce qui signifie que l'utilisation actuelle du GPU est de 0. La mise à l'échelle automatique se déclenche lorsque l'utilisation dépasse 20 %.

3. Tester la mise à l'échelle automatique

Tester la mise à l'échelle horizontale

  1. Exécutez un test de charge.

    hey -n 10000 -c 200 "http://47.95.XX.XX/predict?query=music"
    Remarque

    Le HPA calcule le nombre souhaité de réplicas avec la formule suivante : Desired Replicas = ceil[Current Replicas * (Current Metric / Desired Metric)]. Par exemple, avec 1 réplica, une valeur de métrique de 23 et une cible de 20, le résultat est de 2 réplicas.

  2. Pendant le test de charge, observez le statut du HPA et des Pods.

    1. Vérifiez le statut du HPA.

      kubectl get hpa

      Sortie attendue :

      NAME      REFERENCE                          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
      gpu-hpa   Deployment/bert-intent-detection   23/20     1         10        2          7m56s

      TARGETS affiche 23/20. L'utilisation du GPU dépasse la cible de 20 %, ce qui déclenche une mise à l'échelle horizontale.

    2. Vérifiez le statut des Pods.

      kubectl get pods

      Sortie attendue :

      NAME                                    READY   STATUS    RESTARTS   AGE
      bert-intent-detection-7b486f6bf-f****   1/1     Running   0          44m
      bert-intent-detection-7b486f6bf-m****   1/1     Running   0          14s

      Deux Pods sont en cours d'exécution, ce qui correspond à la cible de 2.

    La mise à l'échelle horizontale est confirmée.

Tester la réduction d'échelle

Une fois le test de charge arrêté, l'utilisation du GPU tombe en dessous de 20 % et la réduction d'échelle commence.

  1. Vérifiez le statut du HPA.

    kubectl get hpa

    Sortie attendue :

    NAME      REFERENCE                          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    gpu-hpa   Deployment/bert-intent-detection   0/20      1         10        1          15m

    TARGETS affiche 0/20 , ce qui signifie que l'utilisation du GPU est de 0. Après environ 5 minutes, la réduction d'échelle commence.

  2. Vérifiez le statut des Pods.

    kubectl get pods

    Sortie attendue :

    NAME                                    READY   STATUS    RESTARTS   AGE
    bert-intent-detection-7b486f6bf-f****   1/1     Running   0          52m

    Un seul Pod reste, confirmant la réduction d'échelle.

FAQ

Comment vérifier l'utilisation du GPU ?

Dans l'onglet GPU Monitoring, observez les tendances d'utilisation du GPU : une utilisation croissante indique une carte active, tandis qu'une tendance plate signifie qu'elle est inactive. Pour afficher la tendance :

  1. Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Sur la page Prometheus Monitoring, cliquez sur l'onglet GPU Monitoring.