Kubernetes 上の AI および GPU ワークロード: デバイス プラグインとトレーニング ジョブ
2026 年には、AI 推論クラスターの 66% が Kubernetes 上で実行されます (CNCF 調査 2026)。理由 それは簡単です。Kubernetes は、AI ワークロードの最も困難な運用上の問題、つまりスケジューリングを解決します。 インテリジェントな GPU スケーリング、トレーニング ジョブの柔軟なスケーリング、分散ストレージとの統合 データセットの場合、ノード障害時の自動再試行。ただし、Kubernetes をセットアップする GPU ワークロードには、通常のデプロイをはるかに超える特定のスキルが必要です ウェブアプリケーション。
この記事では、 NVIDIA デバイス プラグイン のために GPU をクラスターに公開する、スケジュールする方法 分散トレーニングジョブ PyTorch と TensorFlow の使用方法 カーペンター スポットスケーリングを行うには GPU (コストを 40 ~ 70% 削減)、およびワークロードでの GPU の使用を最適化するパターン 推論から生産へ。
何を学ぶか
- Kubernetes 用 NVIDIA デバイス プラグインのインストールと構成
- GPU デマンドを使用したポッドのスケジュール (nvidia.com/gpu リソース)
- PyTorchJob および TFJob を使用した分散トレーニング (Kubeflow Training Operator)
- Karpenter NodePool によるスポット GPU ノードの自動プロビジョニング
- 複数のポッド間で GPU を共有するための GPU タイム スライシング
- A100/H100 GPU パーティションの MIG (マルチインスタンス GPU)
- DCGM Exporter と Grafana による GPU モニタリング
- K8 での TorchServe を使用した高スループット推論のパターン
Kubernetes 上の GPU アーキテクチャ
Kubernetes はネイティブに GPU を認識しません。 GPU は、 デバイスプラグインフレームワーク: GPU を備えたすべてのノードで実行される DaemonSet、 kubelet に登録し、コンテナへの GPU の割り当てを管理します。の NVIDIA Device Plugin は、このフレームワークの最も一般的な実装です。
NVIDIA デバイス プラグインのインストール
# Pre-requisiti: NVIDIA GPU drivers installati sui nodi
# Verifica driver sui nodi
kubectl get nodes -l accelerator=nvidia
kubectl describe node gpu-node-1 | grep -i nvidia
# Installa NVIDIA Device Plugin con Helm
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update
helm install nvdp nvdp/nvidia-device-plugin \
--namespace kube-system \
--version 0.16.0 \
--set failOnInitError=false
# Oppure con manifest diretto
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.16.0/deployments/static/nvidia-device-plugin.yml
# Verifica che le GPU siano visibili nel cluster
kubectl get nodes -o json | jq '.items[].status.allocatable | select(."nvidia.com/gpu" != null)'
# Output: { "nvidia.com/gpu": "8" } per un nodo con 8 GPU A100
NVIDIA GPU Operator のインストール (推奨されるアプローチ)
実稼働環境のクラスターの場合、 GPUオペレーター NVIDIA が管理する 必要なすべてのコンポーネント (ドライバー、デバイス プラグイン、コンテナー ランタイム、 監視用の DCGM エクスポーター:
# Installa GPU Operator
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--create-namespace \
--version v24.9.0 \
--set driver.enabled=true \
--set mig.strategy=single \
--set dcgmExporter.enabled=true \
--set dcgmExporter.serviceMonitor.enabled=true
# Verifica installazione
kubectl get pods -n gpu-operator
# Attendi che tutti i pod siano Running
kubectl wait --for=condition=ready pod -l app=nvidia-device-plugin-daemonset -n gpu-operator --timeout=300s
# Verifica GPU allocabili
kubectl describe node gpu-node-1 | grep -A 5 "Allocatable:"
# nvidia.com/gpu: 8
GPU を使用したポッドのスケジュール設定
デバイス プラグインがアクティブになると、他のプラグインと同様にマニフェストで GPU をリクエストできます。 他の Kubernetes リソース。違い: リクエストは使用せず、制限のみを使用します GPU の場合 (Kubernetes は常に必要な GPU の正確な数を保証します)。
# pod-gpu-basic.yaml
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
restartPolicy: OnFailure
containers:
- name: inference
image: nvcr.io/nvidia/pytorch:24.01-py3
command: ["python3", "-c"]
args:
- |
import torch
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"GPU count: {torch.cuda.device_count()}")
print(f"GPU name: {torch.cuda.get_device_name(0)}")
x = torch.rand(1000, 1000).cuda()
print(f"Tensor on GPU: {x.device}")
resources:
limits:
nvidia.com/gpu: "1" # richiedi 1 GPU
memory: "16Gi"
cpu: "4"
requests:
memory: "16Gi"
cpu: "4"
volumeMounts:
- name: model-storage
mountPath: /models
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: model-pvc
nodeSelector:
accelerator: "nvidia-a100" # schedule solo su nodi A100
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
Kubeflow Training Operator を使用して配信されたトレーニング
大規模なモデルをトレーニングするには、多くの場合、複数のノード上に複数の GPU が必要になります。の Kubeflow トレーニング オペレーター 分散トレーニング ジョブを管理します PyTorchJob、TFJob、MXJob、MPIJob。まずオペレーターをインストールします。
# Installa Training Operator
kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.8.0"
# Verifica
kubectl get pods -n kubeflow
kubectl get crd | grep kubeflow
マルチ GPU マルチノード トレーニング用の PyTorchJob
# pytorch-distributed-training.yaml
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: llm-finetuning-job
namespace: ml-training
spec:
pytorchReplicaSpecs:
Master:
replicas: 1
restartPolicy: OnFailure
template:
spec:
containers:
- name: pytorch
image: company.registry.io/training:llm-v2.1
command:
- python3
- -m
- torch.distributed.run
- --nproc_per_node=8
- --nnodes=4
- --node_rank=$(RANK)
- --master_addr=$(MASTER_ADDR)
- --master_port=23456
- train_llm.py
- --model=llama-7b
- --dataset=/data/training_set
- --batch-size=32
- --epochs=3
- --output=/models/finetuned
env:
- name: NCCL_DEBUG
value: "INFO"
- name: NCCL_SOCKET_IFNAME
value: "eth0"
resources:
limits:
nvidia.com/gpu: "8"
memory: "120Gi"
cpu: "32"
requests:
memory: "120Gi"
cpu: "32"
volumeMounts:
- name: training-data
mountPath: /data
- name: model-output
mountPath: /models
- name: shm
mountPath: /dev/shm
volumes:
- name: training-data
persistentVolumeClaim:
claimName: training-dataset-pvc
- name: model-output
persistentVolumeClaim:
claimName: model-output-pvc
- name: shm
emptyDir:
medium: Memory
sizeLimit: "64Gi" # shared memory per NCCL
nodeSelector:
accelerator: "nvidia-a100-80gb"
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
Worker:
replicas: 3 # 3 worker + 1 master = 4 nodi, 32 GPU totali
restartPolicy: OnFailure
template:
spec: # stesso spec del Master...
containers:
- name: pytorch
image: company.registry.io/training:llm-v2.1
resources:
limits:
nvidia.com/gpu: "8"
memory: "120Gi"
cpu: "32"
Karpenter によるスポット GPU ノード プロビジョニング
GPU はクラウド内で最も高価なリソースです。スポット GPU インスタンスのコストが 60 ~ 70% 削減 オンデマンドと比較して。 カーペンター 自動プロビジョニングを管理します スポット GPU ノードの数、停止の場合はオンデマンドにフォールバック:
# karpenter-gpu-nodepool.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu-spot
spec:
template:
metadata:
labels:
role: gpu-worker
accelerator: nvidia
spec:
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
name: gpu-nodeclass
requirements:
# Tipologie di istanze GPU AWS
- key: node.kubernetes.io/instance-type
operator: In
values:
- p4d.24xlarge # 8x A100 80GB
- p3.8xlarge # 4x V100
- g5.12xlarge # 4x A10G
- g4dn.12xlarge # 4x T4
# Preferisci spot
- key: karpenter.sh/capacity-type
operator: In
values:
- spot
- on-demand # fallback
- key: kubernetes.io/os
operator: In
values:
- linux
taints:
- key: nvidia.com/gpu
value: "true"
effect: NoSchedule
limits:
nvidia.com/gpu: 256 # max 256 GPU totali nel cluster
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30m # rimuovi nodi GPU spot quando il job finisce
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: gpu-nodeclass
spec:
amiFamily: AL2
role: KarpenterNodeRole
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "my-cluster"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "my-cluster"
instanceStorePolicy: RAID0 # usa i dischi NVMe locali per storage temporaneo
userData: |
#!/bin/bash
# Installa NVIDIA drivers al primo boot
/etc/eks/bootstrap.sh my-cluster
nvidia-smi # verifica GPU disponibili
GPU タイム スライシング: 複数のポッド間で GPU を共有する
軽い推論や開発ワークロードの場合、GPU 全体が無駄になることがよくあります。 の GPU タイムスライシング 複数のポッド間で物理 GPU を共有できます。 それぞれが、計算時間の一部を含む「仮想 GPU」を認識します。
# gpu-time-slicing-config.yaml
# Configura il Device Plugin per time-slicing
apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config
namespace: gpu-operator
data:
any: |-
version: v1
flags:
migStrategy: none
sharing:
timeSlicing:
renameByDefault: false
failRequestsGreaterThanOne: false
resources:
- name: nvidia.com/gpu
replicas: 4 # ogni GPU fisica diventa 4 "GPU" logiche
---
# Applica il config all'operator
kubectl patch clusterpolicy gpu-cluster-policy \
-n gpu-operator \
--type merge \
-p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config"}}}}'
# Verifica: ogni nodo con 1 GPU A100 ora mostra 4 GPU allocabili
kubectl describe node gpu-node-1 | grep nvidia.com/gpu
# Allocatable:
# nvidia.com/gpu: 4
# Pod che usa 1/4 di GPU
apiVersion: v1
kind: Pod
metadata:
name: inference-small
spec:
containers:
- name: model-server
image: company.registry.io/inference:v1
resources:
limits:
nvidia.com/gpu: "1" # ottiene 1/4 della GPU fisica
MIG: A100 および H100 用のマルチインスタンス GPU
NVIDIA A100 および H100 GPU のサポート MIG (マルチインスタンス GPU)、それ GPU を分離されたハードウェア インスタンスに分割します (タイムシェアリングだけではありません)。各 MIG インスタンス メモリと計算が保証されており、他のものに干渉しません。
# Configura MIG sul nodo (eseguito sul nodo GPU, non da kubectl)
# Richiede: driver NVIDIA >= 525, GPU A100 o H100
# Abilita MIG mode sulla GPU
sudo nvidia-smi -mig 1
# Crea 7 istanze MIG da 1/7 di A100 (1g.10gb)
sudo nvidia-smi mig -cgip -p 0,9 # Profile 9 = MIG 1g.10gb
# Verifica istanze create
sudo nvidia-smi mig -lgi
# +-------------------------------------------------------+
# | GPU instances: |
# | GPU Name Profile Instance Placement |
# | ID ID Start:Size |
# |=======================================================|
# | 0 MIG 1g.10gb 9 1 0:1 |
# | 0 MIG 1g.10gb 9 2 1:1 |
# | 0 MIG 1g.10gb 9 3 2:1 |
# ... (7 istanze totali)
# Nel cluster Kubernetes, configurare MIG Strategy nel GPU Operator
kubectl patch clusterpolicy gpu-cluster-policy \
-n gpu-operator \
--type json \
-p '[{"op":"replace","path":"/spec/mig/strategy","value":"mixed"}]'
# Pod che richiede specifica istanza MIG
apiVersion: v1
kind: Pod
metadata:
name: inference-mig
spec:
containers:
- name: model
image: nvcr.io/nvidia/pytorch:24.01-py3
resources:
limits:
nvidia.com/mig-1g.10gb: "1" # richiedi 1 istanza MIG 1g.10gb
DCGM Exporter による GPU モニタリング
トレーニング ジョブが効率的かどうかを理解するには、GPU モニタリングが不可欠です そしてFinOpsにとっても。 DCGM Exporter は GPU メトリクスを Prometheus に公開します。
# DCGM Exporter viene installato automaticamente con GPU Operator
# Verifica che le metriche siano disponibili
kubectl port-forward svc/gpu-operator-dcgm-exporter 9400:9400 -n gpu-operator &
curl -s localhost:9400/metrics | grep DCGM_FI
# Metriche chiave da monitorare:
# DCGM_FI_DEV_GPU_UTIL - utilizzo GPU (0-100%)
# DCGM_FI_DEV_MEM_COPY_UTIL - utilizzo memoria GPU
# DCGM_FI_DEV_FB_USED - memoria GPU usata (MB)
# DCGM_FI_DEV_POWER_USAGE - consumo energetico (W)
# DCGM_FI_DEV_SM_CLOCK - clock streaming multiprocessor
# DCGM_FI_DEV_GPU_TEMP - temperatura GPU
# Alert: GPU sottoutilizzata (< 50% per 30 minuti = spreco)
- alert: GPUUnderutilized
expr: DCGM_FI_DEV_GPU_UTIL < 50
for: 30m
labels:
severity: warning
annotations:
summary: "GPU {{ $labels.gpu }} sul nodo {{ $labels.Hostname }} utilization < 50%"
description: "Valuta se il job puo essere terminato o ottimizzato"
# Dashboard Grafana: importa ID 12239 (NVIDIA DCGM Exporter Dashboard)
TorchServe を使用した推論用モデルのデプロイメント
本番環境の推論には、負荷分散を処理するモデル サーバーが必要です これには、複数のモデルのレプリケーション、リクエストのバッチ処理、バージョン管理が含まれます。トーチサーブ 公式の PyTorch ソリューション:
# torchserve-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-inference
namespace: ml-inference
spec:
replicas: 3 # 3 replica per alta disponibilita
selector:
matchLabels:
app: model-inference
template:
metadata:
labels:
app: model-inference
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8082" # TorchServe metrics port
spec:
containers:
- name: torchserve
image: pytorch/torchserve:0.11.0-gpu
args:
- torchserve
- --start
- --model-store=/models
- --models=text-classifier=bert-classifier.mar
- --ts-config=/config/config.properties
ports:
- containerPort: 8080 # inference API
- containerPort: 8081 # management API
- containerPort: 8082 # metrics
resources:
limits:
nvidia.com/gpu: "1"
memory: "16Gi"
cpu: "4"
requests:
memory: "8Gi"
cpu: "2"
readinessProbe:
httpGet:
path: /ping
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
httpGet:
path: /ping
port: 8080
initialDelaySeconds: 120
periodSeconds: 30
volumeMounts:
- name: model-store
mountPath: /models
- name: ts-config
mountPath: /config
volumes:
- name: model-store
persistentVolumeClaim:
claimName: model-store-pvc
- name: ts-config
configMap:
name: torchserve-config
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: torchserve-config
namespace: ml-inference
data:
config.properties: |
inference_address=http://0.0.0.0:8080
management_address=http://0.0.0.0:8081
metrics_address=http://0.0.0.0:8082
number_of_gpu=1
batch_size=32
max_batch_delay=100 # ms: attendi fino a 100ms per fare batching
max_response_size=6553500
install_py_dep_per_model=true
---
# HPA basato su latenza con KEDA (event-driven autoscaling)
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: inference-scaler
namespace: ml-inference
spec:
scaleTargetRef:
name: model-inference
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc:9090
metricName: torchserve_queue_latency_microseconds
threshold: "100000" # 100ms di coda = scala up
query: avg(torchserve_queue_latency_microseconds{model_name="bert-classifier"})
Kubernetes 上の AI ワークロードのベスト プラクティス
GPUコストの最適化
- トレーニングにはスポット、推論にはオンデマンド: トレーニングはチェックポイントを使用して中断を処理できます。推論は常に利用可能でなければなりません
- 頻繁なチェックポイント: スポット中断後にトレーニングを再開するには、30 分ごとにチェックポイントを保存します
- 開発のためのタイムスライシング: 開発者にはタイムスライスされた GPU を使用し、実稼働には MIG またはフル GPU を使用します
- ゼロまでスケール: Karpenter はトレーニング終了時にスポット GPU ノードを削除します - アイドル状態の GPU に対して料金を支払う必要はありません
- 推論でのバッチ処理: バッチサイズ = 32 の TorchServe は、単一リクエストと比較してスループットを 10 ~ 20 倍向上させます。
- 導入前のプロファイル: NVIDIA Nsight を使用してトレーニング ジョブをプロファイリングし、非効率性を特定します
Kubernetes での一般的な GPU エラー
- 汚染耐性のないコンテナ: GPU ノードに汚染がある
nvidia.com/gpu=true:NoSchedule;許容されない場合、Pod は GPU ノード上でスケジュールされません。 - メモリの分離に失敗しました: GPU は、CPU のようにコンテナー間でメモリを分離しません。 1 GPU を割り当てても、モデルが使用可能なメモリを超えるメモリを使用すると、ジョブが CUDA OOM でクラッシュします。
- 共有メモリなしの NCCL: PyTorch 分散トレーニングでは NCCL を使用しますが、これには大規模な /dev/shm (通常 10 ~ 60GB) が必要です。常にemptyDirをmedium: Memoryで構成します。
- GPU 使用率を監視しない: GPU 使用率が 20% の場合、非常に無駄になります。 DCGM ダッシュボードは、展開後に最初に確認する場所である必要があります。
結論と次のステップ
Kubernetes が AI/ML ワークロードの標準プラットフォームになったのは偶然ではありません。 リソースの抽象化、高度なスケジューリング システム、オペレータ エコシステム (Kubeflow、トレーニング オペレーター) 両方のトレーニングを調整するための理想的なコンテキストを作成します。 その推論はスケールに合わせて行われます。 Karpenter によるノードのプロビジョニングの自動管理 スポット GPU、トレーニング ジョブのコストを、使用量と比較して 40 ~ 70% 削減できます。 オンデマンド インスタンスの。
次のステップは、これらのワークロードを完全な MLOps パイプラインと統合することです。 MLflow によるモデルの管理、DVC によるデータセット管理、自動再トレーニングのための CI/CD。 FinOps for Kubernetes の記事 (このシリーズの記事 9) では、測定方法について詳しく説明しています。 クラスター内の GPU ワークロードの総コストを最適化します。
Kubernetes at Scale シリーズの今後の記事
関連シリーズ
- 本番環境における MLOps と機械学習 — ML 用の CI/CD パイプライン、モデル レジストリ
- ディープラーニングとニューラルネットワーク — GPU でのモデルトレーニングの理論的基礎
- Kubernetes での自動スケーリング — カスタムメトリクスに基づいてスケーリングするための KEDA







