Contents

Kubernetes Node Affinity

Why do you need Node Affinity?

Node Affinity
nodeSelector is not enough to set PODs on the specific Node.
If you want to make some limitations that are more complex than nodeSelector, you have to use affinity.

Compare nodeSelector and affinity

nodeSelctor node-selector.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: nginx
      image: nginx
  nodeSelector:
    size: Large

affinity affinity.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: nginx
      image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: size
                operator: In
                values:
                  - Large

affinity Types

DuringScheduling
The meaning of schedule is to bind the POD to the Node in Kubernetes.
So DuringScheduling means “How to apply when it’s binding”.
DuringExecution
DuringExecution means “Hwo to apply to the running PODs”.
TypeAction
requiredApply the Configuration
preferredTry to apply, but it’s not necessary
ignoreNo Action

operator Types in affinity

TypeAction
InIt is like ‘IN’ in SQL. The values is an array.
NotInIt is like NOT IN in SQL. The values is an array.
ExistsJust check the key is exists. The values is not defined.

Examples of affinity

Scenarios

There are three Nodes.
Each node has a label that key is ‘size’.
The labels are Large, Medium, and Small.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Large on node01
kubectl label nodes node01 size=Large

# Medium on node02
kubectl label nodes node02 size=Medium

# Small on node03
kubectl label nodes node03 size=Small

# Check labels
kubectl get nodes --show-labels

Scheduling PODs to Large Node

Use nodeSelector

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
  nodeSelector: Large

Use affinity

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: size
                operator: In
                values:
                  - Large

Scheduling PODs not to Small Node

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: size
                operator: NotIn
                values:
                  - Small

Scheduling PODs to Medium and Small Node

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: size
                operator: In
                values:
                  - Medinum
                  - Small

Deployment with affinity

blue-deployment.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue
spec:
  template:
    metadata:
      name: blue-pod
      labels:
        app: blue-app
    spec:
      containers:
        - name: nginx-container
          image: nginx
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: color
                    operator: In
                    values:
                      - blue
  replicas: 3
  selector:
    matchLabels:
      app: blue-app

red-deployment.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: apps/v1
kind: Deployment
metadata:
  name: red
spec:
  replicas: 2
  selector:
    matchLabels:
      app: red-app
  template:
    metadata:
      name: red-pod
      labels:
        app: red-app
    spec:
      containers:
        - name: nginx-container
          image: nginx
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: node-role.kubernetes.io/master
                    operator: Exists