Портативный Kubernetes: строим частное ARM64-облако своими руками

Прокомментировать Просмотры: 5

Размеры и порты

Старт

Внешне Mixtile Cluster Box напоминает плотный мини-сервер, однако внутри скрывается куда более интересная архитектура: квартет автономных плат Blade 3, современный PCIe-коммутатор, выделенный управляющий модуль под управлением OpenWrt и амбициозная задумка объединить ноды в локальную IP-сеть прямо поверх шины PCIe. Моя планка была выше банального развертывания домашнего Kubernetes: я намеревался избавиться от штатного Debian, построить отказоустойчивый кластер на базе Talos, развернуть Cozystack и на практике протестировать производительность аппаратных компонентов — накопителей NVMe, виртуализации KVM, а также графических (GPU) и нейросетевых (NPU) ускорителей.

На текущий момент система функционирует стабильно. В распоряжении имеются четыре ARM64-узла (три control-plane и один compute), операционная система Talos Linux 1.14.2, Kubernetes 1.34.3 и Cozystack 1.7.0-alpha.3 с профилем isp-full. Поверх этого стека задействованы LINSTOR в связке с DRBD и ZFS, KubeVirt с поддержкой аппаратной виртуализации KVM, а графический чип Mali-G610 и NPU RK3588 корректно распознаются на каждой плате. Тем не менее, путь к этому результату оказался значительно тернистее сценария «скачал готовый образ и заварил чай».

Архитектура Cluster Box

Устройство представляет собой компактный корпус форм-фактора 213 × 190 × 129 мм, рассчитанный на размещение четырех модулей Blade 3. Внутренняя объединительная плата (backplane) оснащена коммутатором ASMedia ASM2824, четырьмя слотами U.2 для вычислительных плат, четырьмя разъемами M.2 NVMe (PCIe 3.0 x2), четырьмя портами SATA 3.0, отдельным контроллером управления, парой 60-миллиметровых кулеров и внешним гигабитным сетевым интерфейсом. Питание подается от источника 19–19,5 В с силой тока до 4,74 А, что номинально ограничивает энергопотребление всей конструкции на уровне 90 Вт.

Каждая плата Blade 3 монтируется в слот U.2, через который одновременно подается питание и передаются линии SATA и PCIe 3.0 x4. Производитель отказался от последовательного соединения: у каждого модуля есть собственный выделенный канал до коммутатора ASM2824. Подробная схема и спецификации распиновки приведены в официальном даташите Cluster Box v1.1. Стоит отметить, что во второй ревизии устройства отладочный разъем SFF-8643 был заменен на более современный OCuLink.

Аппаратная база каждого модуля Blade 3 строится вокруг процессора RK3588, объединяющего четыре ядра Cortex-A76, четыре энергоэффективных Cortex-A55, графический ускоритель Mali-G610, модуль NPU производительностью до 6 TOPS, 32 ГБ оперативной памяти LPDDR4, 256 ГБ памяти eMMC, два порта 2.5GbE, линии PCIe 3.0 x4 и интерфейсы SATA через слот U.2, а также видеовыход HDMI 2.1 с аппаратным декодированием H.264/H.265 вплоть до разрешения 8K. Более детальные сведения можно найти в документации на Blade 3.

В сумме кластер обладает впечатляющими для такого форм-фактора характеристиками: 32 вычислительных ядра, 128 ГБ ОЗУ, четыре графических ядра, совокупная производительность NPU до 24 TOPS и около терабайта встроенной памяти eMMC. В моем случае на каждом модуле установлен твердотельный накопитель Samsung 980 PRO объемом 2 ТБ, что в сумме дает 8 ТБ сырого пространств NVMe. Из-за особенностей архитектуры объединительной платы накопители функционируют на линиях PCIe 3.0 x2, а не x4, однако для данного класса оборудования этого запаса прочности хватает с избытком.

Диаграмма
Диаграмма

Контроллер управления на базе OpenWrt

Формально данное решение не является классическим контроллером BMC с поддержкой IPMI или Redfish, однако выполняет схожие функции: управляет питанием плат Blade 3, предоставляет веб-интерфейс и доступ по SSH, конфигурирует коммутатор PCIe, отслеживает состояние нод через утилиту nodectl, занимается выдачей адресов, выполняет роль Root Complex для технологии MIOP и обеспечивает внешний интернет-шлюз.

