О кластере из OPi0: Часть 1

Я с горем пополам загрузил одноплатник с сети, испытав при этом смешанные чувства.
В первой части прикидываем масштабы трагедии и пытаемся что-то запустить.

Введение

Однажды, начитавшись тематических статеек в интернете, мне приспичило сделать так же, но своё, родное. Ну, и по возможности — чуть более упоротое, чем у других.

И идея получилась такая: взять с десяток одноплатных компьютеров и построить из них кластер. Одноплатники хочется иметь дешёвые (я же пока не миллионер, а с экономической точки зрения такой кластер — куча денег на ветер: облачку за ту же сумму можно на годы арендовать), и выбор мой остановился на Orange Pi Zero. Хотелось также сэкономить на флешках, изыскав внутренние резервы, поэтому одноплатники должны грузиться с сети каким-то унифицированным имиджем (ну, или двумя-тремя, мне не принципиально). У одноплатников богато GPIO ножек (хотя гребёнки придётся купить отдельно и припаять самостоятельно), поэтому хочется организовать некое взаимодействие через них, а не через «продуктивную» сеть. Возможно, даже запилить какую-нибудь daughter-board с разъёмами, с неё же подводить питание, ею же управлять охлаждением, моргать лампочками и всё, что душа пожелает.

Общий вид изделия в воображении автора
Общий вид изделия в воображении автора

С софтовой частью я пока ещё не определился. Всё-таки, машинки чахленькие, и многий современный софт на них будет чувствовать слегка неуютно, а хочется чтобы на них сверху ещё и что-то полезное можно было запустить. Кубер напрашивается, но, думается мне, точно не взлетит. Будем посмотреть.

Вопрос хранилища продуктивных данных открыт, но пока не прорабатывался вовсе. Возможно, сгодится и имеющийся NAS, с которого должна происходить загрузка, возможно придумаю что-то ещё. Но пока дешёвых одноплатников™ с пристойной дисковой подсистемой мне не попадалось.

Дисклеймер: приведённые здесь и в последующих частях сведения не претендуют на корректность, полезность и что бы то ни было. Задачей текста является описание моего личного опыта, а не предоставление уважаемому читателю инструкций, пригодных для воспроизведения и получения какого-либо результата. Если уважаемый читатель на свой страх и риск (а как иначе) решит что-то повторить, а его в результате прибьёт током, его квартира выгорит, за закупленное оборудование образуются кредиты или постигнет ещё какая неприятность — я тут совершенно ни при чём, у читателя (либо его законного представителя) имеется своя голова на плечах, и о последствиях ему стоит думать самостоятельно.

Обвязка

Тут всё уже придумано до нас, и всё необходимое у меня есть в наличии. А необходимо следующее:

Пункты 2 — 4 могут быть как одним физическим устройством, так и несколькими, в произвольных комбинациях. Задача — выдать девайсу адрес, конфиг загрузчика, ядро и initrd, и корневую ФС. Как это сделано у меня? Очень просто. Есть роутер MikroTik, на нём DHCP-сервер помимо прочего отдаёт опцию Next Server, в которой IP-адрес TFTP-сервера. Сам роутер тоже может поработать TFTP-сервером (тогда эта опция не нужна), но когда надо жонглировать опциями в загрузчике — он не очень удобный (а для устаканившейся конфигурации вполне подойдёт). TFTP у меня работает на NAS фирмы QNAP. Очень удобно оказалось, подключившись к нему по SSH, редактировать по велению левой пятки конфиги, тут же перезагружать плату и смотреть, что получилось. На нём же работает и NFS (и то, и другое — штатный функционал, как, кстати, и NTP — пригодится в хозяйстве). При этом NFS и TFTP отдают один и тот же каталог, чтобы два раза не вставать.

По поводу пункта 5 — разъёмов для подключения монитора у платы нет (на самом деле извернуться можно — на гребёнке о 13 пинах на девятом есть TV-OUT, но его ещё найди, куда подключить). Зато есть UART, который, имеючи соответствующие переходники и кабели, можно подключить к COM- или USB-порту компьютера. У меня это неведомый девайс с названием JY-R2T, согласующий UART платы и COM компьютера, а заодно подводящий к плате 5 вольт питания на первую ногу 13-пиновой гребёнки. Подключить остальные три пина не составит труда любому умеющему отличать буквы друг от друга.

Тестовый стенд (aka кишочки)
Тестовый стенд (aka кишочки)

Загрузка

