基于 GPU 的工作负载(如 AI 推理服务)可能会占用大量内存,并且难以优化,而无需了解 GPU 活动。 你可能会看到内存不足(OOM)错误、意外延迟峰值或 GPU 内存压力上升,但传统的 Kubernetes 指标不显示代码分配内存的位置。 GPU 分析可帮助你识别负责 GPU 内存使用的函数。
本文介绍如何部署基于 eBPF 的 GPU 可观测性代理、在 Pyroscope 中存储配置文件,以及如何在 Grafana 中可视化 GPU 内存分配。
重要
AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
重要
AKS 文档和示例中都提到了开源软件。 您部署的软件被排除在 AKS 服务级别协议、有限保修和 Azure 支持之外。 将开源技术与 AKS 一起使用时,请查阅相应社区和项目维护者提供的支持选项来制定计划。
Microsoft 将负责生成我们在 AKS 上部署的开源包。 该责任包括拥有构建、扫描、签名、验证和快速修复流程的完整所有权,并掌控容器镜像中的二进制文件。 如需了解详细信息,请参阅 AKS 漏洞管理和 AKS 支持范围。
先决条件
- 至少具有一个启用了 GPU 的节点池的 AKS 群集。
-
Azure CLI 2.72.0 或更高版本。 请运行
az --version以查看版本。 - 这是
k8s-extensionAzure CLI 扩展。 运行az extension add --name k8s-extension以安装它。 -
Helm 3.x 或更高版本。 请运行
helm version以查看版本。 - Azure Monitor,除非你使用自己的监控解决方案。
- Azure 托管 Grafana,除非你使用自己的 Grafana 实例。
步骤 1:通过 Inspektor 小工具扩展启用 GPU 分析
Inspektor Gadget 是一个基于 eBPF 的开源 Kubernetes 可观测性框架。 对于 GPU 性能分析,它无需更改代码、使用边车容器或重启 Pod,即可跟踪 CUDA 内存分配调用。
在 AKS 群集上启用 GPU 性能分析:
注释
此命令假定你在 AKS 群集上启用了Azure Monitor。 如果使用自己的 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 Pod 是否正在运行:
kubectl get pods -n gadget -l k8s-app=gadget
Tip
GPU 内存分析可在内存分配事件发生时捕获这些事件。 如果你的工作负载在启用性能分析之前分配了 GPU 内存,性能分析器将无法捕获这些事件。 对于诸如 vLLM 这类在启动时预分配 GPU 内存的工作负载,请在部署工作负载之前启用性能分析,或者重启工作负载以捕获初始内存分配路径。
步骤 2:使用 Pyroscope 启用性能剖析可视化
注释
如果群集中有现有的 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 Pod 是否正在运行:
kubectl get pods -n gadget pyroscope-0
注释
有关高可用性部署,请参阅 Pyroscope 微服务文档。
注释
此命令将配置文件存储在本地文件系统上,因此,如果重新创建 Pod,分析数据将丢失。 若要在 Pod 重启后保留配置文件,请参阅 GPU 分析常见问题解答。
步骤 3:将火镜连接到 Azure 托管 Grafana
注释
如果使用自己的 Grafana 实例,请参阅 GPU 分析常见问题解答。
Tip
若要直接在Pyoscope UI 中查看工作负荷配置文件,请运行 kubectl port-forward -n gadget pyroscope-0 4040:4040。
通过Azure 专用链接将火镜连接到Azure 托管 Grafana。
设置群集和 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"
创建专用链接:
注释
创建专用链接可能需要几分钟时间。
# 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中创建Pyoscope数据源:
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."
验证数据源是否具有有效的 URL:
az grafana data-source show \
--name "$GRAFANA_NAME" \
--data-source local-pyroscope
步骤 4:将 Grafana 连接到 Prometheus Azure Monitor托管服务
注释
这些步骤基于 将 Prometheus 的 Azure Monitor 托管服务连接到 Grafana。 请确保 Grafana 的托管标识在 Azure Monitor 工作区上具有 监视数据读取者 角色,尤其是在该工作区位于其他资源组或其他订阅下时。
设置Azure Monitor工作区环境变量:
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 Monitor工作区。 若要搜索订阅,请省略 --resource-group。
创建 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\" }
}
}"
验证数据源:
az grafana data-source show \
--name "$GRAFANA_NAME" \
--data-source "$AMP_NAME"
步骤 5:在 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 性能分析常见问题解答。