Начинка управляющей платы сравнительно скромна: процессор MediaTek MT7620A (MIPS24KEc, 580 МГц), 256 МБ оперативной памяти DDR2 и операционная система OpenWrt. Если в спецификациях 2023 года упоминались 16 МБ SPI Flash, то в обновленной ревизии объем хранилища расширен до 16 ГБ, отладочный порт перенесен на интерфейс OCuLink, а заводскую прошивку теперь можно восстановить с помощью физической кнопки питания. «Из коробки» устройство поставляется с OpenWrt 23 на борту, подробности об обновлении аппаратной части публиковались в официальном блоге Mixtile.

Панель управления доступна по IP-адресу контроллера. Стандартные учетные данные — mixtile / mixtile — настоятельно рекомендуется изменить сразу после первого входа, избегая при этом публикации интерфейса во внешнюю сеть.

Используя эту платформу OpenWrt, я постепенно формирую собственную управляющую среду. Прямо из браузера можно дистанционно включать, выключать или перезагружать любой модуль Blade 3, мониторить его состояние, переключаться на последовательную консоль (serial), изучать системные логи, регулировать скорость вращения вентиляторов и проверять доступность Talos API на порту 50000. Штатное корректное выключение инициируется коротким нажатием на кнопку питания через линии GPIO: контроллер ожидает завершения процессов ОС и лишь при зависании ноды принудительно снимает питание.

UI Cluster Box bmc
UI Cluster Box bmc

Автономность OpenWrt от инфраструктуры Kubernetes является главным преимуществом: даже при полном падении control-plane сохраняется возможность управления питанием, доступ к консоли и шанс реанимировать узел. Дополнительно я экспериментировал с установкой легковесного агента Teleport, адаптированного под архитектуру MIPS, чтобы организовать защищенный доступ к устройству без проброса портов наружу. Полноценная интеграция пока остается в планах на будущее.

Доступ  в serial через UI
Доступ в serial через UI

MIOP: сетевое взаимодействие по шине PCIe

Наиболее интригующая особенность устройства — организация стека TCP/IP непосредственно поверх шины PCIe. Контроллер на базе MT7620A выступает в роли Root Complex, четыре платы Blade 3 работают как конечные точки (endpoints), коммутатор ASM2824 выделяет каждой из них линии x4, а специальный драйвер создает стандартный сетевой интерфейс (на контроллере он именуется pci0). Команда nodectl list позволяет увидеть все четыре подключенных модуля.

Согласно внутренней документации Mixtile, свежая версия драйвера способна демонстрировать пропускную способность до 19 Гбит/с в утилите iperf3 и около 15,5 Гбит/с в полнодуплексном режиме. Это существенно превосходит показатели как стандартного гигабитного линка, так и встроенных контроллеров 2.5GbE. В среде OpenWrt поддержка MIOP уже интегрирована в прошивку, однако для самих плат Blade 3 производитель поставляет лишь пакеты DEB и специализированные образы для Debian, Ubuntu и собственной кастомной сборки. Исходные коды актуального драйвера, к сожалению, закрыты.

Для концепции Talos это становится серьезным препятствием. Данная операционная система неизменяема (immutable), установка сторонних пакетов .deb в нее невозможна, а драйвер должен строго соответствовать ABI ядра и поставляться в виде системного расширения (system extension). Представители Mixtile обещали подготовить сборку под Talos, но на момент написания статьи она еще не вышла. По этой причине ноды общаются между собой через обычный интерфейс 2.5GbE. Как только появится необходимый драйвер, трафик репликации DRBD между NVMe логично перевести на шину PCIe, оставив гигабитный Ethernet исключительно для входящего Ingress-трафика.

Препятствия при использовании стандартных образов Talos

Задействовать ванильное ядро Talos удалось, однако стандартный образ для Blade 3 «из коробки» не запустится: для этого требуются кастомный Device Tree, адаптированный под плату загрузчик U-Boot, компоненты TF-A, бинарный файл инициализации памяти DDR, специальные SBC-оверлеи, корректное смещение загрузчика, установщик и набор расширений. Репозиторий с необходимыми наработками доступен по адресу mixtile-rockchip/mixtile-talos.

