Azure Kubernetes Service (AKS)で GPU プロファイリングを設定する (プレビュー)

AI 推論サービスなどの GPU ベースのワークロードは、メモリを集中的に消費し、GPU アクティビティを可視化せずに最適化するのが難しい場合があります。 メモリ不足 (OOM) エラー、予期しない待機時間の急増、または GPU メモリ不足が発生する場合がありますが、従来の Kubernetes メトリックでは、コードがメモリを割り当てる場所が表示されません。 GPU プロファイリングは、GPU メモリの使用を担当する関数を識別するのに役立ちます。

この記事では、eBPF ベースの GPU 監視エージェントをデプロイし、プロファイルをパイロスコープに格納し、Grafana で GPU メモリ割り当てを視覚化する方法について説明します。

Important

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿のまま" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は運用環境での使用を目的としていません。 詳細については、次のサポート記事を参照してください。

Important

オープンソース ソフトウェアは、AKS のドキュメントとサンプル全体で説明されています。 デプロイするソフトウェアは、AKS サービス レベル アグリーメント、限定保証、Azure サポートから除外されます。 AKS と共にオープンソース テクノロジを使用する場合は、それぞれのコミュニティとプロジェクト保守担当者から受けられるサポート オプションを調べ、計画を策定してください。

Microsoft は、AKS 上に展開するオープンソース パッケージを構築する責任を負います。 その責任には、ビルド、スキャン、署名、検証、修正プログラム プロセスの完全な所有権と、コンテナー イメージ内のバイナリの制御権が伴います。 詳細については、AKS の脆弱性の管理に関するページと「AKS のサポート範囲」を参照してください。

前提条件

  • 少なくとも 1 つの GPU 対応ノード プールを持つ AKS クラスター。
  • Azure CLI バージョン 2.72.0 以降。 バージョンを確認するには az --version を実行します。
  • k8s-extension Azure CLI 拡張機能。 az extension add --name k8s-extensionを実行してインストールします。
  • Helm バージョン 3.x 以降。 バージョンを確認するには helm version を実行します。
  • 独自の監視環境を使用しない限り、Azure Monitor。
  • Azure Managed Grafana (ただし、独自の Grafana インスタンスを使用する場合は除く)。

手順 1: Inspektor ガジェット拡張機能を使用して GPU プロファイリングを有効にする

Inspektor Gadget は、Kubernetes 用のオープンソースの eBPF ベースの可観測性フレームワークです。 GPU プロファイリングでは、コードの変更、サイドカー、ポッドの再起動を行わずに、コンピューティング統合デバイス アーキテクチャ (CUDA) メモリ割り当て呼び出しをトレースします。

AKS クラスターで GPU プロファイリングを有効にします。

Note

このコマンドは、AKS クラスターでAzure Monitorを有効にしていることを前提としています。 独自の Prometheus セットアップを使用する場合は、 --configuration-settings azureMonitor.enabled=trueを削除します。 詳細については、 GPU プロファイリングに関する FAQ を参照してください。

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 ガジェット ポッドが実行されていることを確認します。

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

Tip

GPU メモリ プロファイリングでは、メモリ割り当てイベントが発生したときにキャプチャされます。 プロファイリングを有効にする前にワークロードによって GPU メモリが割り当てられる場合、プロファイラーはこれらのイベントをキャプチャしません。 起動時に GPU メモリを事前に割り当てる vLLM などのワークロードの場合は、ワークロードをデプロイする前にプロファイリングを有効にするか、ワークロードを再起動して初期メモリ割り当てパスをキャプチャします。

手順 2: パイロスコープを使用してプロファイルの視覚化を有効にする

Note

クラスターに既存の Grafana およびPyrscope スタックがある場合は、この手順をスキップします。

パイロスコープ は、メモリの最適化とトラブルシューティングのためにパフォーマンス プロファイルを視覚化して格納するオープンソース プロジェクトです。

クラスターに 1 つの Pyrscope インスタンス をデプロイします。

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

Note

高可用性のデプロイについては、 Pyscope マイクロサービスのドキュメントを参照してください。

Note

このコマンドはローカル ファイルシステムにプロファイルを格納するため、ポッドが再作成されるとプロファイル データは失われます。 ポッドの再起動間でプロファイルを保持するには、 GPU プロファイリングに関する FAQ を参照してください。

手順 3: パイロスコープをAzure Managed Grafanaに接続する

Note

独自の Grafana インスタンスを使用する場合は、 GPU プロファイリングに関する FAQ を参照してください。

Tip

パイロスコープ UI でワークロード プロファイルを直接表示するには、 kubectl port-forward -n gadget pyroscope-0 4040:4040実行します。

Azure Private Linkを介して、パイロスコープをAzure Managed 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 Managed 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 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."

データ ソースに有効な URL があることを確認します。

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

手順 4: Grafana を Prometheus のマネージド サービスAzure Monitor接続する

Note

これらの手順は、Azure Monitor の Prometheus 用マネージド サービスを Grafana に接続するに基づいています。 特にワークスペースが別のリソース グループまたはサブスクリプションにある場合は、Grafana のマネージド ID に 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)"

ダッシュボードの URL を取得します。

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 の統合と永続的なPyscope ストレージについては、 GPU プロファイリングに関する FAQ を参照してください。

次のステップ