У меня есть кластер с 3 узлами, работающий на GKE. Все узлы имеют преимущественную силу, что означает, что они могут быть убиты в любое время и, как правило, не живут дольше 24 часов. В случае, если узел убит, автоскалер раскручивает новый узел, чтобы заменить его. Обычно это занимает минуту или около того, когда это происходит.
В моем кластере у меня есть развертывание с его репликами, установленными на 3. Я хочу, чтобы каждый модуль был распределен по всем узлам, так что мое приложение будет по-прежнемуработать до тех пор, пока хотя бы один узел в моем кластере жив.
Я использовал следующую конфигурацию привязки, так что модули предпочитают работать на хостах, отличных от тех, которые уже используют модули для этого развертывания:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- my-app
topologyKey: kubernetes.io/hostname
weight: 100
Когда я масштабирую свое приложение от 0, это, кажется, работает как предназначено. Но на практике происходит следующее:
- Допустим, модули, принадлежащие
my-app
replicaset A
, B
и C
, работают на узлах 1
, 2
и 3
соответственно. Таким образом, состояние будет:
1 -> A
2 -> B
3 -> C
Узел 3 убит, взяв с собой модуль C. В результате этого в репликационном наборе будет 2 запущенных модуля. Планировщик автоматически начнет планировать новый модуль, чтобы довести репликационный набор до 3. Он ищет узел без каких-либо модулей для
my-app
. Так как автоскаляр все еще находится в процессе запуска узла замены (
4
), доступны только
1
и
2
. Он планирует новый модуль
D
на узле
1
Узел
4
в конце концов подключается к сети, но, поскольку у
my-app
запланированы все свои модули, на нем не запущено ни одного модуля. Результирующее состояние
1 -> A, D
2 -> B
4 -> -
Это не идеальная конфигурация. Проблема возникает из-за задержки создания нового узла, а расписание не знает, что оно будет доступно очень скоро.
Существует ли лучшая конфигурация, которая может гарантировать, что модули будут всегда распределены по узлу? Я думал, что директива типа preferredDuringSchedulingpreferredDuringExecution
могла бы сделать это, но ее не существует.