На данный момент используется Talos 1.14.2, официальное ядро Linux 6.18.54, U-Boot 2026.07, TF-A версии lts-v2.14.6 и Device Tree из актуального mainline-порта Blade 3 для проекта Armbian. Оверлей спроектирован по аналогии с siderolabs/sbc-rockchip, однако применение DTB от платки Turing RK1 недопустимо — при идентичном процессорном разъеме схемотехника плат различается кардинально.

Процесс сборки автоматизирован через Docker Buildx: сперва оверлей публикуется в OCI-реестре, после чего официальная утилита формирует установщик и сырой образ диска. На выходе получается файл _out/metal-arm64.raw.xz. Перед запуском прошивки специальный скрипт проверяет содержимое 64-го сектора и аварийно завершает работу при обнаружении пустоты — это предохраняет от записи нерабочих образов без встроенного загрузчика.

В состав итогового образа включены официальные расширения: DRBD 9.3.4, ZFS 2.4.4, утилиты iSCSI, графические драйверы Panfrost/Panthor для Mali-G610, а также компоненты Rockchip RKNN с модулем ядра rocket. Все они скомпилированы строго под ABI версии Talos 1.14.2 с сохранением идентичной цифровой подписи модулей.

Каждый модуль прошивался индивидуально в режиме MaskROM. На macOS процедура выполняется с помощью утилиты rkdeveloptool: переключатель DIP 4 переводят в положение ON, подают питание, выполняют команды rkdeveloptool ld, загружают во временную память SPL-загрузчик и записывают raw-образ во внутреннюю память eMMC. В репозитории этот алгоритм автоматизирован в виде скрипта scripts/flash-blade3-macos.sh, который проверяет целостность архива и загрузчика, дожидается подключения ровно одной платы, запрашивает подтверждение оператора и только затем производит запись. Временный загрузчик требуется исключительно для инициализации по USB, тогда как постоянный U-Boot уже зашит в образ, начиная с 64-го сектора.

Команды сборки и прошивки
docker login ghcr.io
USERNAME= ./build.sh all

rkdeveloptool ld
rkdeveloptool db rk3588_spl_loader_v1.08.111.bin
./scripts/flash-blade3-macos.sh

Трудности в процессе настройки

Первые попытки сборки успешно завершались отчетами об успехе, но U-Boot по факту отсутствовал в положенном месте — теперь это отсекается на этапе проверки 64-го сектора. На следующем этапе утилита генерации образов корректно распознавала оверлей, однако установщик отказывался работать до тех пор, пока структура пакетов не была приведена в соответствие с актуальным API Talos 1.14. Дополнительные проблемы доставил Python 3.14 в среде macOS: с ним часть инструментов сборки U-Boot отказалась компилироваться, из-за чего версию интерпретатора пришлось зафиксировать.

Наиболее коварная проблема носила сетевой характер. Пара контроллеров RTL8125B подключена через коммутатор ASM1182e и лишена заводских MAC-адресов в микросхеме EEPROM, поэтому стандартный драйвер r8169 генерировал новый случайный адрес при каждой перезагрузке. В домашних условиях это доставляет неудобства, но в кластере Kubernetes такое поведение моментально ломает DHCP, распределенную базу etcd и привязку томов LINSTOR. Встроенный загрузчик U-Boot уже умел считывать стабильные аппаратные адреса из энергонезависимой памяти OTP, однако в дереве устройств ядра (DTB) отсутствовали как необходимые алиасы, так и корректное описание шины PCIe. После ручного добавления корневого порта, коммутатора, дочерних портов и алиасов сетевой драйвер начал корректно присваивать постоянные MAC-адреса.

Для полноценной работы хранилища оказалось недостаточно одного модуля drbd.ko: в конфигурационном файле ноды потребовалось явно активировать транспорт drbd_transport_tcp, после чего LINSTOR успешно сформировал реплицируемые тома. Графический процессор и NPU на платах присутствовали изначально, однако в ванильном ядре Linux они оставались неактивными. Для их задействования были интегрированы драйверы Panfrost/Panthor для Mali и rocket для NPU, а в Device Tree открыты три ядра и блок IOMMU. В результате на всех четырех модулях появились рабочие устройства /dev/dri/renderD128 и /dev/accel/accel0.

