1 - Распределение подов по узлам
Можно настроить под так, чтобы тот мог запускаться только на определенном(-ых) узле(-ах) или предпочитал определенную группу узлов.
Сделать это можно несколькими способами, при этом все рекомендуемые подходы используют селекторы лейблов для выбора.
Зачастую нужды в подобных ограничениях нет; планировщик автоматически размещает поды оптимальным образом (например, распределяет их по узлам, чтобы они не оказались все на одном узле с дефицитом ресурсов).
Однако в некоторых обстоятельствах возможность контролировать, куда именно попадет под, может пригодиться. Например, она поможет запланировать под на узел с быстрым SSD-хранилищем или разместить два активно взаимодействующих друг с другом пода в одной зоне доступности.
Для планирования подов на определенные узлы можно использовать любой из методов:
Лейблы узлов
Как и у многих других объектов Kubernetes, у узлов есть лейблы. Их можно навешивать вручную.
Kubernetes также навешивает стандартный набор лейблов на все узлы кластера.
Примечание:
Значения этих лейблов зависят от облачного провайдера, поэтому на них нельзя полагаться.
Например, в одних окружениях значение kubernetes.io/hostname
может совпадать с именем узла, в других — отличаться.
Изоляция узла/ограничение его использования
Лейблы узлов позволяют размещать поды на определенные узлы или группы узлов. С их помощью можно планировать поды на узлы с определенными требованиями к изоляции, безопасности или соответствию нормативным положениям.
При использовании лейблов для изоляции узлов следует выбирать ключи лейблов, которые kubelet не может изменить. В этом случае взломанный узел не сможет навесить на себя эти лейблы в надежде, что планировщик разместит на него рабочие нагрузки.
Admission-плагин NodeRestriction не позволяет kubelet'у устанавливать или изменять лейблы с префиксом node-restriction.kubernetes.io/
.
Чтобы использовать этот префикс для изоляции узла:
- Убедитесь, что используется авторизатор узлов и включен admission-плагин
NodeRestriction
.
- Добавьте лейблы с префиксом
node-restriction.kubernetes.io/
к узлам и используйте их в селекторах узлов. Например, example.com.node-restriction.kubernetes.io/fips=true
или example.com.node-restriction.kubernetes.io/pci-dss=true
.
nodeSelector
nodeSelector
— простейшая рекомендуемая форма настроек выбора узлов.
Можно добавить поле nodeSelector
в спецификацию пода и перечислить в нем лейблы узлов, которые подходят для развертывания пода. В этом случае Kubernetes будет планировать под только на узлы со всеми указанными лейблами.
Дополнительную информацию см. в разделе Размещение подов на узлах.
Правила совместного/раздельного существования (affinity и anti-affinity)
nodeSelector
— самый простой способ развернуть поды на узлах с определенными лейблами. Правила совместного/раздельного существования расширяют типы ограничений, которые можно накладывать. Вот некоторые из их преимуществ:
- Язык правил affinity/anti-affinity более выразителен.
nodeSelector
выбирает узлы только со всеми указанными лейблами. Правила affinity/anti-affinity расширяют логику выбора и делают ее более гибкой.
- Правило может быть мягким (soft) или предпочтительным (preferred). В этом случае планировщик все равно запланирует под, даже если подходящего узла для него не найдется.
- При планировании пода планировщик может учитывать лейблы других подов, запущенных на узле (или в иной топологической области), а не только лейблы самого узла. Это позволяет формулировать правила, определяющие сосуществование подов на узле.
Правила совместного существования (affinity) бывают двух типов:
- Правила для узлов (node affinity) работают подобно полю
nodeSelector
, но более выразительны. Кроме того, можно задавать мягкие правила.
- Правила для подов (inter-pod affinity и anti-affinity) позволяют при планировании учитывать лейблы других подов.
Правила совместного существования для узлов (node affinity)
Правила совместного существования для узлов концептуально похожи на nodeSelector
. С помощью лейблов они позволяют ограничивать список узлов, на которые может быть запланирован под. Существует два типа таких правил:
requiredDuringSchedulingIgnoredDuringExecution
: Планировщик не может запланировать под, если правило не выполнено. Работает как nodeSelector
, но с более выразительным синтаксисом.
preferredDuringSchedulingIgnoredDuringExecution
: Планировщик пытается найти узел, который соответствует правилу. Если подходящий узел не удается найти, планировщик все равно планирует под.
Примечание:
В типах выше IgnoredDuringExecution
означает, что под продолжит свою работу, если лейблы узлов изменятся после того, как Kubernetes запланировал его.
Задавать правила совместного существования для узлов можно с помощью поля .spec.affinity.nodeAffinity
в спецификации пода.
В качестве примера рассмотрим следующую спецификацию пода:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- antarctica-east1
- antarctica-west1
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: registry.k8s.io/pause:2.0
В этом примере применяются следующие правила:
- У узла должен быть лейбл с ключом
topology.kubernetes.io/zone
, и значение этого лейбла должно быть либо antarctica-east1
, либо antarctica-west1
.
- Предпочтительно, чтобы у узла был лейбл с ключом
another-node-label-key
и значением another-node-label-value
.
Можно использовать поле operator
для указания логического оператора, который Kubernetes будет применять при интерпретации правил. Доступны In
, NotIn
, Exists
, DoesNotExist
, Gt
и Lt
.
Узнать больше о том, как они работают, можно в подразделе Операторы.
NotIn
и DoesNotExist
позволяют задавать правила раздельного существования (anti-affinity) для узла.
Кроме того, можно использовать taint'ы узлов, чтобы "отвадить" поды от определенных узлов.
Примечание:
Когда указаны и nodeSelector
, и nodeAffinity
, под будет запланирован на узел только в том случае, если оба этих условия удовлетворены.
Если указать несколько условий nodeSelectorTerms
, привязанных к типам nodeAffinity
, то под может быть запланирован на узел, если удовлетворяется одно из указанных условий nodeSelectorTerms
. К условиям применяется логическое ИЛИ.
Если задать несколько выражений в поле matchExpressions
для одного условия nodeSelectorTerms
, под будет запланирован на узел только если удовлетворены все выражения matchExpressions
. К условиям применяется логическое И.
Дополнительную информацию см. в разделе Размещаем поды на узлы с помощью Node Affinity.
Вес правил совместного существования
Для каждого правила типа preferredDuringSchedulingIgnoredDuringExecution
можно указать вес weight
в диапазоне от 1 до 100. Найдя несколько узлов, удовлетворяющих всем остальным требованиям для планирования пода, планировщик перебирает предпочтительные правила, которым удовлетворяет узел, и суммирует их веса.
Итоговая сумма добавляется к оценке, полученной при анализе других параметров, влияющих на приоритет узла. Принимая решение о размещении пода, планировщик отдает предпочтение узлам с наибольшей суммарной оценкой.
В качестве примера рассмотрим следующую спецификацию пода:
apiVersion: v1
kind: Pod
metadata:
name: with-affinity-anti-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: label-1
operator: In
values:
- key-1
- weight: 50
preference:
matchExpressions:
- key: label-2
operator: In
values:
- key-2
containers:
- name: with-node-affinity
image: registry.k8s.io/pause:2.0
Если правилу preferredDuringSchedulingIgnoredDuringExecution
соответствуют два узла (один — с лейблом label-1:key-1
, другой — с label-2:key-2
), планировщик считает вес weight
каждого узла и добавляет его к другим оценкам для этого узла. Под планируется на узел с наивысшей итоговой оценкой.
Примечание:
Чтобы Kubernetes смог запланировать поды в этом примере, необходимо, чтобы существовали узлы с лейблом kubernetes.io/os=linux
.
Правила совместного существования и профили планирования
СТАТУС ФИЧИ:
Kubernetes v1.20 [beta]
При настройке нескольких профилей планирования можно связать профиль с правилами совместного существования для узлов (это удобно, когда профиль применяется к определенному набору узлов). Для этого необходимо добавить addedAffinity
в поле args
плагина NodeAffinity
в конфигурации планировщика. Например:
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
- schedulerName: foo-scheduler
pluginConfig:
- name: NodeAffinity
args:
addedAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: scheduler-profile
operator: In
values:
- foo
Правило addedAffinity
применяется ко всем подам с полем .spec.schedulerName
, имеющим значение foo-scheduler
, в дополнение к NodeAffinity, заданному в PodSpec. Таким образом, подходящие для пода узлы должны удовлетворять параметрам addedAffinity
и правилам .spec.NodeAffinity
пода.
Поскольку конечные пользователи не видят addedAffinity
, результат применения этих правил может быть для них неожиданным. Используйте лейблы узлов, которые однозначно соотносятся с именем профиля планировщика.
Примечание:
Контроллер DaemonSet,
создающий поды для DaemonSet'ов, не поддерживает профили планирования. Контроллер DaemonSet создает поды, а штатный планировщик Kubernetes, размещая их, следит за соблюдением правил
nodeAffinity
.
Правила совместного/раздельного существования подов
Правила совместного/раздельного существования подов позволяют выбирать узлы для планирования в зависимости от лейблов подов, которые уже на этих узлах работают (вместо лейблов самих узлов).
Алгоритм работы правил совместного/раздельного существования подов можно описать так: "данный под должен (или не должен в случае раздельного (anti-affinity) существования) размещаться на X, если на нем уже работает один или несколько подов, удовлетворяющих правилу Y", где X — топологический домен, например, узел, стойка, зона/регион облачного провайдера и т. п., а Y — правило, которое Kubernetes пытается удовлетворить.
Для задания правил Y используются селекторы лейблов с необязательным связанным списком пространств имен. Для подов в Kubernetes указываются пространства имен, соответственно, их лейблы также оказываются неявно связаны с этими же пространствами имен. Любые селекторы лейблов для лейблов подов должны содержать пространства имен, в которых Kubernetes должен искать эти лейблы.
Топологический домен X задается с помощью topologyKey
— ключа для лейбла узла, который система использует для обозначения домена. Примеры см. в разделе Типичные лейблы, аннотации и taint'ы.
Примечание:
Обработка правил совместного/раздельного существования подов требует значительных ресурсов и может значительно замедлить планирование в больших кластерах. Их не рекомендуется использовать в кластерах, число узлов в которых превышает несколько сотен.
Примечание:
Правила раздельного существования для подов требуют согласованности лейблов узлов. Другими словами, у каждого узла в кластере должен быть лейбл, относящий его к определенному ключу topologyKey
. Отсутствие лейблов topologyKey
у некоторых или всех узлов в кластере может привести к непредсказуемому поведению.
Типы правил совместного/раздельного существования подов
По аналогии c правилами для узлов существует два типа правил для подов:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
Например, с помощью правила совместного существования requiredDuringSchedulingIgnoredDuringExecution
можно заставить планировщик размещать поды, относящиеся к разным сервисам, в одной зоне облачного провайдера, поскольку они активно обмениваются данными друг с другом.
Аналогичным образом можно использовать правило раздельного существования preferredDuringSchedulingIgnoredDuringExecution
для распределения подов по нескольким зонам облачного провайдера.
Для задания правил совместного существования предназначено поле affinity.podAffinity
в спецификации пода.
Для задания правил раздельного существования предназначено поле affinity.podAntiAffinity
в спецификации пода.
Планирование группы подов, связанных правилами совместного существования
Если планируемый под — первый в серии подов, связанных правилами совместного существования,
он может быть запланирован, если удовлетворит всем остальным правилам совместного существования. Чтобы подтвердить, что этот под — действительно первый,
проводится проверка, которая должна показать, что пространство имен и селектор этого пода уникальны в кластере (то есть нет других таких подов). Кроме того,
под должен соответствовать своим собственным правилам, а выбранный узел — всем запрошенным топологиям.
Это предотвращает тупиковую ситуацию, когда поды не могут запланироваться из-за того, что все они связаны правилами совместного существования.
Пример правил совместного/раздельного существования для пода
Рассмотрим следующую спецификацию пода:
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: topology.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: topology.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: registry.k8s.io/pause:2.0
В примере задается одно правило совместного существования подов, и одно — раздельного. Для совместного правила используется жесткий тип requiredDuringSchedulingIgnoredDuringExecution
, для раздельного — мягкий preferredDuringSchedulingIgnoredDuringExecution
.
Правило совместного существования гласит, что планировщик может разместить под на узел, только если тот находится в зоне с одним или более подами с лейблом security=S1
.
Например, если есть кластер с выделенной зоной, назовем ее "V",
состоящей из узлов с лейблом topology.kubernetes.io/zone=V
, планировщик может
назначить под на любой узел зоны V только если в этой зоне уже есть хотя бы один под
с лейблом security=S1
. И наоборот, если в зоне V нет подов с лейблом security=S1
,
планировщик не сможет назначить под на какой-либо из узлов в этой зоне.
Правило раздельного существования гласит, что планировщик при возможности не должен размещать под на узел, если тот находится в зоне с одним или более подами с лейблом security=S2
.
Например, если есть кластер с выделенной зоной, назовем ее "R",
состоящей из узлов с лейблами topology.kubernetes.io/zone=R
. Планировщик должен избегать
назначать поды на узлы из зоны R, если в ней уже есть по крайней мере один под
с лейблом security=S2
. Соответственно, если в зоне R нет подов с лейблами security=S2
,
правило раздельного существования не будет влиять на планирование подов в эту зону.
Больше примеров правил совместного/раздельного существования для подов можно найти в рабочей документации.
Поле operator
пода поддерживает значения In
, NotIn
, Exists
и DoesNotExist
при задании правил совместного/раздельного существования.
Узнать больше о том, как они работают, можно в подразделе Операторы.
В принципе, topologyKey
может быть любым разрешенным лейблом-ключом со следующими исключениями по соображениям производительности и безопасности:
- При задании правил совместного/раздельного существования для подов пустое поле
topologyKey
не допускается как для requiredDuringSchedulingIgnoredDuringExecution
, так и для preferredDuringSchedulingIgnoredDuringExecution
.
- Для правил раздельного существования типа
requiredDuringSchedulingIgnoredDuringExecution
admission-контроллер разрешает использовать только kubernetes.io/hostname
в качестве topologyKey
. Для работы с кастомными топологиями admission-контроллер можно дополнить или совсем отключить его.
В дополнение к labelSelector
и topologyKey
можно опционально указать список пространств имен, которые должен выбирать labelSelector
, с помощью поля namespaces
на том же уровне, что labelSelector
и topologyKey
. Если поле namespaces
опущено или пусто, по умолчанию выбирается пространство имен пода, в котором задаются правила совместного/раздельного существования.
Селектор пространств имен
СТАТУС ФИЧИ:
Kubernetes v1.24 [stable]
Подходящие пространства имен также можно выбрать с помощью namespaceSelector
, который попытается найти лейбл в наборе пространств имен.
Условия совместного существования применяются к пространствам имен, выбранным как селектором namespaceSelector
, так и полем namespaces
.
Обратите внимание, что пустой селектор namespaceSelector
({}) выбирает все пространства имен, в то время как пустой или null-список namespaces
и null-селектор namespaceSelector
выбирает пространство имен пода, в котором правило задано.
matchLabelKeys
СТАТУС ФИЧИ:
Kubernetes v1.31 [beta]
(enabled by default: true)
Примечание:
Поле matchLabelKeys
является полем альфа-уровня и по умолчанию отключено в
Kubernetes 1.32.
Включить его можно с помощью переключателя функциональности
(feature gate) MatchLabelKeysInPodAffinity
.
Kubernetes включает необязательное поле matchLabelKeys
для правил совместного (раздельного) существования подов.
В нем указываются ключи для лейблов, которые должны совпадать с лейблами входящего пода,
чтобы правила совместного (раздельного) существования выполнялись.
Ключи используются для поиска значений в лейблах подов; эти ключи-лейблы объединяются (с помощью AND
)
с ограничениями, задаваемыми с помощью поля labelSelector
. Такая комбинированная фильтрация позволяет отобрать
набор существующих подов, которые приниматься в расчет при обработке правил совместного (раздельного) существования.
Обычно matchLabelKeys
используется вместе с pod-template-hash
(задается для подов,
которые управляются как часть деплоймента, где значение уникально для каждой ревизии).
Использование pod-template-hash
в matchLabelKeys
позволяет нацеливаться на поды, принадлежащие
к той же ревизии, что и входящий под. Таким образом, что скользящее обновление не нарушит правила совместного существования.
apiVersion: apps/v1
kind: Deployment
metadata:
name: application-server
...
spec:
template:
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- database
topologyKey: topology.kubernetes.io/zone
# При расчете affinity подов учитываются только поды из определенного выката.
# При обновлении Deployment'а новые поды будут следовать своим собственным правилам совместного существования
# (если они заданы в новом шаблоне подов)
matchLabelKeys:
- pod-template-hash
mismatchLabelKeys
СТАТУС ФИЧИ:
Kubernetes v1.31 [beta]
(enabled by default: true)
Примечание:
Поле mismatchLabelKeys
является полем альфа-уровня и по умолчанию отключено в
Kubernetes 1.32.
Включить его можно с помощью переключателя функциональности
(feature gate) MatchLabelKeysInPodAffinity
.
Kubernetes включает необязательное поле mismatchLabelKeys
для определения правил совместного (раздельного) существования подов.
В поле указываются ключи для лейблов, которые не должны совпадать с лейблами входящего пода,
чтобы правила совместного (раздельного) существования подов удовлетворялись.
Один из примеров использования — размещение подов определенной группы пользователей (tenant'ов) или команды в конкретном топологическом домене (узле, зоне и т. д.).
То есть идея в том, чтобы избежать одновременного запуска подов от разных групп пользователей в одном топологическом домене.
apiVersion: v1
kind: Pod
metadata:
labels:
# Assume that all relevant Pods have a "tenant" label set
tenant: tenant-a
...
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
# следим за тем, чтобы поды, связанные с этим тенантом, попадали на нужный пул узлов
- matchLabelKeys:
- tenant
topologyKey: node-pool
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
# следим за тем, чтобы поды, связанные с этим тенантом, не смогли планироваться на узлы для другого тенанта
- mismatchLabelKeys:
- tenant # значение лейбла "tenant" этого пода будет предотвращать
# планирование на узлы в пулах, на которых работают поды
# другого тенанта
labelSelector:
# Должен быть labelSelector, который выбирает поды с лейблом tenant,
# иначе этот под также будет "ненавидеть" поды из daemonset'ов, например,
# те, у которых нет лейбла tenant.
matchExpressions:
- key: tenant
operator: Exists
topologyKey: node-pool
Другие примеры использования
Правила совместного/раздельного существования для подов особенно удобны, когда используются совместно с абстракциями более высокого уровня, такими как ReplicaSet, StatefulSet, Deployment и т. д. Эти правила позволяют настроить размещение рабочих нагрузок с учетом имеющейся топологии; например, пара связанных подов будет планироваться на один и тот же узел.
Представьте кластер, состоящий из трех узлов. Он используется для запуска веб-приложения и как in-memory-кэш (например, Redis). Предположим, что задержка между веб-приложением и кэшем должна быть минимальной. Правила совместного/раздельного существования для подов позволяют настроить планировщик так, чтобы тот размещал веб-серверы как можно ближе к кэшу.
В приведенном ниже примере конфигурации деплоймента с Redis его реплики получают лейбл app=store
. Правило podAntiAffinity
запрещает планировщику размещать несколько реплик с лейблом app=store
на одном узле. В результате каждый узел получает по отдельной кэш-реплике.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine
Конфигурация деплоймента, приведенная ниже, создает три реплики веб-сервера с лейблом app=web-store
.
Правило совместного существования предписывает планировщику размещать каждую реплику на узле, на котором уже имеется под с лейблом app=store
. В то же время правило раздельного существования запрещает планировщику размещать несколько серверов с лейблом app=web-store
на одном узле.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: nginx:1.16-alpine
Развертывание ресурсов в соответствии с приведенными выше конфигурациями приведет к созданию кластера, в котором на каждом узле будет по одному веб-серверу и одной реплике Redis (всего три отдельных узла):
узел 1 |
узел 2 |
узел 3 |
webserver-1 |
webserver-2 |
webserver-3 |
cache-1 |
cache-2 |
cache-3 |
В итоге к каждому инстансу Redis'а, скорее всего, будет обращаться клиент, который работает с ним на том же узле. Подобный подход позволит минимизировать как перекос (дисбаланс нагрузки), так и задержки.
Правила совместного/раздельного существования для подов можно использовать и в других случаях.
См., например, руководство по ZooKeeper. В нем с помощью правил раздельного существования StatefulSet настраивается так, чтобы обеспечить высокую доступность (используется подход, аналогичный тому, что применен выше).
nodeName
Поле nodeName
в спецификации пода — более непосредственный способ выбора узлов по сравнению с правилами совместного существования или селектором nodeSelector
. Если поле nodeName
не пустое, планировщик игнорирует под, а kubelet на узле с соответствующим именем пытается разместить под на этом узле. Приоритет поля nodeName
выше, чем селектора nodeSelector
или правил совместного/раздельного существования.
Однако у nodeName
имеются и некоторые недостатки:
- Если узел с заданным именем не существует, под не будет запущен. Кроме того, в некоторых случаях он может быть автоматически удален.
- Если на узле с заданным именем недостаточно ресурсов для работы пода, последний будет остановлен; соответствующая причина (например, OutOfmemory или OutOfcpu) будет указана.
- В облачных окружениях имена узлов не всегда предсказуемы или стабильны.
Примечание:
Поле
nodeName
предназначено для использования в кастомных планировщиках или в продвинутых случаях,
когда необходимо обойти настроенные планировщики. Обход планировщиков может привести к тому, что поды не будут запущены,
если целевые узлы окажутся перегруженными. С помощью правила
совместного существования (affinity) узла или поля
nodeselector
под можно назначить на определенный узел, не обходя планировщики с помощью
nodeName
.
Ниже приведен пример спецификации пода с полем nodeName
:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: kube-01
Такой под будет работать только на узле с именем kube-01
.
Ограничения на топологию распределения подов
С помощью ограничений на топологию распределения (topology spread constraints) можно настроить размещение подов в кластере по failure-доменам, таким как регионы, зоны, узлы, или любым другим заданным топологическим конфигурациям. Это позволяет повысить производительность, ожидаемую доступность или эффективность использования ресурсов.
Дополнительные сведения о принципах их работы читайте в разделе Ограничения на топологию распределения подов.
Операторы
Ниже приведены все логические операторы, которые можно использовать в поле operator
для nodeAffinity
и podAffinity
.
Оператор |
Действие |
In |
Значение лейбла присутствует в предоставленном наборе строк |
NotIn |
Значение лейбла отсутствует в предоставленном наборе строк |
Exists |
Лейбл с таким ключом существует для объекта |
DoesNotExist |
У объекта не существует лейбла с таким ключом |
Следующие операторы могут использоваться только с nodeAffinity
.
Оператор |
Действие |
Gt |
Введенное значение будет обработано как целое число, и это целое число меньше, чем целое число, полученное в результате обработки значения лейбла, указанного этим селектором |
Lt |
Введенное значение будет обработано как целое число, и это целое число больше, чем целое число, полученное в результате обработки значения лейбла, указанного этим селектором |
Примечание:
Операторы Gt
и Lt
не работают с нецелыми значениями. Если заданное значение
не является целым числом, под не будет запланирован. Кроме того, Gt
и Lt
недоступны для podAffinity
.
Что дальше