Kubernetes. Распределение Pod между Node
Ссылки
https://blog.kubecost.com/blog/kubernetes-node-affinity/
https://prudnitskiy.pro/post/2021-01-15-k8s-pod-distribution/
Входные данные
3 ноды:
kub-node-1
kub-node-2
kub-node-3
Способы управления распределением
NodeSelector
Распределение POD по нодам на основании маркировки нод
Маркируем ноды в кластере
Например по типам ЖД
--overwrite - перезаписывает label, если label с таким именем уже имеется
kubectl label nodes kub-node-1 --overwrite disk=ssd
kubectl label nodes kub-node-2 --overwrite disk=ssd
kubectl label nodes kub-node-3 --overwrite disk=hdd
Деплоим приложение, указывая по нодам с какими метками распределять поды: "nodeSelector: disk: ssd"
nano deployment_nodeSelector.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: enc-httpd-php namespace: enc labels: app: enc-httpd-php spec: replicas: 3 selector: matchLabels: app: enc-httpd-php template: metadata: labels: app: enc-httpd-php spec: containers: - name: enc-httpd-php image: registry.domain123.ru:5000/centos7-apache24-php54:v1.0 ports: - containerPort: 80 imagePullSecrets: - name: registry.domain123.ru.5000 nodeSelector: disk: ssd
kubectl apply -f deployment_nodeSelector.yaml
Видим что поды распределены только по нодам с меткой "ssd", на ноде с меткой "hdd" под не будет деплоиться
kubectl get pods -o wide -n enc
... NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES enc-httpd-php-65b5b9b48f-2r9ff 1/1 Running 0 13h 172.16.213.73 kub-node-2 <none> <none> enc-httpd-php-65b5b9b48f-59g6c 1/1 Running 0 13h 172.16.213.159 kub-node-1 <none> <none> enc-httpd-php-65b5b9b48f-r5m5n 1/1 Running 0 13h 172.16.213.160 kub-node-1 <none> <none> ...
NodeAffinity
Более гибкий и универсальный способ распределения
Особенности
- Логические операторы для выбора условия размещения – IN (размещать на одной из нод с разными метками) или AND (размещать на нодах, имеющих обе метки сразу)
- Можно выбрать политики размещения pod-ов относительно друг друга: например – запретить экземплярам кэша оказываться на одной физической машине или требовать размещение приложения вместе с экземпляром кеша на одном физическом узле
Общий принцип
...
spec:
affinity:
nodeAffinity:
{affinityClass}:
nodeSelectorTerms:
- matchExpressions:
- key: {affinityKey}
operator: {affinityOperator}
values:
- {affinityValues}
...
- affinityClass влияет на строгость выбора узла:
- requiredDuringSchedulingIgnoredDuringExecution: обязательно размещать pod-ы по требованию nodeAffinity. Если разместить не получится – pod застрянет в статусе Pending
- preferredDuringSchedulingIgnoredDuringExecution: по возможности размещать pod-ы по требованиям affinity. Если поды не влезли – scheduler разместит их "как получится"
- affinityKey – это метка (ключ), по которой мы будем искать ноды для размещения pod-ов.
- affinityValues – это значения метки, которые нам подойдут
- affinityOperator – это тот логический оператор, по которому будет производится выбор метки.
Варианты:
In – подойдет любое из перечисленных значений
NotIn – противоположно In
Exists – метка просто есть (values игнорируется)
DoesNotExists – противоположно Exists
Gt – Greater than – значение метки больше указанного в политике числа. Сработает только для чисел
Lt – Less than – противоположно Gt
Настройка
Маркируем ноды в кластере
Например по типам ЖД
--overwrite - перезаписывает label, если label с таким именем уже имеется
kubectl label nodes kub-node-1 --overwrite disk=ssd
kubectl label nodes kub-node-2 --overwrite disk=hdd
kubectl label nodes kub-node-3 --overwrite disk=streamer
Деплоим приложение, указывая по нодам с какими метками распределять поды (используя "requiredDuringSchedulingIgnoredDuringExecution"):
nano deployment_nodeAffinity.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: enc-httpd-php namespace: enc labels: app: enc-httpd-php spec: replicas: 3 selector: matchLabels: app: enc-httpd-php template: metadata: labels: app: enc-httpd-php spec: containers: - name: enc-httpd-php image: registry.domain123.ru:5000/centos7-apache24-php54:v1.0 ports: - containerPort: 80 imagePullSecrets: - name: registry.domain123.ru.5000 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disk operator: In values: - ssd - hdd
Применяем
kubectl apply -f deployment_nodeAffinity.yaml
Смотрим
kubectl get pods -o wide --all-namespaces
... NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES enc enc-httpd-php-77f449d9dc-2pxn9 1/1 Running 0 11m 172.16.213.165 kub-node-1 <none> <none> enc enc-httpd-php-77f449d9dc-ggfds 1/1 Running 0 11m 172.16.213.76 kub-node-2 <none> <none> enc enc-httpd-php-77f449d9dc-wqnz8 1/1 Running 0 11m 172.16.213.166 kub-node-1 <none> <none> ...
Деплоим приложение, указывая по нодам с какими метками распределять поды (используя "preferredDuringSchedulingIgnoredDuringExecution"):
nano deployment_nodeAffinity.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: enc-httpd-php namespace: enc labels: app: enc-httpd-php spec: replicas: 3 selector: matchLabels: app: enc-httpd-php template: metadata: labels: app: enc-httpd-php spec: containers: - name: enc-httpd-php image: registry.domain123.ru:5000/centos7-apache24-php54:v1.0 ports: - containerPort: 80 imagePullSecrets: - name: registry.domain123.ru.5000 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disk operator: In values: - ssd - streamer
kubectl apply -f deployment_nodeAffinity.yaml
kubectl get pods -o wide --all-namespaces
... NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES enc enc-httpd-php-6f7cb667df-9ct6z 1/1 Running 0 9s 172.16.213.167 kub-node-1 <none> <none> enc enc-httpd-php-6f7cb667df-hf878 1/1 Running 0 9s 172.16.213.202 kub-node-3 <none> <none> enc enc-httpd-php-6f7cb667df-kp6sv 1/1 Running 0 9s 172.16.213.168 kub-node-1 <none> <none> ...