Развертывание кластера и Cozystack

Конфигурация Talos формируется с помощью утилиты talm. Узлы управления получили IP-адреса в диапазоне 192.168.70.201–204, а в качестве виртуального IP-адреса (VIP) для API задействован 192.168.70.205. Три ноды задействованы под control-plane, четвертая выполняет роль worker-узла, при этом поды распределяются по всем четырем платам. Сетевая схема стандартна: подсети 10.244.0.0/16 для подов и 10.96.0.0/16 для сервисов, доменная зона — cozy.local. Системные компоненты Talos и etcd размещаются на быстрых накопителях eMMC, тогда как массивы NVMe целиком отданы под нужды распределенного хранилища.

Поверх Kubernetes установлен Cozystack 1.7.0-alpha.3 с профилем isp-full. Поскольку речь идет об альфа-версии, говорить о промышленной эксплуатации пока рано, однако платформа развернулась успешно: Flux, Kube-OVN, Cilium, MetalLB, cert-manager, KubeVirt, CDI, LINSTOR, VictoriaMetrics, Grafana, Velero, Cluster API и набор операторов для баз данных функционируют штатно. Контрольная проверка показала статус 4/4 Ready для нод, 111/111 успешных HelmRelease и 240 активных подов (из них 237 в статусе Running и 3 Succeeded, без ошибок или зависаний).

Каждый узел располагает примерно 250 ГБ памяти eMMC под системные нужды и терабайтами на диске Samsung 980 PRO для данных. Настроено два класса хранения: local с единственной копией и стратегией WaitForFirstConsumer, а также replicated на базе DRBD с параметром autoPlace: 3. Реплики распределяются по трем физическим платам, что позволяет безболезненно терять один узел без риска утраты данных. На данный момент передача данных идет по сети Ethernet, но с появлением поддержки MIOP в Talos репликацию планируется перенести на шину PCIe.

Аппаратная виртуализация KVM на процессорах RK3588 поддерживается ядром Talos «из коробки», поэтому KubeVirt корректно обнаруживает устройство /dev/kvm на всех узлах. Для тестирования была развернута виртуальная машина с Ubuntu 24.04.5 (2 vCPU, 4 ГБ оперативной памяти и 20 ГБ дискового пространства на реплицируемом томе), доступ к которой осуществлялся через virtctl. Команда uname -m подтвердила архитектуру aarch64, утилита systemd-detect-virt определила окружение как kvm, а вывод lscpu продемонстрировал реальные ядра A76 и A55 без признаков эмуляции. После завершения тестов ВМ и связанный с ней том были удалены.

Поддержка GPU и NPU на уровне ядра уже активна. Для их проброса внутрь контейнеров требуются соответствующие device-плагины и пользовательское окружение: библиотеки Mesa/PanVK для графики Mali и специализированный стек для ускорителей rocket. Официальный инструментарий RKNN Toolkit2 с данным драйвером несовместим, так как ему требуется проприетарный модуль ядра rknpu.ko.

Схема сети и проверка VM
192.168.70.201  node 1
192.168.70.202  node 2
192.168.70.203  node 3
192.168.70.204  node 4
192.168.70.205  Kubernetes API VIP

Pod CIDR:       10.244.0.0/16
Service CIDR:   10.96.0.0/16
Cluster domain: cozy.local
$ uname -m
aarch64

$ systemd-detect-virt
kvm

Планы по развитию BMC

Следующий этап автоматизации заключается в том, чтобы научить управляющую плату не просто пассивно мониторить состояние нод, но и полностью сопровождать их жизненный цикл от подачи питания до ввода в кластер. В настоящее время установка Talos требует ручного вмешательства через режим MaskROM и USB-подключение. Желаемый сценарий выглядит следующим образом: контроллер самостоятельно подключается к последовательной консоли, прерывает загрузку в U-Boot, скачивает образ по протоколу TFTP, записывает его на eMMC и ожидает отклика на порту 50000. В веб-интерфейсе это должно быть реализовано в виде простой кнопки и ссылки для выбора образа. Служба TFTP через dnsmasq уже настроена, утилита lrzsz зарезервирована для передачи по serial, однако пересылать гигабайтный образ таким способом неэффективно. Кроме того, Talos распространяется в формате .raw.xz, тогда как встроенный в U-Boot распаковщик gzwrite работает только с архивами gzip, что потребует предварительной распаковки файла силами самого контроллера.

