Configurar a criação de perfil de GPU em AKS (Serviço de Kubernetes do Azure) (versão prévia)

Cargas de trabalho baseadas em GPU, como serviços de inferência de IA, podem ser com uso intensivo de memória e difíceis de otimizar sem visibilidade da atividade de GPU. Você pode ver erros de OOM (memória insuficiente), picos de latência inesperados ou aumento da pressão de memória de GPU, mas as métricas tradicionais do Kubernetes não mostram onde o código aloca memória. A criação de perfil de GPU ajuda você a identificar as funções responsáveis pelo uso de memória de GPU.

Este artigo mostra como implantar um agente de observabilidade de GPU baseado em eBPF, armazenar perfis no Pyroscope e visualizar alocações de memória de GPU no Grafana.

Importante

As funcionalidades em versão preliminar do AKS estão disponíveis de forma optativa e por autoatendimento. As versões prévias são fornecidas “no estado em que se encontram” e “conforme disponíveis” e são excluídas dos contratos de nível de serviço e da garantia limitada. As versões prévias do AKS são parcialmente cobertas pelo suporte ao cliente em uma base de melhor esforço. Dessa forma, esses recursos não são destinados ao uso em produção. Para obter mais informações, consulte os seguintes artigos:

Importante

O software de código aberto é mencionado em toda a documentação e amostras do AKS. O software que você implanta está excluído dos contratos de nível de serviço do AKS, garantia limitada e suporte do Azure. Ao usar tecnologia de código aberto junto com o AKS, consulte as opções de suporte disponíveis nas comunidades e mantenedores de projetos respectivos para desenvolver um plano.

A Microsoft assume a responsabilidade por criar os pacotes de código aberto que implantamos no AKS. Essa responsabilidade inclui ter propriedade completa do processo de criação, verificação, sinalização, validação e hotfix, junto com o controle sobre os binários em imagens de contêiner. Para obter mais informações, confira Gerenciamento de vulnerabilidades para o AKS e Cobertura de suporte do AKS.

Pré-requisitos

  • Um cluster do AKS com pelo menos um pool de nós habilitado para GPU.
  • CLI do Azure versão 2.72.0 ou posterior. Execute az --version para verificar sua versão.
  • A extensão da CLI do k8s-extension Azure. Execute o comando az extension add --name k8s-extension para instalá-lo.
  • Helm versão 3.x ou posterior. Execute helm version para verificar sua versão.
  • Azure Monitor, a menos que você use sua própria configuração de monitoramento.
  • Espaço Gerenciado do Azure para Grafana, a menos que você use sua própria instância do Grafana.

Etapa 1: Habilitar a criação de perfil de GPU por meio da extensão Inspektor Gadget

Inspektor Gadget é uma estrutura de observabilidade baseada em eBPF de software livre para Kubernetes. Para criação de perfil de GPU, ele rastreia chamadas de alocação de memória CUDA (Arquitetura de Dispositivo Unificada de Computação) sem exigir alterações no código, sidecars ou reinicializações de pods.

Habilite a criação de perfil de GPU no cluster do AKS:

Note

Esse comando pressupõe que você habilitou Azure Monitor no cluster do AKS. Se você usar sua própria configuração do Prometheus, remova --configuration-settings azureMonitor.enabled=true. Para obter mais informações, consulte as perguntas frequentes sobre a criação de perfil de 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

Verifique se os pods do Inspektor Gadget estão em execução:

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

Dica

A análise de perfil da memória da GPU captura eventos de alocação de memória à medida que ocorrem. Se sua carga de trabalho alocar memória de GPU antes de habilitar a criação de perfil, o criador de perfil não capturará esses eventos. Para cargas de trabalho como vLLM que pré-alocam memória GPU durante a inicialização, habilite a criação de perfil antes de implantar a carga de trabalho ou reinicie a carga de trabalho para capturar os caminhos de alocação de memória iniciais.

Etapa 2: Habilitar a visualização de perfil com o Pyroscope

Note

Se você já tiver uma instalação existente do Grafana e do Pyroscope no seu cluster, ignore esta etapa.

O Pyroscope é um projeto de software livre que visualiza e armazena perfis de desempenho para otimização de memória e solução de problemas.

Implante uma única instância do Pyroscope em seu 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

Verifique se o pod Pyroscope está em execução:

kubectl get pods -n gadget pyroscope-0

Note

Para uma implantação de alta disponibilidade, consulte a documentação dos microsserviços do Pyroscope.

Note

Esse comando armazena perfis no sistema de arquivos local, portanto, os dados de criação de perfil serão perdidos se o pod for recriado. Para manter perfis entre reinicializações de pod, consulte as perguntas frequentes sobre a criação de perfil de GPU.

Etapa 3: Conectar o Piroscope ao Espaço Gerenciado do Azure para Grafana

Note

Se você usar sua própria instância do Grafana, consulte as perguntas frequentes sobre a criação de perfil de GPU.

Dica

Para exibir perfis de carga de trabalho diretamente na interface do usuário do Pyroscope, execute kubectl port-forward -n gadget pyroscope-0 4040:4040.

Conecte o Piroscope ao Espaço Gerenciado do Azure para Grafana por meio de Link Privado do Azure.

Defina as variáveis de ambiente do cluster e do 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)

Dica

Se você não tiver uma instância Espaço Gerenciado do Azure para Grafana, execute az grafana create --name "$GRAFANA_NAME" --resource-group "$RESOURCE_GROUP" --location "$LOCATION" --output none.

Defina as variáveis de ambiente do endpoint privado:

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

Crie o link privado:

Note

A criação do link privado pode levar alguns minutos.

# 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."

Crie a fonte de dados do Pyroscope no Espaço Gerenciado do Azure para 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."

Verifique se a fonte de dados tem uma URL válida:

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

Etapa 4: Conectar o Grafana ao serviço gerenciado Azure Monitor do Prometheus

Note

Essas etapas se baseiam em Conectar o serviço gerenciado do Azure Monitor para Prometheus ao Grafana. Verifique se a identidade gerenciada do Grafana tem a função Leitor de Dados de Monitoramento no workspace do Azure Monitor, especialmente se o workspace estiver em um grupo de recursos ou assinatura diferente.

Defina as variáveis de ambiente do espaço de trabalho do Azure Monitor:

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

Dica

Execute az resource list --resource-type Microsoft.Monitor/accounts --resource-group "$AMP_RESOURCE_GROUP" --output table para listar os espaços de trabalho do Azure Monitor no grupo de recursos. Para pesquisar a assinatura, omita --resource-group.

Crie a fonte de dados do 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\" }
    }
  }"

Verifique a fonte de dados:

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

Etapa 5: Configurar painéis no Grafana

Importe o painel de observabilidade da 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)"

Obtenha a URL do painel:

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

echo "${GRAFANA_URL}/d/AdvancedGPUObservability"

Para interpretar os dados de criação de perfil, consulte Analisar gráficos de chama de criação de perfil da GPU.

Limpar os recursos

Remova a pilha de observabilidade de GPU no 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

Como ler gráficos de chama

Para interpretar os resultados do profilamento e identificar os gargalos de memória da GPU, consulte Analisar gráficos de chama do profilamento de GPU.

perguntas frequentes

Para integrações personalizadas do Prometheus e Grafana e armazenamento persistente do Pyroscope, consulte o FAQ sobre criação de perfil de GPU.

Próximas Etapas