基於 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-extensionCLI 擴充功能。 執行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 配置檔常見問題。