diff --git a/kubernetes/k3s-affinate.md b/kubernetes/k3s-affinate.md new file mode 100644 index 0000000..f0c2cdd --- /dev/null +++ b/kubernetes/k3s-affinate.md @@ -0,0 +1,198 @@ +# Аффинность узлов в 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 \ No newline at end of file diff --git a/raspberry-and-orange-pi/k3s.md b/raspberry-and-orange-pi/k3s.md index f3e6a0f..19c60d7 100644 --- a/raspberry-and-orange-pi/k3s.md +++ b/raspberry-and-orange-pi/k3s.md @@ -41,7 +41,7 @@ sudo /usr/local/bin/k3s-agent-uninstall.sh # На воркере Некоторые требования к узлам: * На всех Orange Pi установлена одинаковая версия Ubuntu (например, 22.04 или 24.04). -* Статические IP-адреса узлов (или зрезервированные под MAC-адреса IP в DHCP). +* Статические IP-адреса узлов (или зарезервированные под MAC-адреса IP в DHCP). * На уздах открыты порты 6443 (для API), 2379-2380 (для etcd) и 10250 (для kubelet). @@ -664,5 +664,63 @@ SSH-тоннель с помощью `autossh` и упаковкой UDP-тра +----- +Cертификаты +sudo kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.1/cert-manager.yaml + +PVC Longhorn +sudo kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.5.3/deploy/longhorn.yaml + +Установить Helm (менеджер пакетов для Kubernetes): + +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + +Добавить репозиторий Traefik в Helm: +helm repo add traefik https://helm.traefik.io/traefik + +Обновить репозитории: +helm repo update + +mkdir ~/.kube/config +sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config + +sudo chown opi:opi ~/.kube +chmod 755 ~/.kube +sudo chown opi:opi ~/.kube/config +chmod 755 ~/.kube/config +sudo chown opi:opi ~/.kube/config/k3s.yaml +chmod 755 ~/.kube/config/k3s.yaml + +или +chmod 755 ~/.kube ~/.kube/config +chmod 755 ~/.kube ~/.kube +chmod 600 ~/.kube/config/k3s.yaml + +ls -ld ~/.kube ~/.kube/config ~/.kube/config/k3s.yaml + +```text +drwxr-xr-x 4 opi opi 4096 Apr 26 11:32 /home/opi/.kube +drwxr-xr-x 2 opi opi 4096 Apr 26 11:09 /home/opi/.kube/config +-rw------- 1 opi opi 2961 Apr 26 11:09 /home/opi/.kube/config/k3s.yaml +``` + +Установить переменную KUBECONFIG: +```bash +export KUBECONFIG=~/.kube/config/k3s.yaml +``` + +И добавь её в `~/.bashrc` для постоянства: +```bash +echo 'export KUBECONFIG=~/.kube/config/k3s.yaml' >> ~/.bashrc +source ~/.bashrc +``` + + +Установить Traefik: +```bash +helm install traefik traefik/traefik -n kube-system --set service.type=LoadBalancer + ``` + +