Podʼи вважалися готовими до планування відразу після створення. Планувальник Kubernetes виконує всі необхідні дії для знаходження вузлів для розміщення всіх Podʼів, що очікують. Однак на практиці деякі Podʼи можуть перебувати в стані «бракує необхідних ресурсів» («miss-essential-resources») протягом тривалого періоду. Ці Podʼи фактично створюють непотрібне навантаження на планувальник (і на залежні від нього інтегратори, такі як Cluster AutoScaler).
Шляхом вказання/видалення поля .spec.schedulingGates для Podʼа ви можете контролювати, коли Pod готовий до розгляду для планування.
schedulingGates PodʼаПоле schedulingGates містить список рядків, і кожний рядок сприймається як критерій, який повинен бути задоволений перед тим, як Pod буде вважатися придатним для планування. Це поле можна ініціалізувати лише під час створення Podʼа (клієнтом або шляхом зміни під час допуску). Після створення кожен schedulingGate можна видалити у довільному порядку, але додавання нового шлюзу планування заборонено.
stateDiagram-v2
s1: Pod створено
s2: Очікування планування Podʼа
s3: Pod готовий до планування
s4: Pod виконується
if: шлюзи планування порожні?
[*] --> s1
s1 --> if
s2 --> if: шлюз
планування
видалено
if --> s2: ні
if --> s3: так
s3 --> s4
s4 --> [*]
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
class s1,s2,s3,s4,if k8s
Схема. schedulingGates Podʼа
Щоб позначити Pod як не готовий до планування, ви можете створити його з одним або кількома шлюзами планування так:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
schedulingGates:
- name: example.com/foo
- name: example.com/bar
containers:
- name: pause
image: registry.k8s.io/pause:3.6
Після створення Podʼа ви можете перевірити його стан за допомогою:
kubectl get pod test-pod
Вивід показує, що він перебуває в стані SchedulingGated:
NAME READY STATUS RESTARTS AGE
test-pod 0/1 SchedulingGated 0 7s
Ви також можете перевірити його поле schedulingGates, запустивши:
kubectl get pod test-pod -o jsonpath='{.spec.schedulingGates}'
Вивід:
[{"name":"example.com/foo"},{"name":"example.com/bar"}]
Щоб повідомити планувальнику, що цей Pod готовий до планування, ви можете повністю видалити його schedulingGates шляхом повторного застосування зміненого маніфеста:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.6
Ви можете перевірити, чи очищено schedulingGates, виконавши:
kubectl get pod test-pod -o jsonpath='{.spec.schedulingGates}'
Очікується, що вивід буде порожнім. І ви можете перевірити його останній стан, запустивши:
kubectl get pod test-pod -o wide
Враховуючи те, що test-pod не запитує жодних ресурсів CPU/памʼяті, очікується, що стан цього Podʼа перейде з попереднього SchedulingGated в Running:
NAME READY STATUS RESTARTS AGE IP NODE
test-pod 1/1 Running 0 15s 10.0.0.4 node-2
Метрика scheduler_pending_pods має нову мітку "gated", щоб відрізняти, чи були спроби запланувати Pod, але він був визначений як непридатний для планування, чи він явно позначений як не готовий для планування. Ви можете використовувати scheduler_pending_pods{queue="gated"} для перевірки результату метрики.
Ви можете змінювати директиви планування Podʼа, коли вони мають шлюзи планування, з певними обмеженнями. У загальних рисах, ви можете лише робити директиви планування Podʼа жорсткішими. Іншими словами, оновлені директиви призведуть до можливості розміщення Podʼів тільки на підмножині вузлів, з якими вони раніше мали збіг. Конкретніше, правила для оновлення директив планування Podʼа такі:
Для .spec.nodeSelector дозволяються лише додавання. Якщо відсутнє, його можна встановити.
Для spec.affinity.nodeAffinity, якщо nil, тоді дозволяється встановлення будь-чого.
Якщо NodeSelectorTerms був порожнім, дозволено встановлення. Якщо не порожній, тоді дозволяються лише додавання NodeSelectorRequirements до matchExpressions або fieldExpressions, а зміни наявних matchExpressions і fieldExpressions не будуть дозволені. Це тому, що умови в .requiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms обʼєднуються через OR, тоді як вирази в nodeSelectorTerms[].matchExpressions та nodeSelectorTerms[].fieldExpressions обʼєднуються через AND.
Для .preferredDuringSchedulingIgnoredDuringExecution всі оновлення дозволені. Це повʼязано з тим, що бажані умови не є авторитетними, і тому контролери політики не перевіряють ці умови.