Node affinity allows you to create more complex node placement, but it comes at the expense of a more complex definition.
With the nodeSelector, you are only able to select a single key-value for scheduling pods.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app-name: data-miner
spec:
containers:
- name: myapp-pod
image: apache/spark
nodeSelector:
size: Large
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app-name: data-miner
spec:
containers:
- name: myapp-pod
image: apache/spark
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: size
operator: In
values:
- Large
- Medium
Other operators are:
NotIn, Exists, NotExists (and more). Exists doesn't require the Values:, and just checked to see if the key exists on the node as a label
These are based on the time the pod is scheduled and doesn't care what happens to the labels once the pod is up and running. For example, if the pod starts and the matching label is then removed from the node after the pod starts, the pod will continue to run.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app-name: data-miner
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- YourAppLabel
topologyKey: "kubernetes.io/hostname"