Škálování ML na Kubernetes: Deployment and Orchestrace in Production
Váš model strojového učení prošel všemi offline testy, metriky jsou vynikající, poskytování přes FastAPI funguje lokálně perfektně. Pak přichází kritický okamžik: musíte to zvládnout 10 000 požadavků za sekundu, dynamicky škálovatelné na základě zatížení, zajišťuje vysokou dostupnost a nulové prostoje během aktualizací. Jedna nádoba již nestačí.
Kubernetes a stal se de facto standardem pro orchestraci pracovních zátěží ML v výroby, přičemž 78 % podnikových organizací jej používá pro modelové nasazení podle CNCF Survey 2025. Nestačí však dát model do podu: je třeba jej spravovat Plánování GPU, automatické škálování řízené událostmi, kvóty zdrojů, nasazení a monitorování specializované na vyvozování. Trh MLOps, který bude mít v roce 2026 hodnotu 4,38 miliardy dolarů, s CAGR 39,8 %, má svůj hlavní škálovací motor v Kubernetes.
V tomto článku prozkoumáme kompletní architekturu pro přenos modelů ML do Kubernetes výroba: od KServe a Seldon Core pro inferenční obsluhu až po plánování GPU se zařízením NVIDIA Pluginy, přes inteligentní automatické škálování s HPA, VPA a KEDA, až po monitorování pomocí Prometheus a Grafana.
Co se naučíte
- proč je Kubernetes standardem pro ML v produkci a kdy jej použít
- Plánování a sdílení GPU pomocí NVIDIA Device Plugin a MIG
- KServe: Nasazení InferenceService se zavedením canary a škálováním na nulu
- Seldon Core v2: Složitelné a vícemodelové servisní potrubí
- Pokročilé automatické škálování: HPA, VPA a KEDA pro událostmi řízené pracovní zatížení ML
- Správa zdrojů: požadavky, limity, prioritní třídy a afinita uzlů
- Monitoring s Prometheus + Grafana specializovaný na ML odvození
- Optimalizace nákladů a doporučené postupy pro clustery GPU
proč Kubernetes pro ML v produkci
Než se ponoříme do technické konfigurace, je nezbytné pochopit, proč Kubernetes Prosadila se jako referenční platforma pro ML zátěže, překonávající řešení jako např bare metal, vyhrazené virtuální počítače nebo proprietární cloudové služby.
Úlohy ML mají ve srovnání s tradičními webovými aplikacemi jedinečné vlastnosti. Školení vyžaduje masivní GPU na hodiny nebo dny, pak je třeba uvolnit zdroje. Závěr má nepředvídatelné vrcholy a kritická latence. Modely musí být aktualizovány bez prostojů. Datové sady mohou být obrovské a vyžadují specializované úložiště. Kubernetes řeší všechny tyto scénáře s nativními primitivy: plánování podu na konkrétních uzlech GPU, trvalé svazky na datovou sadu, úlohy pro dávkové školení, HorizontalPodAutoscaler pro odvození měřítka.
Kubernetes vs cloudově řízená alternativa
Samoobslužné nebo spravované Kubernetes (EKS, GKE, AKS): úplná kontrola,
multi-cloudová přenositelnost, optimalizovatelné náklady, ale vysoká provozní složitost.
SageMaker / Vertex AI / Azure ML: rychlé nastavení, cloudová nativní integrace,
ale uzamčení dodavatele, vyšší dlouhodobé náklady a menší flexibilita pro vlastní architektury.
Základní pravidlo: tým <5 lidí nebo omezený rozpočet? Začněte se spravovaným ML.
Tým >5 s více modely ve výrobě? Kubernetes vrátí vaši investici za 6-12 měsíců.
Referenční architektura
Cluster Kubernetes pro ML v produkci je obvykle strukturován na třech odlišných vrstvách, každá z nich s dobře definovanými povinnostmi:
- Vrstva infrastruktury: Uzly CPU pro obsluhu světla a orchestraci, uzly GPU pro trénink a těžké vyvozování, uzly úložiště pro datové sady a artefakty. GPU bazény jsou oddělené konkrétními štítky uzlů.
- Vrstva platformy: KServe nebo Seldon Core pro inferenční obsluhu, Kubeflow pro tréninkový kanál, MLflow pro experimentální sledování (viz článek 4), Argo Workflows pro složitá orchestrace.
- Vrstva pozorovatelnosti: Prometheus pro metriky, Grafana pro dashboardy, Jaeger pro distribuované sledování, Loki pro agregaci protokolů.
# 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
Plánování a sdílení GPU
GPU jsou nejdražším zdrojem clusteru ML. Spravovat je špatně znamená plýtvat desítkami
tisíce eur měsíčně. Kubernetes odhaluje GPU jako plánovatelné zdroje prostřednictvím
Pluginy zařízení NVIDIA, DaemonSet, který automaticky detekuje GPU na uzlech
a zaznamená je jako nvidia.com/gpu v kubeletu.
# 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
Pro inferenční úlohy, které nevyžadují plnou GPU, nabízí NVIDIA dvě strategie Sdílení GPU: Časové krájení e Multi-Instance 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
Time-Slicing vs MIG: Kdy použít který
Časové dělení: vhodné pro nenáročnou pracovní zátěž (<2GB modely VRAM), zavádí latenci z přepínání kontextu. Funguje na jakémkoli GPU NVIDIA. MIG: úplná hardwarová izolace, garantovaná vyhrazená paměť, nulové rušení mezi pracovní zátěží. K dispozici pouze u A100, A30, H100. Ideální pro přísné latence SLA. Nikdy nekombinujte dva přístupy na stejném uzlu.
KServe: Native Inference Serving na Kubernetes
KPodávat (dříve KFServing) a standard CNCF pro inferenční poskytování na Kubernetes,
vznikl ze spolupráce společností Google, IBM, Bloomberg a dalších. Poskytuje abstrakci
InferenceService který skrývá složitost nasazení, správu automaticky
Canary rollout, škálování na nulu, automatické škálování založené na požadavcích a podpora více rámců
(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"
Jednou ze silných stránek KServe je nativní podpora pro i Zavedení Canary: můžete poslat procento provozu do nové verze šablony, zatímco zbytek pokračujte v používání stabilního, přesně jako A/B testování, které jsme viděli v článku předchozí v této sérii.
# 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]]}'
Vlastnost měřítko na nulu KServe (založené na Knative Serving) e zvláště cenné pro občas používané modely: modul se po určité době vypne konfigurovatelná doba nečinnosti a automaticky se restartuje při prvním požadavku se studeným startem obvykle méně než 30 sekund u modelů předem uložených do mezipaměti.
# 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: Composable ML Pipelines
Zatímco KServe vyniká při obsluze jednotlivých modelů, Seldon Core v2 svítí při správě komplexních architektur ML: vícekrokové potrubí, modelové soubory, A/B směrování s obchodní logikou a integrace s Kafkou pro zpracování streamů. Seldon v2 používá MLServer jako inferenční runtime, kompatibilní s protokolem V2 (KFServing Inference Protocol) a nativně podporuje PyTorch, scikit-learn, Objímání obličeje a vlastní modely.
# 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 vs Seldon Core: Který si vybrat
- KPodávat: nejlepší pro jednotlivé modely, integrace s Knative a Istio, nativní měřítko na nulu, komunita CNCF. Ideální pro týmy začínající s K8s ML.
- Seldon Core v2: nejlepší pro komplexní potrubí, soubory, Kafkova integrace, multi-modelové podávání. Ideální pro pokročilé architektury ML se směrováním obchodní logiky.
- Obě: podpora protokolu V2, monitorování Prometheus, Triton pro obsluhu GPU. Vzájemně se nevylučují, některé organizace je používají společně pro různé případy použití.
Inteligentní automatické škálování: HPA, VPA a KEDA
Škálování zátěže ML je složitější než tradiční webové aplikace. Metriky CPU a paměti často přesně neodrážejí skutečné zatížení modelu: model vázaný na GPU může zasytit grafickou kartu, když je CPU na 80 % nečinnosti. Kubernetes nabízí tři komplementární mechanismy automatického škálování, které při správném použití společně pokrývají všechny scénáře 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
KEDA (Kubernetes Event-Driven Autoscaler, CNCF absolventský projekt) a podobně Nejvýkonnější nástroj pro pracovní zátěže ML řízené událostmi: Škálujte moduly na základě událostí z front zpráv, databází, metrik Prometheus nebo spouštěčů HTTP, což také umožňuje měřítko na nulu pro dávkové zpracování.
# 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
Automatické škálování vzoru pro ML: Doporučení
Kombinuje tři mechanismy s různými odpovědnostmi:
- HPA na latenci/RPS pro online odvození (responzivní, rychlé)
- VPA ve vypnutém režimu pro optimalizaci požadavků na školení (kontrola a aktualizace ručně)
- KEDA pro dávkové zpracování a kanály řízené událostmi (včetně měřítka na nulu)
Nepoužívejte HPA a VPA na stejném prostředku (CPU/paměť) současně: konflikty
škálování způsobuje nepředvídatelné výkyvy a plýtvání zdroji.
Řízení zdrojů a prioritní třídy
V clusteru sdíleném mezi různými týmy ML je správa zdrojů zásadní zabránit tomu, aby tréninková úloha zablokovala odvození ve výrobě nebo experimentu spotřebují všechna dostupná GPU. Kubernetes nabízí tři nástroje: ResourceQuota, LimitRange e PriorityClass.
# 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 Afinita uzlu a já Poskvrny/tolerance dovolit vám to přesně kontrolovat, na kterých uzlech jsou naplánovány pracovní zátěže ML a zajistit že tréninkové úlohy si nekonkurují s dedukcí na stejných 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
Monitorování pomocí Prometheus a Grafana pro ML
Monitorování systému ML na Kubernetes vyžaduje metriky na dvou úrovních: metriky Standardní infrastruktura Kubernetes (CPU, paměť, síť) a specifické metriky odvození ML (latence k modelu, propustnost, chybovost, signál posunu dat). KServe a Seldon automaticky vystavují metriky Prometheus ve standardním formátu.
# 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"
}
Optimalizace nákladů pro Cluster ML
GPU jsou dominantní nákladovou položkou clusteru ML: NVIDIA A100 SXM4 stojí přibližně 2-3 $/hod v cloudu, H100 4-5 $/hod. Na clusteru 20 GPU mohou měsíční náklady překročit 100 000 $. Optimalizace nákladů není volitelná.
Strategie optimalizace nákladů
- Namátkové/preventivní případy pro trénink: úspora 60-80 % na pracovní místo tolerantní k přerušení. Používejte časté kontrolní body a Argo Workflows pro automatické obnovení.
- Měřítko na nulu pro příležitostné modely: KServe s minReplicas=0 resetuje náklady na GPU, když model nepřijímá žádný provoz.
- GPU Time-Slicing pro lehkou inferenci: Snížení 4–8 modelů na fyzický GPU cena za model 4-8x.
- Cluster Autoscaler se smíšenými fondy uzlů: Přidány/odstraněny uzly GPU automaticky na základě skutečného zatížení clusteru.
- Konsolidace uzlů pomocí Karpenter: konsolidujte lusky na méně uzlech dříve k ukončení prázdných uzlů (20-40% úspora na clusterech s variabilním využitím).
# 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"
Plné nasazení: End-to-End Pipeline
Podívejme se, jak integrovat všechny komponenty do kompletního nasazení Helm pro model výroba, kombinující KServe, monitorování Prometheus a autoscaling s 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 ...
Osvědčené postupy a anti-vzorce
Poté, co jste viděli technickou implementaci, zde jsou lekce získané z nasazení ML na Kubernetes v podnikových prostředích:
Nejlepší postupy
- Vždy specifikujte požadavky na zdroje A limity: bez žádostí, plánovač nemůže umístit moduly správně. Model OOM může bez omezení destabilizovat celý uzel.
- Použijte sondy připravenosti specifické pro ML: kontejner může být "běží", ale model se stále načítá. Musí se zkontrolovat sonda připravenosti že model je skutečně připraven sloužit.
- Pre-pull obrázky na GPU uzlech: Obrázky PyTorch s CUDA často přesahují 10 GB. Použijte DaemonSet nebo předběžné ukládání obrazu do mezipaměti, abyste se vyhnuli vysokým studeným startům.
- Oddělte jmenné prostory podle prostředí: inscenace a produkce na různých jmenných prostorech s odlišnou ResourceQuota zabraňuje náhodnému rušení.
- Implementujte jistič: pokud má model chybovost > 10 %, zastavte provoz automaticky pomocí Istio nebo proxy postranního vozíku.
- Explicitní verzování modelu: musí mít každá služba InferenceService značku verze v názvu nebo štítcích. Nikdy nepoužívejte "nejnovější" ve výrobě.
Anti-vzory, kterým je třeba se vyhnout
- Školení na inferenčních uzlech: tréninkové úlohy saturují CPU/GPU e způsobit špičky latence na produkčních modelech. Vždy používejte oddělené fondy uzlů se skvrnami.
- HPA na CPU pro modely s GPU: CPU může být nízký, zatímco GPU a saturace. Vždy používejte vlastní metriky (latence, RPS, využití GPU) pro zátěž GPU.
-
Žádné elegantní vypnutí: Pody ML musí dokončit požadavky v
kurz před dokončením. Vždy konfigurovat
terminationGracePeriodSeconds>= 30s. - Modely v obrázcích Docker: zahrňte do obrázku závaží modelu Docker zpomaluje aktualizace a obrázky jsou obrovské. Použijte samostatné úložiště modelu (S3, GCS).
-
Rozpočet bez přerušení: bez
PodDisruptionBudget, aktualizace clusteru může odstranit všechny repliky modelu současně.
Rozpočet pro malé a střední podniky: Začněte s méně než 5 000 EUR/rok
Abyste mohli začít s ML na Kubernetes, nepotřebujete podnikový cluster za 100 000 $ měsíčně. Tady realistický zásobník pro MSP s omezeným rozpočtem:
- Cluster K3s na cloudovém VM (2 uzly, 8 vCPU, 32 GB RAM): cca 150-200 EUR/měsíc. K3s je lehká distribuce Kubernetes Rancher, ideální pro malé clustery.
- 1 uzel GPU NVIDIA T4 (spot instance): 0,35-0,50 EUR/hod, přibližně 120-180 EUR/měsíc při používání 12 hodin/den. Měřítko na nulu, když to nepotřebujete.
- KServe + MLflow + Prometheus: vše zdarma, open source, instalovatelné s Helmem za 30 minut.
- Úložiště kompatibilní s S3 (vlastně hostované MinIO): 0 licenčních nákladů, pouze skladování. 100 GB modelů a datových sad: přibližně 2–5 EUR/měsíc na cloudovém úložišti objektů.
Odhadovaná celková částka: 300–400 EUR/měsíc, méně než 5 000 EUR/rok pro životní prostředí připraveno k produkci s GPU, plným monitorováním a automatickým škálováním. Pro srovnání SageMaker s ekvivalentní konfigurací by to stálo 3-5x více.
Závěry
Kubernetes je průmyslový standard pro nasazování modelů ML v produkci z nějakého důvodu: nabízí jedinečnou kombinaci plánování GPU, událostmi řízeného automatického škálování a izolace pracovní zátěže a ekosystém specializovaných nástrojů (KServe, Seldon, KEDA), které žádná jiná platforma neumí z hlediska flexibility a dlouhodobých nákladů.
Optimální cesta pro začátečníky: Nastavte cluster K3s s uzlem GPU, nainstalujte KServe pro obsluhu prvního modelu přidejte Prometheus a Grafana pro sledování a je to když se klastr rozroste nad 5-10 modelů ve výrobě, investujte do KEDA a Seldon Core složitější architektury. Složitost Kubernetes se vyplatí pouze tehdy, když objem pracovní vytížení to ospravedlňuje.
V dalším článku série prozkoumáme ML řízení: jak zaručit soulad s AI Act EU, implementovat vysvětlitelnost pomocí SHAP a LIME, spravovat auditní záznamy a poctivost modelů ve výrobě.
Související články v této sérii
- Servírovací modely: FastAPI + Uvicorn ve výrobě - Model před Kubernetesem
- A/B testování ML modelů - Canary rollout a rozdělení dopravy
- ML Governance: Compliance, audit, etika - Další článek
- Detekce driftu modelu a automatické přeškolení - Pokročilé monitorování
Cross-Series
- Pokročilá řada hlubokého učení - Školení komplexních modelů pro nasazení na K8
- Řada Počítačové vidění - Šablony životopisů optimalizované pro odvození GPU







