08. GPU Node Selection
GPU node selection requires configuring which nodes receive pods requesting GPU resources. Kubernetes scheduler considers resource availability when placing pods, but GPU nodes require explicit labeling, taints, and node affinity rules to ensure proper placement.
Node labeling provides metadata for selection criteria. The standard labels nvidia.com/gpu.count, nvidia.com/gpu.memory, and nvidia.com/gpu.family annotate GPU characteristics without vendor-specific coupling.
# Label nodes with GPU characteristics
kubectl label node gpu-worker-1 \
nvidia.com/gpu.count=1 \
nvidia.com/gpu.memory=16Gi \
nvidia.com/gpu.family=A100
# List nodes with GPU resources
kubectl get nodes -l nvidia.com/gpu.count
Taints prevent pods from scheduling on nodes unless pods tolerate the taints. Taints pair with tolerations to create dedicated GPU pools that accept only GPU workloads. The taint effect determines behavior when untolerated pods attempt scheduling.
# Taint a GPU node to dedicated AI workloads
apiVersion: v1
kind: Node
metadata:
name: gpu-worker-1
spec:
taints:
- key: nvidia.com/gpu
value: "compute"
effect: NoSchedule
Node affinity rules select nodes based on labels while tolerations override taints. Pods specifying node affinity for GPU nodes automatically tolerate the GPU taint. The combination ensures only GPU-requiring workloads reach GPU nodes.
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: nvidia.com/gpu.count
operator:Gt
values:
- "0"
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: inference-server
topologyKey: kubernetes.io/hostname
Topology spread constraints distribute pods across failure domains. Specifying maxSkew ensures pods spread across zones or nodes, improving availability during zone failures. The topologyKey specifies the domain boundary for distribution.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: inference-server
Configure a GPU node pool in a Kubernetes cluster. Label the node with GPU characteristics, apply taints for dedicated scheduling, and deploy an inference workload using node affinity and topology spread constraints. Verify that the scheduler respects the constraints and pods spread appropriately.
# Label and taint the GPU node
kubectl label node worker-gpu-2 \
node.kubernetes.io/gpu-pool=ai-inference \
nvidia.com/gpu.product=NVIDIA-A100-40GB
kubectl taint node worker-gpu-2 \
nvidia.com/gpu=ai-inference:NoSchedule
# Deploy with matching toleration
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: inference-server
spec:
replicas: 3
selector:
matchLabels:
app: inference-server
template:
metadata:
labels:
app: inference-server
spec:
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: nvidia.com/gpu.product
operator: Exists
containers:
- name: inference
image: inference/model-server:v2.1
resources:
limits:
nvidia.com/gpu: 1
EOF