Skip to content

Кластеры Kubernetes ​

Экспериментальная возможность

Кластеры на нескольких хостах, WireGuard между хостами и Cilium обкатаны на тестовых стендах. Перед настоящим созданием — «сухой прогон», после — журнал задания.

Хаб собирает кластер из машин на хостах с виртуализацией (и, если нужно, из самих хостов): создаёт машины из облачного образа, ставит в них nkt, а nkt на каждом узле выполняет шаги установки k3s или kubeadm. Узлы — обычные машины хаба под своим хостом; kubeconfig лежит в карточке кластера.

Кластер на одном хосте ​

«Новый кластер» у хоста с виртуализацией: вариант (k3s или kubeadm), версия Kubernetes (актуальная stable по умолчанию и три предыдущие ветки), топология — одна машина / 1 control plane + N worker / 3 control plane + N worker, размеры машин, образ, сеть, проброс портов с хоста (API 6443 и порты приложений) и Cilium по галочке (с заменой kube-proxy). Внутри узла порт API всегда 6443; порт в «пробросить наружу» относится к хосту.

Раздел «Кластеры»: несколько хостов ​

Диалог «Новый кластер на нескольких хостах» — таблица размещения: хост → роль → машины (сколько, размеры, образ, мост) или сам хост как узел. Образ выбирается из каталога хоста («будет скачан», если его ещё нет) или из библиотеки хаба (см. ниже); форма сама сообщает о неверном числе control plane, о трёх control plane с kubeadm и о пропущенном мосте.

Сеть между хостами — как узлы на разных хостах видят друг друга:

РежимКогдаЧто нужно
NATвсе узлы на одном хостеничего: сеть libvirt хоста
Мостхосты в одном L2-сегментемост на каждом хосте с машинами; адреса машин — из сети хостов
WireGuardхосты в разных сетяхUDP 51820 между хостами: хаб генерирует ключи, ставит wireguard-tools, поднимает wg-quick@nktwg<N> и отдельную сеть машин на каждом хосте; подсети соседей идут через туннель

WireGuard работает, когда хосты видят друг друга по адресу (LAN, VPN, белые IP — тогда откройте UDP 51820 во внешнем файрволе). Если хаб ходит на хост по адресу, которого соседи не видят, задайте на хост «адрес для соседей». Хосты, чьи сети не видят друг друга вовсе, туннель сейчас не свяжет — обход через хаб в планах (TODO). Трафик узлов через хаб не идёт никогда — хаб только раздаёт ключи и конфиги.

Сухой прогон проходит проверки по каждому хосту — KVM и libvirtd, память и ядра, порты, нужные пакеты, образ, мост или адрес для WireGuard, ping между хостами, доступность ссылок — и пишет чек-лист (✓ / ! / ✗) в журнал поверх формы: настройки остаются на месте, их можно поправить и запустить создание. С галочкой «заодно подготовить» хаб сразу скачивает образы и пакеты в кэш и поднимает сеть libvirt.

Что ещё умеет раздел ​

  • Находки Kubernetes по кластерам — сводка со всех control plane.
  • Helm в кластеры — один релиз в выбранные кластеры (или в кластеры группы хостов) заданием хаба, по очереди, с итогом по каждому.
  • Обновление кластера — «Обновить» у кластера: версия, затем по узлам (control plane первыми) cordon, drain, обновление, ожидание Ready, uncordon; на ошибке задание останавливается и продолжается с того же узла.
  • Манифесты: один YAML в несколько кластеров — манифест и выбор кластеров; перед записью — дифф текста с прошлой редакцией и kubectl diff по каждому кластеру, запись — kubectl apply на первом control plane каждого, итог по кластерам. Каждое применение хранится на хабе редакцией; прежнюю можно открыть в редакторе и применить заново.
  • Образы для кластеров — свой qcow2/img/raw загружается на хаб один раз (до 10 ГБ) и выбирается в размещении как «с хаба: …»; при создании хаб заливает его на каждый хост, где образа ещё нет.
  • Сохранённые наборы — «сохранить набор» запоминает всю форму под именем, выбор набора заполняет её заново; наборы едут в экспорт/импорт.
  • Кэш хаба для узлов без интернета — если у хоста включён «apt через хаб», через тот же порт идут и файлы по ссылке (установщик и бинарник k3s с airgap-образами, Cilium CLI, ключ pkgs.k8s.io, образы машин), и зеркало registry (docker.io, quay.io, registry.k8s.io, ghcr.io, gcr.io) — containerd узлов настраивается на него сам. Всё оседает на хабе и уходит в интернет один раз.
  • kubectl — кнопка у готового кластера открывает терминал на первом control plane с готовым kubectl (KUBECONFIG, автодополнение, алиас k); доступ к API снаружи не нужен.
  • Попробовать снова — упавшее задание создания продолжается с того места, где остановилось: созданные машины, туннель и установленные роли не делаются заново.
  • Перед установкой роли узел обновляется до версии nkt хаба; при повторе остатки неудачного kubeadm init/join убираются сами.
  • Удаление кластера убирает машины, туннель и сеть машин; узел-хост остаётся в списке хостов.

В сценариях то же — k8s create с nodes "hv1: cp 1, w 2; hv2: w 2; hv3: host w", network nat|bridge|wireguard, version 1.34, image hub:<файл>, endpoint АДРЕС (Сценарии).

Подробности установки ​

  • kubeadm ставит пакеты из pkgs.k8s.io выбранной ветки; ветка записывается в кластер, и добавленные потом worker'ы получают ту же. Старые ветки вроде v1.31 на Debian 13 не годятся: sqv отвергает их подпись как устаревшую.
  • containerd на машине из облачного образа ставится пакетом дистрибутива; на «железном» хосте уже стоящий (например, containerd.io от Docker) не переустанавливается — у него включаются CRI и SystemdCgroup, прежний конфиг остаётся в config.toml.nkt-bak, контейнеры Docker не останавливаются.
  • Cilium — после старта control plane ставится cilium CLI (последняя стабильная, с проверкой суммы) и cilium install; «заменить kube-proxy» — --disable-kube-proxy у k3s, --skip-phases=addon/kube-proxy у kubeadm.
  • Пробросить наружу — DNAT с портов хоста (6443, 80, 443, любой можно заменить или обнулить) на control plane: свои цепочки NKT-PF, юнит nkt-portforward.service восстанавливает их при загрузке. kubeconfig тогда указывает на хост и выбранный порт API.
  • WireGuard: интерфейс nktwg<N> с адресом 10.200.<N>.<i>/24, сеть машин 10.<100+N>.<i>.0/24; PostUp открывает UDP-порт, пропускает FORWARD через туннель и снимает маскарад libvirt между подсетями машин — узлы видят друг друга по настоящим адресам. Перед созданием машин хаб проверяет связь каждой пары хостов по туннелю; без рукопожатия в журнале — «UDP 51820 закрыт или адрес неверный».
  • Мост: адрес машины узнаётся через qemu-guest-agent, который cloud-init ставит при первом запуске.
  • Задание создания — задание хаба: машины создаются тем же путём, что «Новая машина», дальше установка роли, токен, присоединение остальных узлов, ожидание Ready, проброс и kubeconfig. API повтора: POST /api/jobs/{id}/retry, POST /api/hub/clusters/{id}/retry.