Kubernetes での ML のスケーリング: 本番環境でのデプロイとオーケストレーション
機械学習モデルはすべてのオフライン テストに合格し、メトリクスは優れています。 FastAPI を介したサービスはローカルで完全に機能します。次に重要な瞬間が来ます。管理しなければなりません。 1 秒あたり 10,000 リクエスト、負荷に基づいて動的に拡張し、高可用性を確保 更新中のダウンタイムはゼロです。単一のコンテナではもはや十分ではありません。
Kubernetes ML ワークロードをオーケストレーションするための事実上の標準となっています。 実稼働環境で使用されており、企業組織の 78% がモデルの展開に使用しています。 CNCF Survey 2025 によると、ただし、モデルをポッドに配置するだけでは十分ではなく、管理する必要があります。 GPU スケジューリング、イベント ドリブンの自動スケーリング、リソース クォータ、カナリア デプロイメントおよびモニタリング 推論に特化したもの。 MLOps 市場は 2026 年に 43 億 8,000 万ドルの価値があり、CAGR は 39.8% は、メインのスケーリング エンジンを Kubernetes に搭載しています。
この記事では、ML モデルを Kubernetes に導入するための完全なアーキテクチャについて説明します。 実稼働: 推論サービス用の KServe および Seldon Core から、NVIDIA デバイスによる GPU スケジューリングまで プラグインから、HPA、VPA、KEDA によるインテリジェントな自動スケーリング、Prometheus および Grafana によるモニタリングまで。
何を学ぶか
- Kubernetes が本番環境における ML の標準である理由と、それをいつ使用するか
- NVIDIA デバイス プラグインおよび MIG による GPU のスケジューリングと共有
- KServe: カナリアロールアウトとゼロスケールによる InferenceService デプロイメント
- Seldon Core v2: コンポーザブルなマルチモデル サービング パイプライン
- 高度な自動スケーリング: イベント駆動型 ML ワークロード向けの HPA、VPA、KEDA
- リソース管理: リクエスト、制限、優先クラス、ノード アフィニティ
- ML推論に特化したPrometheus + Grafanaによるモニタリング
- GPU クラスターのコストの最適化とベスト プラクティス
本番環境で ML に Kubernetes を使用する理由
技術的な構成に入る前に、Kubernetes を使用する理由を理解することが重要です。 ML ワークロードのリファレンス プラットフォームとしての地位を確立し、次のようなソリューションを上回っています。 ベアメタル、専用 VM、または独自のクラウド サービス。
ML ワークロードには、従来の Web アプリケーションと比較して独特の特徴があります。トレーニング 大規模な GPU が数時間または数日間必要になる場合は、リソースを解放する必要があります。推論には、 予測できないピークと重大な遅延。モデルはダウンタイムなしで更新する必要があります。データセット サイズが大きくなり、専用のストレージが必要になる場合があります。 Kubernetes はこれらすべてのシナリオに対処します ネイティブ プリミティブを使用: 特定の GPU ノードでのポッド スケジューリング、データセットごとの永続ボリューム、ジョブ バッチトレーニングの場合は horizontalPodAutoscaler 推論スケーリングの場合。
Kubernetes とクラウド管理の代替案
Kubernetes のセルフマネージドまたはマネージド (EKS、GKE、AKS): 完全なコントロール、
マルチクラウドの移植性、コストの最適化が可能ですが、運用は非常に複雑です。
SageMaker / Vertex AI / Azure ML: 素早いセットアップ、クラウドネイティブな統合、
しかし、ベンダー ロックイン、長期的なコストの増加、カスタム アーキテクチャの柔軟性の低下が生じます。
経験則: チームは 5 人未満ですか、それとも予算が限られていますか?マネージド ML を始めましょう。
生産中の複数のモデルを持つ 5 人以上のチームですか? Kubernetes は 6 ~ 12 か月で投資を回収します。
リファレンスアーキテクチャ
実稼働環境における ML 用の Kubernetes クラスターは、通常、3 つの異なるレイヤーで構造化されています。 明確に定義された責任を伴う:
- インフラストラクチャ層: ライト サービングとオーケストレーション用の CPU ノード、GPU ノード トレーニングと高度な推論用、データセットとアーティファクト用のストレージ ノード。 GPU プールは、 特定のノードラベルで区切られています。
- プラットフォーム層: 推論サービスの場合は KServe または Seldon Core、推論サービスの場合は Kubeflow トレーニング パイプライン、実験追跡用の MLflow (記事 4 を参照)、Argo ワークフロー 複雑なオーケストレーション。
- 可観測性レイヤー: メトリクスには Prometheus、ダッシュボードには Grafana、Jaeger 分散トレースの場合は Loki、ログ集約の場合は Loki。
# Namespace structure per ML cluster
# Separare ambienti e responsabilità
kubectl create namespace ml-training # Job di training
kubectl create namespace ml-serving # Inference services
kubectl create namespace ml-monitoring # Prometheus, Grafana
kubectl create namespace mlflow # Experiment tracking
kubectl create namespace kubeflow # Pipeline orchestration
# Label nodi per GPU scheduling
kubectl label nodes gpu-node-1 accelerator=nvidia-a100
kubectl label nodes gpu-node-2 accelerator=nvidia-t4
kubectl label nodes cpu-node-1 workload=inference-cpu
GPUのスケジューリングと共有
GPU は、ML クラスターの最も高価なリソースです。下手に管理すると、何十ものお金を無駄にすることになります。
月額数千ユーロ。 Kubernetes は、GPU をスケジュール可能なリソースとして公開します。
NVIDIA デバイス プラグイン、ノード上の GPU を自動的に検出する DaemonSet
そしてそれらを次のように記録します nvidia.com/gpu キュベレットで。
# Installazione NVIDIA Device Plugin via Helm
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update
helm upgrade -i nvdp nvdp/nvidia-device-plugin \
--namespace kube-system \
--set failOnInitError=false
# Verifica GPU disponibili sui nodi
kubectl describe nodes | grep -A5 "Allocatable:"
# Output atteso:
# nvidia.com/gpu: 8
# cpu: 96
# memory: 768Gi
# Pod che richiede 1 GPU intera
apiVersion: v1
kind: Pod
metadata:
name: ml-training-job
spec:
containers:
- name: trainer
image: pytorch/pytorch:2.5.0-cuda12.4-cudnn9-runtime
resources:
limits:
nvidia.com/gpu: 1 # Richiede 1 GPU intera
cpu: "8"
memory: "32Gi"
requests:
nvidia.com/gpu: 1
cpu: "4"
memory: "16Gi"
nodeSelector:
accelerator: nvidia-a100 # Forza scheduling su A100
フル GPU を必要としない推論ワークロードに対して、NVIDIA は 2 つの戦略を提供します GPU 共有: タイムスライス e マルチインスタンス GPU (MIG).
# Configurazione Time-Slicing (per GPU T4/V100, sharing software)
# Ogni GPU fisica viene divisa in N repliche logiche
apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config
namespace: kube-system
data:
any: |-
version: v1
flags:
migStrategy: none
sharing:
timeSlicing:
replicas: 4 # 4 pod condividono 1 GPU fisica
failRequestsGreaterThanOne: false
# Apply al device plugin
kubectl patch clusterpolicies/cluster-policy \
-n gpu-operator --type merge \
-p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config"}}}}'
# Configurazione MIG per A100/H100 (hardware isolation)
# Partiziona A100 in 7 istanze MIG da 10GB ciascuna
nvidia-smi mig -cgi 9,9,9,9,9,9,9 -C
# Pod che usa una slice MIG
resources:
limits:
nvidia.com/mig-1g.10gb: 1 # Usa 1 istanza MIG da 10GB
タイムスライスと MIG: いつどちらを使用するか
タイムスライス: 軽い推論ワークロードに適しています (<2GB VRAM モデル)。 コンテキスト切り替えによる遅延が発生します。あらゆる NVIDIA GPU で動作します。 ミグ: 完全なハードウェア分離、保証された専用メモリ、ゼロ干渉 ワークロード間で。 A100、A30、H100でのみ使用可能です。厳格なレイテンシー SLA に最適です。 同じノード上で 2 つのアプローチを決して組み合わせないでください。
KServe: Kubernetes でのネイティブ推論サービス
Kサーブ (以前の KFServing) と Kubernetes での推論サービスの CNCF 標準、
Google、IBM、ブルームバーグなどのコラボレーションから生まれました。抽象化を提供します
InferenceService 導入の複雑さを隠し、自動的に管理します
Canary ロールアウト、ゼロへのスケール、リクエストベースの自動スケーリング、および複数のフレームワークのサポート
(PyTorch、TensorFlow、scikit-learn、XGBoost、ONNX、Hugging Face)。
# Installazione KServe (versione 0.13+)
kubectl apply -f https://github.com/kserve/kserve/releases/download/v0.13.0/kserve.yaml
# Verifica installazione
kubectl get pods -n kserve
# kserve-controller-manager-xxx Running
# kserve-gateway-xxx Running
# InferenceService per modello scikit-learn
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
name: "churn-predictor"
namespace: ml-serving
annotations:
serving.kserve.io/enable-prometheus-scraping: "true"
spec:
predictor:
minReplicas: 1
maxReplicas: 10
scaleTarget: 50 # Target: 50 req/sec per replica
scaleMetric: rps # Scala in base a requests-per-second
sklearn:
storageUri: "gs://my-ml-bucket/models/churn-model/v3"
runtimeVersion: "1.5.2"
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "4Gi"
KServe の強みの 1 つは、i のネイティブ サポートです。 カナリアのロールアウト: トラフィックの一部を新しいバージョンのテンプレートに送信し、残りのトラフィックをテンプレートの新しいバージョンに送信できます。 記事で見た A/B テストとまったく同じように、安定したものを使い続けてください。 このシリーズの前のもの。
# Canary Rollout: 20% traffico alla nuova versione
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
name: "churn-predictor"
namespace: ml-serving
spec:
predictor:
# Versione stabile (80% traffico)
minReplicas: 2
maxReplicas: 8
sklearn:
storageUri: "gs://my-ml-bucket/models/churn-model/v3"
runtimeVersion: "1.5.2"
canaryTrafficPercent: 80
# Versione canary (20% traffico)
predictor:
# NOTA: nella specifica KServe, il canary si gestisce con
# l'annotation traffic-split
# Ecco la sintassi corretta tramite Knative revisions:
---
# Alternativa: InferenceGraph per traffic splitting esplicito
apiVersion: "serving.kserve.io/v1alpha1"
kind: "InferenceGraph"
metadata:
name: "churn-ab-split"
namespace: ml-serving
spec:
nodes:
root:
routerType: WeightedEnsemble
routes:
- serviceName: churn-predictor-v3
weight: 80
- serviceName: churn-predictor-v4
weight: 20
# Test dell'endpoint
curl -X POST \
http://churn-predictor.ml-serving.svc.cluster.local/v1/models/churn-predictor:predict \
-H 'Content-Type: application/json' \
-d '{"instances": [[35, 12000, 2, 1, 0.8, 3]]}'
の特徴 ゼロまでスケールする KServe の (Knative Serving に基づく) e 時々使用するモデルに特に価値があります。一定時間が経過するとポッドがオフになります。 アイドル時間を設定可能で、最初のリクエスト時にコールド スタートで自動的に再起動します。 事前にキャッシュされたモデルの場合、通常は 30 秒未満です。
# Configurazione scale-to-zero con timeout personalizzato
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
name: "batch-analyzer"
namespace: ml-serving
annotations:
# Scale-to-zero dopo 5 minuti di inattivita
autoscaling.knative.dev/scaleToZeroGracePeriod: "300s"
# Window per calcolo scale-up
autoscaling.knative.dev/window: "60s"
# Utilization target (in percentuale)
autoscaling.knative.dev/targetUtilizationPercentage: "70"
spec:
predictor:
minReplicas: 0 # Abilita scale-to-zero
maxReplicas: 5
pytorch:
storageUri: "gs://my-ml-bucket/models/analyzer/v1"
runtimeVersion: "2.5.0"
Seldon Core v2: コンポーザブル ML パイプライン
KServe は個々のモデルの提供に優れていますが、 セルドンコアv2 輝く 複雑な ML アーキテクチャの管理: マルチステップ パイプライン、モデル アンサンブル、 ビジネス ロジックによる A/B ルーティング、およびストリーム処理のための Kafka との統合。 Seldon v2 は、V2 プロトコルと互換性のある推論ランタイムとして MLServer を使用します。 (KFServing Inference Protocol)、PyTorch、scikit-learn、 ハグフェイスとカスタムモデル。
# Installazione Seldon Core v2 via Helm
helm repo add seldonio https://storage.googleapis.com/seldon-charts
helm install seldon-core-v2 seldonio/seldon-core-v2 \
--namespace seldon-mesh \
--create-namespace \
--set controller.clusterwide=true
# Model: singolo modello XGBoost
apiVersion: mlops.seldon.io/v1alpha1
kind: Model
metadata:
name: churn-xgb
namespace: ml-serving
spec:
storageUri: "gs://my-ml-bucket/models/churn-xgb/v2"
requirements:
- xgboost
memory: 100Mi
# Pipeline: preprocessing + prediction + postprocessing
apiVersion: mlops.seldon.io/v1alpha1
kind: Pipeline
metadata:
name: churn-pipeline
namespace: ml-serving
spec:
steps:
- name: preprocessor
inputs:
- churn-pipeline.inputs
- name: churn-xgb
inputs:
- preprocessor.outputs
- name: postprocessor
inputs:
- churn-xgb.outputs
output:
steps:
- postprocessor
# Autoscaling basato su RPS
replicas: 1
scaling:
replicas:
minReplicas: 1
maxReplicas: 8
metric: rps
target: 100
KServe と Seldon コア: どちらを選択するか
- Kサーブ: 単一モデル、Knative および Istio との統合、ネイティブ スケール トゥ ゼロ、CNCF コミュニティに最適です。 K8s ML から始めるチームに最適です。
- セルドンコア v2: 複雑なパイプライン、アンサンブル、Kafka 統合、マルチモデル サービングに最適です。ビジネス ロジック ルーティングを備えた高度な ML アーキテクチャに最適です。
- 両方: V2 プロトコル、Prometheus モニタリング、GPU サービス用の Triton をサポートします。これらは相互に排他的ではなく、組織によっては、さまざまなユースケースでこれらを一緒に使用しています。
インテリジェントな自動スケーリング: HPA、VPA、KEDA
ML ワークロードのスケーリングは、従来の Web アプリケーションよりも複雑です。 CPU とメモリのメトリクスは、モデルの実際の負荷を正確に反映していないことがよくあります。 GPU バウンド モデルでは、CPU が 80% アイドル状態であるときにグラフィックス カードが飽和状態になる可能性があります。 Kubernetes は 3 つの補完的な自動スケーリング メカニズムを提供しており、これらを正しく組み合わせて使用すると、 すべての ML シナリオをカバーしています。
# HPA (Horizontal Pod Autoscaler): scala il numero di repliche
# Configurazione per inference service basata su custom metrics
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: churn-predictor-hpa
namespace: ml-serving
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: churn-predictor
minReplicas: 2
maxReplicas: 20
metrics:
# Scala su CPU (fallback)
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# Scala su custom metric: inference latency P99
- type: Pods
pods:
metric:
name: inference_request_duration_p99
target:
type: AverageValue
averageValue: "500m" # 500ms P99 latency target
behavior:
scaleUp:
stabilizationWindowSeconds: 30 # Reazione rapida al traffico
policies:
- type: Percent
value: 100
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300 # Lento a rimuovere pod (warm models)
# VPA (Vertical Pod Autoscaler): ottimizza resources requests/limits
# NOTA: non usare VPA e HPA sulle stesse metriche CPU/Memory!
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: batch-trainer-vpa
namespace: ml-training
spec:
targetRef:
apiVersion: batch/v1
kind: Job
name: model-training
updatePolicy:
updateMode: "Off" # Solo raccomandazioni, non applica auto (Off | Initial | Recreate)
resourcePolicy:
containerPolicies:
- containerName: trainer
minAllowed:
cpu: "1"
memory: 4Gi
maxAllowed:
cpu: "16"
memory: 128Gi
controlledResources: ["cpu", "memory"]
# Leggi le raccomandazioni VPA
kubectl describe vpa batch-trainer-vpa
# Output:
# Recommendation:
# Container Recommendations:
# Container Name: trainer
# Lower Bound: cpu: 2, memory: 8Gi
# Target: cpu: 6, memory: 32Gi
# Upper Bound: cpu: 12, memory: 64Gi
ケダ (Kubernetes Event-Driven Autoscaler、CNCF 卒業プロジェクト) および イベント駆動型 ML ワークロード用の最も強力なツール: イベントに基づいてポッドをスケールする メッセージ キュー、データベース、Prometheus メトリクス、または HTTP トリガーからの送信も可能 バッチ処理の場合はゼロにスケールします。
# KEDA: scala i worker ML in base alla coda di inference requests
# Installazione
helm repo add kedacore https://kedacore.github.io/charts
helm install keda kedacore/keda --namespace keda --create-namespace
# ScaledObject per batch ML processing da RabbitMQ
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: ml-batch-processor-scaler
namespace: ml-serving
spec:
scaleTargetRef:
name: batch-ml-processor
minReplicaCount: 0 # Scale-to-zero quando coda vuota
maxReplicaCount: 30 # Max 30 worker per GPU cluster
pollingInterval: 15 # Controlla la coda ogni 15 secondi
cooldownPeriod: 60 # Aspetta 60s prima di scale-down
triggers:
- type: rabbitmq
metadata:
host: amqp://rabbitmq.ml-serving.svc.cluster.local
queueName: inference-requests
mode: QueueLength
value: "10" # 1 pod ogni 10 messaggi in coda
# Trigger alternativo: Prometheus metric
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc.cluster.local:9090
metricName: inference_queue_depth
query: sum(inference_queue_depth{namespace="ml-serving"})
threshold: "50" # 1 replica ogni 50 richieste pendenti
ML のパターン自動スケーリング: 推奨事項
異なる責任を持つ 3 つのメカニズムを組み合わせます。
- HPA オンライン推論のレイテンシー/RPS (応答性、高速)
- VPA がオフ モード トレーニング ジョブ リクエストを最適化するため (手動で確認して更新します)
- ケダ バッチ処理およびイベント駆動型パイプライン用 (ゼロへのスケールを含む)
同じリソース (CPU/メモリ) 上で HPA と VPA を同時に使用しないでください: 競合します。
スケーリングは予測できない変動とリソースの無駄を引き起こします。
リソース管理と優先クラス
異なる ML チーム間で共有されるクラスターでは、リソース管理が重要です。 トレーニング ジョブが本番環境または実験での推論をブロックしないようにする 利用可能なすべての GPU を消費します。 Kubernetes は 3 つのツールを提供します。 リソースクォータ, 制限範囲 e 優先クラス.
# ResourceQuota: limita risorse per namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: ml-serving-quota
namespace: ml-serving
spec:
hard:
requests.cpu: "40"
requests.memory: 160Gi
limits.cpu: "80"
limits.memory: 320Gi
requests.nvidia.com/gpu: "4" # Max 4 GPU per inference namespace
limits.nvidia.com/gpu: "4"
pods: "50"
---
# LimitRange: imposta defaults e limiti per singolo container
apiVersion: v1
kind: LimitRange
metadata:
name: ml-container-limits
namespace: ml-serving
spec:
limits:
- type: Container
default: # Default limits se non specificati
cpu: "2"
memory: 4Gi
defaultRequest: # Default requests se non specificati
cpu: "500m"
memory: 1Gi
max: # Massimo per container
cpu: "8"
memory: 32Gi
nvidia.com/gpu: "2"
min: # Minimo per container
cpu: "100m"
memory: 256Mi
---
# PriorityClass: garantisce che l'inferenza non venga preemptata dal training
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: ml-inference-critical
value: 1000000 # Alta priorità per serving
globalDefault: false
description: "Inference services critici - non preemptabili"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: ml-training-batch
value: 100000 # Bassa priorità per training
preemptionPolicy: PreemptLowerPriority
description: "Training jobs - preemptabili se necessario"
Il ノードアフィニティ そして私 汚染/容認 許可してください ML ワークロードがどのノードにスケジュールされるかを正確に制御し、 トレーニング ジョブは同じ GPU 上の推論と競合しないことを示します。
# Taint nodi GPU dedicati all'inferenza
kubectl taint nodes gpu-inference-1 dedicated=inference:NoSchedule
kubectl taint nodes gpu-inference-2 dedicated=inference:NoSchedule
# Solo pod con toleration possono usare questi nodi
# InferenceService spec con affinity e toleration
spec:
predictor:
tolerations:
- key: dedicated
operator: Equal
value: inference
effect: NoSchedule
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: accelerator
operator: In
values:
- nvidia-a100
- nvidia-h100
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: churn-predictor
topologyKey: kubernetes.io/hostname
# Distribuisce repliche su host diversi per HA
Prometheus と Grafana による ML のモニタリング
Kubernetes で ML システムを監視するには、次の 2 つのレベルのメトリクスが必要です。 Kubernetes の標準インフラストラクチャ (CPU、メモリ、ネットワーク) と特定のメトリクス ML 推論 (モデルまでのレイテンシ、スループット、エラー率、データ ドリフト信号)。 KServe と Seldon は、Prometheus メトリクスを標準形式で自動的に公開します。
# Configurazione Prometheus per scraping KServe metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kserve-inference-monitor
namespace: ml-monitoring
labels:
release: prometheus
spec:
namespaceSelector:
matchNames:
- ml-serving
selector:
matchLabels:
serving.kserve.io/inferenceservice: "true"
endpoints:
- port: metrics
interval: 15s
path: /metrics
honorLabels: true
# Metriche KServe esposte automaticamente:
# kserve_inference_request_total{model_name, namespace, status_code}
# kserve_inference_request_duration_seconds{model_name, quantile}
# kserve_inference_request_size_bytes{model_name}
# kserve_inference_response_size_bytes{model_name}
# PrometheusRule: alert per latenza elevata
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: ml-inference-alerts
namespace: ml-monitoring
spec:
groups:
- name: ml-inference.rules
rules:
- alert: HighInferenceLatency
expr: |
histogram_quantile(0.99,
rate(kserve_inference_request_duration_seconds_bucket[5m])
) > 1.0
for: 5m
labels:
severity: warning
annotations:
summary: "P99 latency > 1s per {{ $labels.model_name }}"
description: "Modello {{ $labels.model_name }} ha latenza P99 di {{ $value }}s"
- alert: ModelErrorRateHigh
expr: |
rate(kserve_inference_request_total{status_code!="200"}[5m])
/ rate(kserve_inference_request_total[5m]) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "Error rate > 5% per {{ $labels.model_name }}"
# Dashboard Grafana: query principali per ML inference monitoring
# (da importare come JSON o configurare manualmente)
# 1. Throughput modello (req/sec)
rate(kserve_inference_request_total[5m])
# 2. Latenza P50, P95, P99
histogram_quantile(0.50, rate(kserve_inference_request_duration_seconds_bucket[5m]))
histogram_quantile(0.95, rate(kserve_inference_request_duration_seconds_bucket[5m]))
histogram_quantile(0.99, rate(kserve_inference_request_duration_seconds_bucket[5m]))
# 3. GPU Utilization per nodo (richiede NVIDIA DCGM Exporter)
DCGM_FI_DEV_GPU_UTIL{namespace="ml-serving"}
# 4. GPU Memory in uso
DCGM_FI_DEV_FB_USED{namespace="ml-serving"} /
DCGM_FI_DEV_FB_TOTAL{namespace="ml-serving"} * 100
# 5. Numero repliche attive per modello
kube_deployment_status_replicas_available{
namespace="ml-serving",
deployment=~".*-predictor.*"
}
# 6. Scaling events (utile per debug autoscaler)
kube_horizontalpodautoscaler_status_desired_replicas{
namespace="ml-serving"
}
クラスター ML のコストの最適化
GPU は ML クラスターの主要なコスト項目です。NVIDIA A100 SXM4 のコストはおよそ クラウドでは 2 ~ 3 ドル/時間、H100 では 4 ~ 5 ドル/時間。 20 GPU のクラスターでは、月額コストは次のようになります。 10万ドルを超える。コストの最適化はオプションではありません。
コスト最適化戦略
- トレーニング用のスポット/プリエンプティブル インスタンス: ジョブごとに 60 ~ 80% の節約 中断に耐性がある。自動再開には、頻繁なチェックポイントと Argo ワークフローを使用します。
- 臨時モデルのゼロへのスケール: minReplicas=0 の KServe リセット モデルがトラフィックを受信しない場合の GPU のコスト。
- 軽量推論のための GPU タイム スライシング: 物理 GPU ごとに 4 ~ 8 モデルの削減 モデルあたりのコストは 4 ~ 8 倍。
- 混合ノード プールを含むオートスケーラー クラスター: GPU ノードの追加/削除 実際のクラスターの負荷に基づいて自動的に実行されます。
- Karpenter によるノードの統合: ポッドをより少ないノードに迅速に統合する 空のノードを終了します (使用量が変動するクラスターで 20 ~ 40% の節約)。
# Cluster Autoscaler per node pool GPU
# (esempio GKE, ma concettualmente uguale per EKS/AKS)
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-autoscaler-config
namespace: kube-system
data:
config.yaml: |
nodeGroups:
- name: gpu-a100-pool
minSize: 0 # Scala a zero se nessun workload GPU
maxSize: 10 # Max 10 nodi A100
machineType: a2-highgpu-1g
expander: least-waste # Usa il nodo che spreca meno risorse
scaleDownUnneededTime: 10m # Rimuovi nodo inutilizzato dopo 10 min
scaleDownUtilizationThreshold: 0.5 # Scala down se utilizzo < 50%
skipNodesWithSystemPods: false
# Cost tracking con labels obbligatorie su tutti i workload
# Ogni Job/Deployment deve avere questi labels per tracking
metadata:
labels:
cost-center: "data-science"
project: "churn-prediction"
environment: "production"
model-version: "v3"
完全な展開: エンドツーエンドのパイプライン
すべてのコンポーネントをモデルの完全な Helm デプロイメントに統合する方法を見てみましょう 本番環境では、KServe、Prometheus モニタリング、自動スケーリングと KEDA を組み合わせています。
# Helm Chart structure per ML service completo
# charts/ml-inference-service/
# ├── Chart.yaml
# ├── values.yaml
# └── templates/
# ├── inference-service.yaml
# ├── hpa.yaml
# ├── service-monitor.yaml
# └── network-policy.yaml
# values.yaml
model:
name: "churn-predictor"
version: "v3"
storageUri: "gs://my-ml-bucket/models/churn-model/v3"
framework: "sklearn"
runtimeVersion: "1.5.2"
scaling:
minReplicas: 2
maxReplicas: 20
targetRPS: 50
targetLatencyP99: "500m"
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "4Gi"
monitoring:
enabled: true
prometheusNamespace: "ml-monitoring"
grafanaDashboard: true
canary:
enabled: false
weight: 0
# Deploy
helm upgrade --install churn-predictor ./charts/ml-inference-service \
--namespace ml-serving \
--values production-values.yaml \
--wait --timeout 10m
# Verifica deployment
kubectl get inferenceservice -n ml-serving
# NAME URL READY PREV LATEST ...
# churn-predictor http://churn-predictor True 0 100 ...
ベストプラクティスとアンチパターン
技術的な実装を確認した後、ML の導入から学んだ教訓を次に示します。 エンタープライズ環境における Kubernetes:
ベストプラクティス
- 常にリソース要求と制限を指定します。 リクエストがなければ、 スケジューラはポッドを正しく配置できません。 OOM モデルには制限がなく、次のことが可能です。 ノード全体を不安定にします。
- ML 固有の Readiness プローブを使用します。 コンテナは可能です 「実行中」ですが、モデルはまだロード中です。 Readiness Probe はチェックする必要があります モデルが実際に提供できる状態にあることを確認します。
- GPU ノード上のイメージを事前にプルします。 CUDA を使用した PyTorch イメージ 10GBを超えることもよくあります。 DaemonSet またはイメージの事前キャッシュを使用して、コールド スタートの頻度が高くならないようにします。
- 環境ごとに名前空間を分離します。 異なる名前空間でのステージングと本番環境 個別の ResourceQuota を使用すると、偶発的な干渉が回避されます。
- サーキットブレーカーを実装します。 モデルのエラー率が 10% を超える場合は停止します Istio またはサイドカー プロキシを使用して自動的にトラフィックします。
- 明示的なモデルのバージョン管理: すべての InferenceService には次のものが必要です 名前またはラベル内のバージョンタグ。運用環境では「最新」を決して使用しないでください。
避けるべきアンチパターン
- 推論ノードでのトレーニング: トレーニング ジョブが CPU/GPU を飽和させる e 実稼働モデルでレイテンシーのスパイクを引き起こします。テイントのある別のノード プールを常に使用してください。
- GPU バウンド モデルの CPU 上の HPA: CPU の負荷が低い可能性があります。 GPU と飽和。 GPU ワークロードには常にカスタム メトリクス (レイテンシ、RPS、GPU 使用率) を使用してください。
-
正常なシャットダウンはありません: ML ポッドはリクエストを完了する必要があります
終了前のコース。常に設定する
terminationGracePeriodSeconds>= 30代。 - Docker イメージのモデル: 画像にモデルの重みを含める Docker により更新が遅くなり、イメージが巨大になります。別のモデル ストレージ (S3、GCS) を使用します。
-
中断予算なし: それなし
PodDisruptionBudget、 クラスターの更新では、すべてのモデルのレプリカを同時に削除できます。
中小企業の予算: 年間 5,000 ユーロ未満から開始
Kubernetes で ML を始めるのに、月額 10 万ドルのエンタープライズ クラスターは必要ありません。ここ 予算が限られている中小企業にとって現実的なスタック:
- クラウド VM 上の K3s クラスター (2 ノード、8 vCPU、32GB RAM): 月額約 150 ~ 200 ユーロ。 K3s は Rancher の軽量 Kubernetes ディストリビューションであり、小規模クラスターに最適です。
- 1 NVIDIA T4 GPU ノード (スポット インスタンス): 0.35 ~ 0.50 ユーロ/時間、約 120 ~ 180 ユーロ/月 1日12時間使用した場合。必要がない場合はゼロまでスケールします。
- KServe + MLflow + プロメテウス: すべて無料、オープンソース、インストール可能 ヘルムと30分で。
- S3 互換ストレージ (セルフホスト型 MinIO): ライセンス費用はゼロ、ストレージのみ。 100 GB のモデルとデータセット: クラウド オブジェクト ストレージで月額約 2 ~ 5 ユーロ。
推定合計額: 300 ~ 400 ユーロ/月、5,000 ユーロ/年未満 環境のために GPU、完全なモニタリング、自動スケーリングを備え、実稼働環境に対応しています。比較のために、SageMaker 同等の構成の場合、コストは 3 ~ 5 倍になります。
結論
Kubernetes が本番環境に ML モデルをデプロイするための業界標準であるのには、次のような理由があります。 GPU スケジューリング、イベント駆動型自動スケーリング、ワークロード分離の独自の組み合わせを提供します。 他のプラットフォームでは実現できない特殊なツール (KServe、Seldon、KEDA) のエコシステム 柔軟性と長期的なコストの点で一致します。
初心者向けの最適なパス: GPU ノードを使用して K3s クラスターをセットアップし、KServe をインストールします 最初のモデルを提供するために、モニタリングのために Prometheus と Grafana を追加するだけです。 実稼働環境でクラスターが 5 ~ 10 モデルを超えて成長する場合は、KEDA および Seldon Core に投資します。 より複雑なアーキテクチャ。 Kubernetes の複雑さは、 仕事量がそれを正当化します。
シリーズの次の記事では、 ML ガバナンス: 保証方法 EU の AI 法への準拠、SHAP および LIME による説明可能性の実装、監査証跡の管理 本番環境におけるモデルの公平性。
このシリーズの関連記事
- サービス提供モデル: FastAPI + Uvicorn の実稼働環境 - Kubernetes以前のモデル
- ML モデルの A/B テスト - Canary ロールアウトとトラフィック分割
- ML ガバナンス: コンプライアンス、監査、倫理 - 次の記事
- モデルのドリフト検出と自動再トレーニング - 高度な監視
クロスシリーズ
- 高度な深層学習シリーズ - K8 にデプロイするための複雑なモデルのトレーニング
- コンピュータビジョンシリーズ - GPU 推論用に最適化された CV テンプレート







