In een Kubernetes Cluster kan het voorkomen dat je bepaalde pods op een vastgestelde worker-node (of groep worker-nodes) wilt installeren. Dit kan zijn omdat deze workers sneller zijn dan andere workers of omdat je de worker nodes in een externe load-balancer als endpoint hebt gedefinieerd. Hoe dan ook, we gaan het forceren want standaard kiest de cluster zelf de worker-node en dat willen we dus niet.
De meest simpele manier om pods aan een bepaalde node te koppelen is om in de manifest file aan te geven welke nodeName er gebruikt dient te worden, bijvoorbeeld:
apiVersion: v1 kind: Pod metadata: name: nginx spec: nodeName: node2 containers: - name: nginx image: nginx
Nu kan het natuurlijk zijn dat je een aantal gelijksoortige worker-nodes wilt gaan gebruiken en dan werkt de optie nodeName uiteraard niet. Een oplossing is hiervoor beschikbaar door ‘labels‘ te gebruiken.
Allereerst gaan we de workers, die we willen gebruiken als bestemming voor de pods, een label geven. (ookal is dat in mijn geval maar één worker-node per uniek label, maar het gaat om het idee)
$ kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 59d v1.16.2 node1 Ready worker 59d v1.16.2 node2 Ready worker 59d v1.16.2 $ kubectl label node node1 kleur=geel $ kubectl label node node2 kleur=groen $ kc get nodes --show-labels | grep worker node1 Ready worker 59d v1.16.2 ...,kleur=geel,... node2 Ready worker 59d v1.16.2 ...,kleur=groen,...
Zoals je ziet hebben de worker nodes in mijn cluster beiden een kleur gekregen, node1 is geel en node2 is groen. We maken nu een manifest file met daarin een nodeSelector:
apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx nodeSelector: kleur: groen
Als we deze manifest deployen naar de cluster zal de pod aangemaakt worden in de worker-node met het label kleur=groen, in dit geval is dat node2.
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx 1/1 Running 0 5m40s 10.44.0.2 node2
Pod Affinity en Anti-Affinity
Niet specifiek bedoeld voor deployments maar wel handig is het gebruik van affinity en anti-affinity. Voor het gebruik hiervan zijn twee opties beschikbaar:
- requiredDuringSchedulingIgnoredDuringExecution – hiermee wordt aangegeven dat de pod niet scheduled kan worden totdat de node aan de affinity voorwaarden voldoet
- preferredDuringSchedulingIgnoredDuringExecution – hiermee wordt aangegeven dat een pod zal proberen op een node te komen die aan de voorwaardes van de affinity voldoet, lukt dat niet dan kan een andere node gebruikt worden.
Een voorbeeld van een podAntiAffinity waarbij wordt voorkomen dat alle pods met label ‘app=simple-nginx’ op dezelfde node terecht komen:
spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - simple-nginx topologyKey: "kubernetes.io/hostname" container:
Dit komt dus in de spec: van de container te staan. (zorg wel voor genoeg ‘vrije’ nodes om te voorkomen dat pods in status ‘Pending’ blijven staan!)