Configurer le profilage GPU sur Azure Kubernetes Service (AKS) (préversion)

Les charges de travail basées sur GPU, telles que les services d’inférence IA, peuvent être gourmandes en mémoire et difficiles à optimiser sans visibilité sur l’activité GPU. Vous pouvez voir des erreurs hors mémoire (OOM), des pics de latence inattendus ou une augmentation de la sollicitation de la mémoire GPU, mais les métriques Kubernetes traditionnelles ne montrent pas où le code alloue de la mémoire. Le profilage GPU vous aide à identifier les fonctions responsables de l’utilisation de la mémoire GPU.

Cet article explique comment déployer un agent d’observabilité GPU basé sur eBPF, stocker des profils dans Pyroscope et visualiser les allocations de mémoire GPU dans Grafana.

Important

Les fonctionnalités d’évaluation AKS sont disponibles en libre-service et font l’objet d’un abonnement. Les versions d'essai sont fournies « en l’état » et « selon disponibilité », et elles sont exclues des contrats de niveau de service et de la garantie limitée. Les versions préliminaires AKS sont, dans la mesure du possible, partiellement couvertes par le service clientèle. Par conséquent, ces fonctionnalités ne sont pas destinées à une utilisation en production. Pour plus d’informations, consultez les articles de support suivants :

Important

Les logiciels open source sont mentionnés dans la documentation et les exemples AKS. Les logiciels que vous déployez sont exclus des contrats de niveau de service AKS, de la garantie limitée et du support Azure. Quand vous utilisez une technologie open source avec AKS, consultez les options de support disponibles auprès des communautés et responsables de projet respectifs pour élaborer un plan.

Microsoft assume la responsabilité de la génération des packages open source que nous déployons sur AKS. Cette responsabilité comprend la maîtrise complète des processus de génération, d’analyse, de signature et de validation ainsi que l’application de correctifs logiciels et le contrôle des fichiers binaires présents dans les images conteneur. Pour plus d’informations, consultez Gestion des vulnérabilités pour AKS et Couverture du support AKS.

Prerequisites

  • Un cluster AKS avec au moins un pool de nœuds avec GPU.
  • Azure CLI version 2.72.0 ou ultérieure. Exécutez az --version pour vérifier votre version.
  • L'extension k8s-extension Azure CLI. Exécutez az extension add --name k8s-extension pour l’installer.
  • Helm version 3.x ou ultérieure. Exécutez helm version pour vérifier votre version.
  • Azure Monitor, sauf si vous utilisez votre propre configuration de supervision.
  • Azure Managed Grafana, sauf si vous utilisez votre propre instance Grafana.

Étape 1 : Activer le profilage GPU via l’extension Inspektor Gadget

Inspektor Gadget est un framework d’observabilité basé sur eBPF open source pour Kubernetes. Pour le profilage GPU, il trace les appels d’allocation de mémoire CUDA (Compute Unified Device Architecture) sans nécessiter de modifications de code, sidecars ou redémarrages de pods.

Activez le profilage GPU sur votre cluster AKS :

Note

Cette commande suppose que vous avez activé Azure Monitor sur votre cluster AKS. Si vous utilisez votre propre configuration Prometheus, supprimez --configuration-settings azureMonitor.enabled=true. Pour plus d’informations, consultez le FAQ sur le profilage GPU.

az k8s-extension create \
  --extension-type microsoft.inspektorgadget \
  --subscription <your-subscription-id> \
  --resource-group <your-resource-group> \
  --cluster-name <your-cluster-name> \
  --cluster-type managedClusters \
  --release-train preview \
  --name inspektor-gadget \
  --configuration-settings gpuObservability.enabled=true \
  --configuration-settings azureMonitor.enabled=true

Vérifiez que les pods Inspektor Gadget sont en cours d’exécution :

kubectl get pods -n gadget -l k8s-app=gadget

Tip

Le profilage de la mémoire GPU capture les événements d’allocation de mémoire au fur et à mesure qu’ils se produisent. Si votre charge de travail alloue de la mémoire GPU avant d’activer le profilage, le profileur ne capture pas ces événements. Pour les charges de travail telles que vLLM qui prélocalisent la mémoire GPU au démarrage, activez le profilage avant de déployer la charge de travail ou redémarrez la charge de travail pour capturer les chemins d’allocation de mémoire initiales.

Étape 2 : Activer la visualisation de profil avec Pyroscope

Note

Si vous disposez d’une pile Grafana et Pyroscope existante dans votre cluster, ignorez cette étape.

