Úlohy AI a GPU na Kubernetes: Plugin zařízení a školicí úlohy
V roce 2026 běží 66 % AI inferenčních clusterů na Kubernetes (průzkum CNCF 2026). Důvod Je to jednoduché: Kubernetes řeší nejnáročnější provozní problémy pracovních zátěží AI – plánování inteligentní škálování GPU, elastické škálování školicích úloh, integrace s distribuovaným úložištěm pro datové sady automatické opakování v případě selhání uzlu. Ale nastavení Kubernetes pro i Pracovní zátěž GPU vyžaduje specifické dovednosti, které jdou nad rámec běžného nasazení webová aplikace.
V tomto článku uvidíme, jak nakonfigurovat Pluginy zařízení NVIDIA pro vystavit GPU clusteru, jak naplánovat Distribuovaná školení s PyTorch a TensorFlow, jak používat Karpenter provést bodové škálování GPU (snížení nákladů o 40–70 %) a vzory pro optimalizaci využití GPU při pracovní zátěži odvození do výroby.
Co se naučíte
- Instalace a konfigurace NVIDIA Device Plugin pro Kubernetes
- Plánování modulů s požadavky na GPU (zdroj nvidia.com/gpu)
- Distribuované školení s PyTorchJob a TFJob (Kubeflow Training Operator)
- Karpenter NodePool pro automatické zřizování bodových uzlů GPU
- GPU time-slicing pro sdílení GPU mezi více Pody
- MIG (Multi-Instance GPU) pro oddíl A100/H100 GPU
- Monitorování GPU pomocí DCGM Exporter a Grafana
- Vzor pro odvozování vysoké propustnosti s TorchServe na K8s
Architektura GPU na Kubernetes
Kubernetes nativně nezná GPU. GPU jsou vystaveny clusteru prostřednictvím Device Plugin Framework: DaemonSet, který běží na každém uzlu s GPU, se registruje u kubeletu a spravuje přidělování GPU kontejnerům. The NVIDIA Device Plugin je nejoblíbenější implementací tohoto rámce.
Instalace NVIDIA Device Plugin
# 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
Instalace NVIDIA GPU Operator (doporučený přístup)
U klastrů ve výrobě je Operátor GPU NVIDIA spravuje automaticky všechny potřebné komponenty: ovladače, zásuvné moduly zařízení, kontejner runtime, Exportér DCGM pro monitorování:
# 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
Plánování modulů s GPU
Jakmile je plugin zařízení aktivní, můžete požadovat GPU v manifestech jako kterékoli jiné jiný zdroj Kubernetes. rozdíl: nepoužíváte žádosti, pouze limity pro GPU (Kubernetes vždy garantuje přesně požadovaný počet 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"
Školení distribuováno s operátorem školení Kubeflow
Trénink velkých modelů často vyžaduje více GPU na více uzlech. The Operátor školení Kubeflow spravuje distribuované tréninkové úlohy s PyTorchJob, TFJob, MXJob a MPIJob. Nejprve nainstalujte operátor:
# 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
PyTorchJob pro školení více GPU s více uzly
# 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 pro Spot GPU Node Provisioning
GPU jsou nejdražším zdrojem v cloudu. Spot GPU instance stojí o 60–70 % méně ve srovnání s on-demand. Karpenter spravuje automatické zajišťování bodových uzlů GPU, s nouzovým režimem na vyžádání v případě výpadku:
# 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 Time-Slicing: Sdílejte GPU mezi více Pody
Pro nenáročnou inferenci nebo vývojovou zátěž je často celé GPU plýtváno. The GPU time-slicing umožňuje sdílet fyzický GPU mezi více Pody, z nichž každý vidí „virtuální GPU“ s částí výpočetního času:
# 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: Multi-Instance GPU pro A100 a H100
Podpora GPU NVIDIA A100 a H100 MIG (Multi-Instance GPU), to rozdělte GPU do izolovaných hardwarových instancí (nejen sdílení času). Každá instance MIG má zaručenou paměť a výpočet a neruší ostatní:
# 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
Monitorování GPU pomocí nástroje DCGM Exporter
Monitorování GPU je nezbytné pro pochopení, zda jsou tréninkové úlohy efektivní a pro FinOps. DCGM Exporter zpřístupňuje metriky GPU společnosti 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)
Nasazení modelů pro odvození s TorchServe
Pro produkční odvození potřebujete modelový server, který zpracovává vyrovnávání zátěže včetně replikace více modelů, dávkování požadavků a verzování. TorchServe a oficiální řešení 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"})
Osvědčené postupy pro pracovní zátěže AI na Kubernetes
Optimalizace nákladů na GPU
- Místo pro školení, na vyžádání pro odvození: Školení zvládne přerušení s kontrolními body; závěr musí být vždy k dispozici
- Časté kontrolní body: Ukládejte kontrolní body každých 30 minut, abyste mohli pokračovat v tréninku po přerušení na místě
- Časové dělení pro vývoj: Použijte časově rozdělené GPU pro vývojáře, MIG nebo plné GPU pro produkci
- Měřítko k nule: Karpenter odebere bodové uzly GPU po dokončení školení – neplatíte za nečinné GPU
- Dávkování v inferenci: TorchServe s batch_size=32 zvyšuje propustnost 10-20x ve srovnání s jednotlivými požadavky
- Profil před nasazením: Použijte NVIDIA Nsight k profilování své školicí práce a identifikaci neefektivity
Běžné chyby GPU na Kubernetes
- Nádoby bez tolerance ke znečištění: GPU uzly mají kaz
nvidia.com/gpu=true:NoSchedule; bez tolerance není modul naplánován v uzlu GPU - Selhání při izolaci paměti: GPU neizoluje paměť mezi kontejnery jako CPU. Pokud přidělíte 1 GPU, ale model využívá více paměti, než je k dispozici, úloha se zhroutí s CUDA OOM
- NCCL bez sdílené paměti: Distribuované školení PyTorch používá NCCL, které vyžaduje velké /dev/shm (typicky 10-60GB); vždy konfigurujte emptyDir s médiem: Memory
- Nesledovat využití GPU: GPU při 20% využití je obrovské plýtvání. Řídicí panel DCGM by měl být prvním místem, o které se budete starat po každém nasazení
Závěry a další kroky
Kubernetes se ne náhodou stal standardní platformou pro pracovní zátěže AI/ML: jeho abstrakce zdrojů, pokročilý systém plánování a ekosystém operátorů (Kubeflow, Training Operator) z něj činí ideální kontext pro organizaci obou školení ten závěr k měřítku. S Karpenter automaticky spravuje zajišťování uzlů Spot GPU, náklady na školení lze snížit o 40–70 % ve srovnání s používáním instancí na vyžádání.
Dalším krokem je integrace těchto úloh s kompletním kanálem MLOps: protokolování modelů s MLflow, správa datových souborů s DVC, CI/CD pro automatické přeškolení. Článek FinOps pro Kubernetes (článek 9 v této sérii) se zabývá tím, jak měřit a optimalizovat celkové náklady na pracovní zátěž GPU v clusteru.
Připravované články v sérii Kubernetes at Scale
Související série
- MLOps a strojové učení ve výrobě — Potrubí CI/CD pro ML, registr modelů
- Hluboké učení a neuronové sítě — teoretické základy modelového školení na GPU
- Automatické škálování v Kubernetes — KEDA pro škálování na základě vlastních metrik







