Introduction
In Kubernetes, controlling where a pod runs is essential for optimizing performance, ensuring high availability, and meeting specific hardware or compliance requirements. You can achieve this using nodeSelector and nodeAffinity.
In this blog, we will cover:
- The nodeSelector approach.
- The nodeAffinity approach for advanced scheduling.
- A real-world use case where pod scheduling plays a critical role.
Using nodeSelector for Simple Scheduling
The nodeSelector field allows you to specify a key-value pair that a node must have for the pod to be scheduled on it.
Example: Scheduling a Pod on an SSD-backed Node
To schedule a pod only on nodes with an SSD disk type, you first label a node:
kubectl label nodes node-1 disktype=ssd
Now, create a pod specification using nodeSelector:
apiVersion: v1
kind: Pod
metadata:
name: specific-node-pod
spec:
nodeSelector:
disktype: ssd
containers:
- name: my-container
image: nginx
🔹 Limitations: nodeSelector provides a simple key-value matching but lacks advanced filtering capabilities.
Using nodeAffinity for More Advanced Scheduling
nodeAffinity offers more flexibility, allowing complex rules and conditions.
Example: Using nodeAffinity for Scheduling
apiVersion: v1
kind: Pod
metadata:
name: affinity-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: my-container
image: nginx
🔹 Key Benefits of nodeAffinity:
- Supports operators like
In,NotIn,Exists, etc. - Allows specifying multiple conditions.
- Provides both hard (required) and soft (preferred) scheduling rules.
Real-World Scenario: Scheduling Workloads Based on GPU Availability
Problem:
A machine learning application requires a GPU for training models efficiently. We must ensure that ML workloads run only on nodes equipped with GPUs.
Solution:
- Label GPU nodes:
kubectl label nodes gpu-node gpu=true
- Use nodeAffinity in Deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ml-workload
spec:
replicas: 2
template:
metadata:
labels:
app: ml-app
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"
containers:
- name: ml-container
image: tensorflow/tensorflow:latest-gpu
Best Practices for Pod Scheduling
- Label Nodes Wisely: Assign meaningful labels for resource types (e.g.,
ssd=true,gpu=true). - Use nodeAffinity Over nodeSelector: It provides better control with expressions and multiple conditions.
- Combine Affinity with Taints and Tolerations: To ensure that only intended workloads run on specialized nodes.
- Test Before Deployment: Use
kubectl describe node <node-name>to verify labels before scheduling.
Conclusion
Pod scheduling in Kubernetes allows precise control over where workloads run. Whether using nodeSelector for simple cases or nodeAffinity for advanced scheduling, these methods help optimize performance and ensure efficient resource utilization.
Would you like a guide on using taints and tolerations alongside affinity? Let us know in the comments!