Pyroscope est un projet open source qui visualise et stocke les profils de performances pour l’optimisation de la mémoire et la résolution des problèmes.

Déployez une instance Pyroscope unique sur votre cluster :

helm install pyroscope -n gadget \
  oci://ghcr.io/grafana/helm-charts/pyroscope \
  --version 1.15.0 \
  --set pyroscope.image.repository=grafana/pyroscope \
  --set-string pyroscope.image.tag=1.15.0 \
  --set pyroscope.replicaCount=1 \
  --set pyroscope.structuredConfig.self_profiling.disable_push=true \
  --set pyroscope.structuredConfig.storage.backend=filesystem \
  --set pyroscope.service.type=LoadBalancer \
  --set pyroscope.service.port=4040 \
  --set-string pyroscope.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true \
  --set-string pyroscope.service.annotations."service\.beta\.kubernetes\.io/azure-pls-create"=true \
  --set-string pyroscope.service.annotations."service\.beta\.kubernetes\.io/azure-pls-name"=pyroscope-pls \
  --set-string pyroscope.service.annotations."service\.beta\.kubernetes\.io/azure-pls-proxy-protocol"=false \
  --set-string pyroscope.service.annotations."service\.beta\.kubernetes\.io/azure-pls-visibility"='*' \
  --set alloy.enabled=false \
  --set minio.enabled=false

Vérifiez que le pod Pyroscope est en cours d’exécution :

kubectl get pods -n gadget pyroscope-0

Note

Pour un déploiement à haute disponibilité, consultez la documentation des microservices Pyroscope.

Note

Cette commande stocke les profils sur le système de fichiers local, de sorte que les données de profilage sont perdues si le pod est recréé. Pour préserver les profils lors des redémarrages de pod, consultez la FAQ sur le profilage GPU.

Étape 3 : Connecter Pyroscope à Azure Managed Grafana

Note

Si vous utilisez votre propre instance Grafana, consultez le FAQ sur le profilage GPU.

Tip

Pour afficher les profils de charge de travail directement dans l’interface utilisateur de Pyroscope, exécutez kubectl port-forward -n gadget pyroscope-0 4040:4040.

Connectez Pyroscope à Azure Managed Grafana via Azure Private Link.

Définissez les variables d’environnement de cluster et Grafana :

export RESOURCE_GROUP="<your-resource-group>"
export AKS_CLUSTER="<your-aks-cluster-name>"
export LOCATION="<your-aks-cluster-location>"
export GRAFANA_NAME="<your-azure-managed-grafana-name>"
export AKS_NODE_RG=$(az aks show \
  --resource-group "$RESOURCE_GROUP" \
  --name "$AKS_CLUSTER" \
  --query 'nodeResourceGroup' \
  --output tsv)

Tip

Si vous n'avez pas d'instance Azure Managed Grafana, exécutez az grafana create --name "$GRAFANA_NAME" --resource-group "$RESOURCE_GROUP" --location "$LOCATION" --output none.

Définissez les variables d’environnement de point de terminaison privé :

export PYROSCOPE_PLS="pyroscope-pls"
export PYROSCOPE_MPE="pyroscope-mpe"
export PYROSCOPE_PORT="4040"

Créez la liaison privée :

Note

La création de la liaison privée peut prendre quelques minutes.

# Check the Azure Managed Grafana extension version.
ver=$(az extension show --name amg --query version --output tsv)
[[ "${ver%%.*}" -ge 3 ]] && MPE="managed-private-endpoint" || MPE="mpe"

# Wait until the Pyroscope private link service is available.
until az network private-link-service show \
  --name "$PYROSCOPE_PLS" \
  --resource-group "$AKS_NODE_RG" \
  --output none 2>/dev/null; do
  sleep 10
done

PYRO_PLS_ID=$(az network private-link-service show \
  --name "$PYROSCOPE_PLS" \
  --resource-group "$AKS_NODE_RG" \
  --query 'id' \
  --output tsv)

az grafana $MPE create \
  --workspace-name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --name "$PYROSCOPE_MPE" \
  --private-link-resource-id "$PYRO_PLS_ID" \
  --location "$LOCATION" \
  --output none

sleep 30

PYRO_CONN=$(az network private-link-service show \
  --name "$PYROSCOPE_PLS" \
  --resource-group "$AKS_NODE_RG" \
  --query "privateEndpointConnections[?privateLinkServiceConnectionState.status=='Pending' && starts_with(name, 'grafana-${GRAFANA_NAME}')].name | [0]" \
  --output tsv)

az network private-link-service connection update \
  --name "$PYRO_CONN" \
  --service-name "$PYROSCOPE_PLS" \
  --resource-group "$AKS_NODE_RG" \
  --connection-status Approved \
  --output none