Текущий функционал BMC ограничивается базовой проверкой доступности порта 50000. В графический интерфейс необходимо добавить отображение версии Talos, сетевого имени хоста, IP-адресов, роли ноды, а также состояния накопителей и сети. Имя хоста уже проскакивает в логах консоли, поэтому физический слот можно сопоставлять с конкретным узлом автоматически. Команды выключения также планируется перенаправить через Talos API, оставив управление по GPIO в качестве аварийного резерва, поскольку для баз данных etcd и распределенного хранилища DRBD резкое отключение питания крайне нежелательно.

Как только появится модуль MIOP, адаптированный под ядро 6.18.54-talos, внутреннюю объединительную шину можно задействовать для репликации данных, процедур bootstrap и восстановления. Самостоятельно собрать этот закрытый модуль без исходных кодов не представляется возможным. Дополнительно требуется разработка легковесного API для управления питанием, мониторинга статуса, консольного доступа и установки образов. Реализация подмножества протокола Redfish значительно упростит интеграцию кластера с такими инструментами, как Ironic и Metal3.

Из менее масштабных задач — ведение журнала системных событий с фиксацией того, кто именно инициировал отключение питания, система уведомлений о зависании узлов на этапе загрузки U-Boot, динамическое регулирование скорости вентиляторов на основе температурных датчиков, поддержка HTTPS для веб-панели и терминала, выделенная сеть управления, а также цифровая подпись обновлений OpenWrt. Конечная цель проста: полностью автономное устройство, способное самостоятельно развернуть Talos, активировать ноды, объединить их в кластер и подготовить к работе без использования флешек или прямого подключения по SSH.

Итоги эксперимента

Форкать ядро Talos не потребовалось: используются официальный Linux 6.18.54, стандартные расширения, стандартный генератор образов, стандартный Kubernetes и практически неизмененный Cozystack. Уникальными компонентами остались лишь загрузчик U-Boot, Device Tree, бинарники TF-A/RKBin, оверлей, инсталлятор и методика прошивки.

Главным ограничением на данный момент остается проприетарная природа MIOP. Аппаратная база для создания высокоскоростной внутренней сети присутствует, но перенести драйвер на новое ядро без исходных кодов нельзя. Тем не менее, даже в текущей конфигурации четыре платы Blade 3 образуют полноценный компактный ARM64-кластер, способный выполнять функции control-plane, хранилища, виртуализации, мониторинга и задействовать аппаратные ускорители GPU и NPU, умещаясь при этом в корпусе чуть крупнее обычного мини-ПК.

При активной нагрузке энергопотребление системы колеблется в пределах 30–40 Вт. Питание можно организовать через триггер USB-C PD на разъем DC 5.5×2.5 мм, однако официальный допуск производителя составляет 19–19,5 В, тогда как стандартный профиль Power Delivery выдает 20 В, формально выходя за рамки спецификации.

Для кого этот проект

Решение явно не рассчитано на тех, кому достаточно одного мини-ПК для Docker-контейнеров. Оно создано для энтузиастов, желающих получить персональное облако из четырех нод, которое легко помещается в рюкзаке, и поэкспериментировать с развертыванием Cozystack на архитектуре ARM64. Устройство не подойдет тем, кто ищет сценарий «включил и забыл»: путь к стабильной работе лежит через режим MaskROM, настройку виртуальных IP-адресов и неизбежные трудности отладки. Это не замена корпоративному дата-центру, а скорее уникальный настольный микро-ЦОД, который честно выполняет свои задачи, изредка преподносит сюрпризы и потребляет меньше электроэнергии, чем электрический чайник.

Hababi come to ...
Hababi come to…

Источники

 

Источник

Поделиться:

Похожие статьи

Поиск по играм, новостям и статьям…

Введите не менее двух символов

Введите не менее двух символов