設定 Azure Kubernetes Service (AKS) 上的 GPU 分析(預覽)

基於 GPU 的工作負載,如 AI 推論服務,可能佔用大量記憶體,且缺乏對 GPU 活動的可視化而難以優化。 你可能會看到記憶體外(OOM)錯誤、意外延遲激增或 GPU 記憶體壓力上升,但傳統 Kubernetes 指標並不會顯示程式碼在哪裡分配記憶體。 GPU 效能分析有助於你辨識負責 GPU 記憶體使用的功能。

本文將教你如何部署基於 eBPF 的 GPU 可觀察性代理程式、在 Pyroscope 中儲存設定檔,以及在 Grafana 中視覺化 GPU 記憶體配置。

Important

AKS 預覽功能可透過自願加入的方式使用。 預覽內容係依「現狀」及「可用情況」提供,不適用於服務等級協議和有限保固。 客戶支援部門會盡最大努力,部分支援 AKS 預覽。 因此,這些功能不適合實際執行用途。 如需詳細資訊,請參閱下列支援文章:

Important

整個 AKS 文件和範例都會提及開放原始碼的軟體。 您部署的軟體會從 AKS 服務等級協定、有限保固和 Azure 支援 中排除。 當您搭配 AKS 使用開放原始碼技術時,請參閱個別社群和專案維護人員所提供的支援選項,以開發計畫。

Microsoft 負責建置我們在 AKS 上部署的開源套件。 該責任包括擁有組建、掃描、簽署、驗證和 Hotfix 程式的完整擁有權,以及控制容器映像中的二進位檔。 如需詳細資訊,請參閱 AKS 弱點管理和 AKS 支援涵蓋範圍。

先決條件

  • 具有至少一個啟用 GPU 之節點集區的 AKS 叢集。
  • Azure CLI 版本 2.72.0 或更後版本。 執行 az --version 以檢查您的版本。
  • Azure k8s-extension CLI 擴充功能。 執行 az extension add --name k8s-extension 以安裝它。
  • Helm 版本 3.x 或更新。 執行 helm version 以檢查您的版本。
  • Azure 監視器,除非你使用自己的監視設定。
  • Azure 受控 Grafana,除非您使用自己的 Grafana 執行個體。

步驟 1:透過 Inspektor Gadget 擴充功能啟用 GPU 效能分析

Inspektor Gadget 是一個基於 Kubernetes 的開源 eBPF 可觀察性框架。 對於 GPU 效能分析,它可追蹤統一計算架構 (CUDA) 記憶體分配呼叫,無需變更程式碼、部署 Sidecar 或重新啟動 Pod。

在您的 AKS 叢集上啟用 GPU 分析:

Note

這個指令假設你已在 AKS 叢集啟用 Azure 監視器。 如果你用的是自己的 Prometheus 設定,請移除 --configuration-settings azureMonitor.enabled=true。 更多資訊請參閱 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

確認 Inspektor Gadget Pods 是否正在運作:

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

Tip

GPU 記憶體配置檔能即時捕捉記憶體配置事件。 如果你的工作負載在啟用剖析前就分配了 GPU 記憶體,分析器就不會捕捉這些事件。 對於像 vLLM 這類會在啟動期間預先配置 GPU 記憶體的工作負載,請先啟用剖析,再部署該工作負載;或者重新啟動工作負載,以擷取初始記憶體配置路徑。

步驟二:啟用 Pyroscope 的輪廓視覺化

Note

如果你的叢集中有現有的 Grafana 和 Pyroscope 堆疊,可以跳過這一步。

Pyroscope 是一個開源專案,能視覺化並儲存效能配置檔,用於記憶體優化與故障排除。

將單一 Pyroscope 實例 部署到你的叢集:

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

確認 Pyroscope 艙是否正在運作:

kubectl get pods -n gadget pyroscope-0

Note

欲取得高度可用性的部署,請參閱 Pyroscope 微服務文件。

Note

此指令將設定檔儲存在本地檔案系統,因此若重新建立 Pod,剖面資料會遺失。 要在 Pod 重啟時持續維持設定檔,請參考 GPU 配置檔常見問題。

步驟 3:Connect Pyroscope 到 Azure 受控 Grafana

Note

如果你使用自己的 Grafana 實例,請參閱 GPU 配置檔常見問題。

Tip

若要直接在 Pyroscope 介面中查看工作負載設定檔,請執行 kubectl port-forward -n gadget pyroscope-0 4040:4040。

Connect Pyroscope to Azure 受控 Grafana through Azure Private Link.

設定叢集與 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

如果你沒有 Azure 受控 Grafana 實例,請執行 az grafana create --name "$GRAFANA_NAME" --resource-group "$RESOURCE_GROUP" --location "$LOCATION" --output none。

設定私有端點環境變數:

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

建立私人連結:

Note

建立私人連結可能需要幾分鐘。

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

在 Azure 受控 Grafana 中建立 Pyroscope 資料來源:

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

確認資料來源是否有有效的網址:

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

步驟 4:將 Grafana 連線到 Azure 監視器 的 Prometheus 受控服務

Note

這些步驟是根據將適用於 Prometheus 的 Azure 監視器受控服務連線至 Grafana。 請確保 Grafana 的受控身分識別在 Azure 監視器工作區上具有監控資料讀取者角色,尤其是當工作區位於不同的資源群組或訂用帳戶內時。

設定 Azure 監視器 工作區環境變數:

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

Tip

執行 az resource list --resource-type Microsoft.Monitor/accounts --resource-group "$AMP_RESOURCE_GROUP" --output table 以列出資源群組中的 Azure 監視器 工作區。 若要搜尋訂閱,請省略 --resource-group。

建立普羅米修斯資料來源:

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\" }
    }
  }"

請驗證資料來源:

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

步驟五:在 Grafana 中設定儀表板

匯入 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)"

取得儀表板網址:

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

echo "${GRAFANA_URL}/d/AdvancedGPUObservability"

要解讀剖析資料,請參閱 分析 GPU 剖面火焰圖。

清理資源

移除叢集內的 GPU 可觀測性堆疊:

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

閱讀火焰圖

欲解讀剖析結果並識別 GPU 記憶體熱點,請參見 「分析 GPU 剖析火焰圖」。

FAQ

關於客製化的 Prometheus 與 Grafana 整合以及持久的 Pyroscope 儲存,請參閱 GPU 配置檔常見問題。

下一步