198 lines
17 KiB
Markdown
198 lines
17 KiB
Markdown
# Аффинность узлов в K3s
|
||
|
||
Аффинность узлов (node affinity) в K3s позволяет управлять размещением подов на определённых узлах кластера.
|
||
Это полезно, когда нужно обеспечить запуск приложения на узле с определёнными характеристиками или метками.
|
||
|
||
?Привязка узлов может быть и жесткой и не жесткой.
|
||
|
||
## Под с предпочтительной привязкой к узлу
|
||
|
||
У меня есть [VPN-под на 3x-ui](k3s-3xui-pod.md), и предпочтительно, чтобы он при старте k3s запускался на узле
|
||
c наивысшем приоритетом в keepalive (у меня это хост `opi5plus-1`), но если нода "упадет" и под 3x-ui "переедет"
|
||
на другой узел, то keepalive повысит приоритет т ноды При этом возвращать под на исходный узел после его восстановления не обязательно.
|
||
|
||
(например, opi5plus-1), но мог переезжать на другие узлы (например, opi5plus-2 или opi5plus-3), если что-то пойдёт не так с основным узлом. При этом возвращать под на исходный узел после его восстановления не обязательно.
|
||
|
||
Ответ: Да, это возможно! В Kubernetes для этого используется механизм node affinity (аффинность к узлам). Он позволяет указать "мягкое" предпочтение для запуска пода на определённом узле, но не запрещает поду перемещаться, если нужного узла нет.
|
||
|
||
Как настроить node affinity
|
||
Допустим, ты хочешь, чтобы под запускался на opi5plus-1 по умолчанию, но мог переехать на другие узлы при необходимости.
|
||
|
||
Шаги:
|
||
|
||
Проверь или добавь метки узлам: Убедись, что твои узлы имеют метки (labels). Например:
|
||
bash
|
||
|
||
Collapse
|
||
|
||
Wrap
|
||
|
||
Copy
|
||
kubectl label nodes opi5plus-1 preferred=true
|
||
kubectl label nodes opi5plus-2 preferred=false
|
||
kubectl label nodes opi5plus-3 preferred=false
|
||
Здесь preferred=true — это метка, которая указывает предпочтительный узел.
|
||
Обнови манифест деплоя 3x-ui: Добавь секцию affinity в спецификацию пода. Пример:
|
||
yaml
|
||
|
||
Collapse
|
||
|
||
Wrap
|
||
|
||
Copy
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: x-ui
|
||
namespace: x-ui
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: x-ui
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: x-ui
|
||
spec:
|
||
affinity:
|
||
nodeAffinity:
|
||
preferredDuringSchedulingIgnoredDuringExecution:
|
||
- weight: 1
|
||
preference:
|
||
matchExpressions:
|
||
- key: preferred
|
||
operator: In
|
||
values:
|
||
- "true"
|
||
containers:
|
||
- name: x-ui
|
||
image: ghcr.io/mhsanaei/3x-ui:latest
|
||
# Остальные настройки контейнера...
|
||
Что здесь происходит:
|
||
|
||
preferredDuringSchedulingIgnoredDuringExecution — это "мягкое" правило. Kubernetes постарается запустить под на узле с меткой preferred=true, но если это невозможно (например, узел недоступен), под запустится на любом другом доступном узле.
|
||
weight: 1 — вес предпочтения. Если у тебя будет несколько правил, можно задавать приоритеты, но для одного правила это не так важно.
|
||
Как это работает:
|
||
|
||
Если узел opi5plus-1 доступен, под запустится там.
|
||
Если opi5plus-1 упадёт, под автоматически переедет на другой узел (например, opi5plus-2).
|
||
После восстановления opi5plus-1 под останется на текущем узле и не вернётся автоматически, что соответствует твоему запросу.
|
||
Как это сочетается с Keepalived?
|
||
Твой скрипт проверки в Keepalived гарантирует, что виртуальный IP будет следовать за подом 3x-ui. Если ты задашь opi5plus-1 как предпочтительный узел через affinity и дашь ему высокий приоритет в Keepalived (например, 100), то в нормальной ситуации под и IP будут на одном узле. А если под переедет из-за сбоя, Keepalived переключит IP на новый узел благодаря скрипту.
|
||
|
||
Итог
|
||
Скрипт проверки: sudo не нужен, так как Keepalived запускает скрипт от root. Если будут проблемы с доступом, добавь --kubeconfig с путём к файлу конфигурации.
|
||
Приоритет узла для пода: Используй node affinity с "мягким" предпочтением (preferredDuringSchedulingIgnoredDuringExecution). Это позволит поду запускаться на нужном узле, но свободно перемещаться при сбоях без обязательного возвращения.
|
||
Твоя идея с приоритетами и "кочеванием" пода отлично реализуема, и связка Keepalived + affinity обеспечит гибкость и надёжность. Удачи с настройкой, если что — пиши! 😊
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
Отлично. Ты мне отлично помог и 3x-ui заработал на VIP. Все сработало как ты сказал. Объясни пожалуйста про метки:
|
||
```
|
||
kubectl label nodes opi5plus-1 preferred=true
|
||
kubectl label nodes opi5plus-2 preferred=false
|
||
kubectl label nodes opi5plus-3 preferred=false
|
||
```
|
||
это означает, что все поды будут предпочитать opi5plus-1 или это касается только подов с nodeAffinity?
|
||
|
||
|
||
|
||
3 / 3
|
||
|
||
|
||
|
||
Completed
|
||
42s
|
||
Thinking
|
||
Исследую использование меток
|
||
|
||
|
||
Thinking
|
||
Исследую использование меток
|
||
Пользователь интересуется метками в K3s и их применением для привязки узлов. Они пометили один узел как "preferred=true", а другие как "preferred=false".
|
||
Метки в K3s — это пары ключ-значение, прикрепленные к объектам, таким как узлы, поды, сервисы. Они помогают организовать и выбрать подмножества объектов.
|
||
Привязка узлов позволяет указать, на каких узлах должен размещаться под. Есть два типа: обязательная и предпочтительная.
|
||
Метка "preferred=true" влияет только на поды с привязкой узлов, ищущими эту метку. Поды без таких правил размещаются без учета этой метки.
|
||
Все три узла имеют метку "preferred", но с разными значениями: opi5plus-1 — true, opi5plus-2 и opi5plus-3 — false.
|
||
Если под не имеет привязки узлов, планировщик размещает его на любом узле с нужными ресурсами, игнорируя метку "preferred".
|
||
Под без nodeSelector или nodeAffinity размещается на любом узле с необходимыми ресурсами. Метка "preferred" важна только для подов, ссылающихся на нее.
|
||
В K8s, метка "preferred=false" добавляет метку "preferred" со значением "false" на узел. Если метки нет, узел ее не имеет.
|
||
Под с предпочтительной привязкой сначала пытается разместиться на opi5plus-1, где preferred=true. Если не получится, может быть размещен на opi5plus-2 или opi5plus-3.
|
||
Метка "preferred=true" влияет только на поды с правилами, ищущими эту метку. Другие поды размещаются по другим критериям.
|
||
В стандартном K3s нет поведения, которое по умолчанию использует метки, такие как "preferred", для влияния на планирование. Метка важна только для подов, явно ссылающихся на нее в правилах привязки.
|
||
Другие поды, без ссылок на эту метку, будут размещены без учета "preferred", основываясь на доступности ресурсов.
|
||
Пример: под без привязки узлов размещается на любом узле, игнорируя метку "preferred". Это подтверждает, что метка влияет только на поды с соответствующими правилами.
|
||
Если под указывает nodeSelector с preferred="false", он размещается только на узлах, где preferred=false, например, opi5plus-2 или opi5plus-3.
|
||
Метка "preferred" влияет только на поды с правилами привязки или селектора, ссылающимися на эту метку. Поды без таких правил не затрагиваются.
|
||
Метка "preferred" важна только для подов, таких как 3x-ui, с установленной предпочтительной привязкой. Другие поды в кластере размещаются по своим спецификациям, если нет похожих правил.
|
||
Метки на узлах важны только тогда, когда правила планирования пода ссылаются на них. Например, под может исключать узлы, где preferred=true, если указано соответствующее правило.
|
||
Прямой ответ
|
||
Метки, такие как preferred=true или preferred=false, влияют только на поды с указанной аффинностью узлов, которые ссылаются на эту метку.
|
||
Другие поды, без аффинности, размещаются без учёта этих меток, основываясь на доступных ресурсах.
|
||
Влияние на поды
|
||
Метки на узлах, вроде preferred, не имеют значения для подов, если те не имеют правил аффинности, ссылающихся на эту метку. Например, под с аффинностью, предпочитающей preferred=true, будет стараться запускаться на opi5plus-1, но может переместиться на другие узлы, если opi5plus-1 недоступен.
|
||
|
||
Неожиданный нюанс
|
||
Интересно, что метки могут использоваться в других правилах, например, для исключения узлов (NotIn), но это требует явного указания в спецификации пода, что выходит за рамки стандартного поведения.
|
||
|
||
Отчёт
|
||
Введение
|
||
Метки (labels) в K3s — это ключевые пары, прикрепляемые к объектам, таким как узлы, поды и сервисы, для организации и выбора подмножества объектов. В контексте планирования подов метки на узлах используются для влияния на их размещение через механизмы, такие как аффинность узлов (node affinity). Пользователь задал вопрос о влиянии меток preferred=true и preferred=false, установленных на узлы, на все поды или только на те, у которых указана аффинность узлов.
|
||
|
||
Анализ влияния меток
|
||
Метки на узлах, такие как preferred=true или preferred=false, добавляются через команды вроде kubectl label nodes opi5plus-1 preferred=true. Эти метки сами по себе не имеют встроенного значения для планировщика K3s, если поды не ссылаются на них в своих правилах размещения.
|
||
|
||
В K3s, основанном на Kubernetes, планировщик подов (scheduler) размещает поды на узлах, учитывая доступные ресурсы (CPU, память) и любые ограничения, указанные в спецификации пода. Метки становятся значимыми только тогда, когда под использует их в правилах nodeSelector, nodeAffinity или nodeAntiAffinity.
|
||
|
||
Пользователь настроил метки следующим образом:
|
||
|
||
opi5plus-1: preferred=true
|
||
opi5plus-2: preferred=false
|
||
opi5plus-3: preferred=false
|
||
И в манифесте пода 3x-ui указал аффинность:
|
||
|
||
yaml
|
||
|
||
Collapse
|
||
|
||
Wrap
|
||
|
||
Copy
|
||
spec:
|
||
affinity:
|
||
nodeAffinity:
|
||
preferredDuringSchedulingIgnoredDuringExecution:
|
||
- weight: 1
|
||
preference:
|
||
matchExpressions:
|
||
- key: preferred
|
||
operator: In
|
||
values:
|
||
- "true"
|
||
Это означает, что под предпочтительно будет размещён на узле с меткой preferred=true, то есть на opi5plus-1. Если такой узел недоступен, под может быть размещён на opi5plus-2 или opi5plus-3, где preferred=false.
|
||
|
||
Влияние на поды без аффинности
|
||
Поды, у которых не указаны nodeSelector, nodeAffinity или nodeAntiAffinity, размещаются планировщиком K3s без учёта метки preferred. Планировщик выбирает узел на основе:
|
||
|
||
Доступных ресурсов.
|
||
Отсутствия конфликтов (например, taints).
|
||
Других факторов, таких как анти-аффинность подов или балансировка нагрузки.
|
||
Таким образом, метки preferred=true и preferred=false не влияют на поды, у которых нет правил, ссылающихся на эту метку. Например, поды Shadowsocks, если они не имеют аффинности, будут размещаться на любом узле без учёта preferred.
|
||
|
||
Пример с таблицей
|
||
Вот таблица, которая иллюстрирует влияние меток на поды:
|
||
|
||
Под Имеет аффинность к preferred? Узел предпочтения Возможные узлы при сбое
|
||
3x-ui Да, preferred=true opi5plus-1 opi5plus-2, opi5plus-3
|
||
Shadowsocks (без аффинности) Нет Любой доступный узел Любой доступный узел
|
||
Заключение
|
||
Метки preferred влияют только на поды с аффинностью, ссылающейся на эту метку, и не затрагивают остальные поды. Это позволяет гибко управлять размещением, сохраняя свободу для других приложений.
|
||
|
||
Ключевые цитаты
|
||
Kubernetes Node Affinity and Anti-Affinity https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
|
||
K3s Documentation on Node Labels https://grok.com/chat/6a083b91-ea05-4246-9407-b9b25af4b48f#:~:text=K3s%20Documentation%20on%20Node%20Labels |