az grafana $MPE refresh \
  --workspace-name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --output none

echo "Successfully created private link."

Créez la source de données Pyroscope dans Azure Managed Grafana :

ver=$(az extension show --name amg --query version --output tsv)
[[ "${ver%%.*}" -ge 3 ]] && MPE="managed-private-endpoint" || MPE="mpe"

PYRO_IP=$(az grafana $MPE show \
  --workspace-name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --name "$PYROSCOPE_MPE" \
  --query 'privateLinkServicePrivateIP' \
  --output tsv)

export PYROSCOPE_URL="http://${PYRO_IP}:${PYROSCOPE_PORT}"

az grafana data-source create \
  --name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --definition "{
    \"name\": \"local-pyroscope\",
    \"uid\": \"local-pyroscope\",
    \"type\": \"grafana-pyroscope-datasource\",
    \"access\": \"proxy\",
    \"url\": \"${PYROSCOPE_URL}\",
    \"jsonData\": { \"keepCookies\": [\"pyroscope_git_session\"] }
  }" \
  --output none

echo "Successfully created the local-pyroscope data source."

Vérifiez que la source de données a une URL valide :

az grafana data-source show \
  --name "$GRAFANA_NAME" \
  --data-source local-pyroscope

Étape 4 : Connecter Grafana à Azure Monitor service managé pour Prometheus

Note

Ces étapes sont basées sur Connecter le service managé Azure Monitor pour Prometheus à Grafana. Vérifiez que l'identité managée de Grafana a le rôle Lecteur de données de surveillance sur l'espace de travail Azure Monitor, en particulier si l'espace de travail se trouve dans un autre groupe de ressources ou un autre abonnement.

Définissez les variables d’environnement d’espace de travail Azure Monitor :

export AMP_NAME="<your-azure-monitor-workspace-name>"
export AMP_RESOURCE_GROUP="<your-azure-monitor-workspace-resource-group>"

Tip

Exécutez az resource list --resource-type Microsoft.Monitor/accounts --resource-group "$AMP_RESOURCE_GROUP" --output table pour répertorier les espaces de travail Azure Monitor dans le groupe de ressources. Pour rechercher l’abonnement, omettez --resource-group.

Créez la source de données Prometheus :

AMP_ENDPOINT=$(az resource show \
  --resource-type Microsoft.Monitor/accounts \
  --name "$AMP_NAME" \
  --resource-group "$AMP_RESOURCE_GROUP" \
  --query properties.metrics.prometheusQueryEndpoint \
  --output tsv)

az grafana data-source create \
  --name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --definition "{
    \"name\": \"$AMP_NAME\",
    \"type\": \"prometheus\",
    \"access\": \"proxy\",
    \"url\": \"$AMP_ENDPOINT\",
    \"jsonData\": {
      \"httpMethod\": \"POST\",
      \"azureCredentials\": { \"authType\": \"msi\" }
    }
  }"

Vérifiez la source de données :

az grafana data-source show \
  --name "$GRAFANA_NAME" \
  --data-source "$AMP_NAME"

Étape 5 : Configurer des tableaux de bord dans Grafana

Importez le tableau de bord d’observabilité GPU :

az grafana dashboard create \
  --name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --definition "$(curl -sSL https://raw.githubusercontent.com/inspektor-gadget/grafana-dashboards/refs/heads/main/dashboards/gpu-observability/AdvancedGPUObservability.json)"

Obtenez l’URL du tableau de bord :

GRAFANA_URL=$(az grafana show \
  --name "$GRAFANA_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --query properties.endpoint \
  --output tsv)

echo "${GRAFANA_URL}/d/AdvancedGPUObservability"

Pour interpréter les données de profilage, consultez Analyser les graphiques en flammes du profilage GPU.

Nettoyer les ressources

Supprimez la pile d’observabilité GPU dans le cluster :

helm uninstall pyroscope -n gadget
az k8s-extension delete \
  --name inspektor-gadget \
  --cluster-name <your-cluster-name> \
  --resource-group <your-resource-group> \
  --cluster-type managedClusters \
  --yes
kubectl delete namespace gadget

Lecture des graphiques de flammes

Pour interpréter les résultats du profilage et identifier les points chauds de la mémoire du GPU, consultez Analyser les graphes en flammes du profilage GPU.

Forum aux questions

Pour connaître les intégrations Prometheus et Grafana personnalisées et le stockage Pyroscope persistant, consultez le FAQ sur le profilage GPU.

Étapes suivantes