Чтобы хоть как-то загрузить плату, нам понадобится U-Boot. На сайте linux-sunxi есть инструкции, как собрать U-Boot и как закатать его на встроенную флешку (да-да, какая-никакая память у платы всё же есть, но маленькая и кроме загрузчика туда ничего не втулить). Шаг про сборку можно немного пропустить, если в качестве ОС для платы использовать Armbian (не исключено, что другие дистрибутивы тоже так могут) и собирать его штатными средствами, тогда образ будет среди артефактов сборки.

U-Boot в принципе штука довольно крутая, и даже если не задаваться целью загрузить «большую» операционную сиситему, в него можно довольно неплохо поиграться — через UART будет доступна весьма фичастая оболочка. Если ничего не трогать, то U-Boot, не найдя ни одного пригодного для загрузки локального диска, пойдёт в сеть. Узнав у DHCP адрес TFTP (это либо Next Server, либо он же сам), он пойдёт искать конфигурационный файл. Там есть своя хитрая логика (сначала для имени файла используется MAC-адрес интерфейса, затем IP-адрес, который постепенно усекается, потом ещё разные варианты написания названия платы от конкретного к более общему), позволяющая в одном хранилище иметь конфиги для разных плат, и они не будут мешать друг другу. Чего я, собственно, рассказываю-то, он обо всём этом пишет в консоль: можно взять и посмотреть.

Здесь нам нужно отдать по TFTP простенький текстовый файл, минимально содержащий информацию, где взять ядро и какие опции ему передать при загрузке. Что-то в духе:

default opi0

label opi0
  kernel boot/zImage
  initrd boot/initrd.img-5.10.30-sunxi
  fdt boot/dtb/sun8i-h2-plus-orangepi-zero.dtb
  append root=/dev/nfs nfsroot=192.168.249.5:/Public/tftp rw autoconf=1 console=ttyS0,115200 sunxi_ve_mem_reserve=0 sunxi_g2d_mem_reserve=0 sunxi_fb_mem_reserve=16 cpufreq.off=1

Часть опций понадёргана из тематических статей, часть подобрана экспериментально, но вот именно с такой комбинацией плата всё-таки загрузилась и изволила поработать. Однако пытливый читатель на этом месте поинтересуется: а что же ты, друг, собрался загружать, если у тебя ничего нет?

Терпение, спокойствие, сейчас они появятся!

Берём, короче, Armbian — клонируем репо, а не выкачиваем готовый имидж под нашу плату. Ядро надо собирать. Там есть разные варианты этого процесса. Сборка на «живой» ОС мне не подошла, потому что заточена под Ubuntu, и вызывала страдание. Сборка под Docker выкидывала коленца, «забывая» иногда выдать какие-либо из артефактов. Зато сборка под ВМ, управляемой Vagrant работает на ура — по крайней мере, у меня. Процесс это не очень быстрый, поэтому запустив что-то в духе

./compile.sh vagrant BOARD=orangepizero \
                     BRANCH=current \
                     RELEASE=buster \
                     BUILD_MINIMAL=yes \
                     BUILD_DESKTOP=no \
                     KERNEL_ONLY=no \
                     KERNEL_CONFIGURE=yes

можно смело пойти пить кофе пешком в соседний город. Ну, не сразу, а выставив опции сборки ядра. Можно, кстати, делать не MINIMAL (DESKTOP точно не надо) и тогда на кофе можно не останавливаться. Опции для сборки — это, кстати, самый интересный момент. Их там много. Нет, МНОГО. Даже МНОГО. Кровь-из-ушей нам нужна, по-хорошему, только одна — поддержка Root FS на NFS. Остальными стоит (осторожно и вдумчиво) поиграться во имя оптимизации, отключения ненужного, включения полезного… Я пока не нашёл для себя хорошей комбинации: во имя поиска проблем с зависанием платы последний конфиг имеет всё по умолчанию, плюс NFS, плюс повышенная болтливость всего отладочного, что только есть (не сильно помогло, к слову).

Зато помогла опция загрузки cpufreq.off=1. Не знаю пока, почему так. Без неё система вешалась где-то примерно после подъёма сетевых интерфейсов, не успев ничего толком сказать. Будем выяснять.

В общем, по окончании сборки останется только смонтировать имидж и залить его содержимое на сервер, туда же забросить все эти ядра, initrd, dtb, чуть-чуть подправить будущий /etc/fstab (оставить в нём только запись про tmpfs), подключить — и можно стартовать!

It's alive! ALIVE!
It’s alive! ALIVE!

Засим первая часть заканчивается. Нужно подобрать опции сборки и что-то решить с софтом. А ещё припаять уже гребёнку. И непременно подумать, что у машинок общее и можно монтировать RO из одного и того же места, а что — врозь, и должно быть в разных. Ну, и максимально автоконфигурацию всего, что можно.

 2021-05-08
it
linux