balena Fin – это несущая плата для вычислительного модуля Raspberry Pi 3/3+, разработанная специально для промышленного использования услуги по управлению компьютерным парком, предоставляемых Balena. В прошлом месяце мы получили комплект разработчика balenaFin, и в первой части обзора показали, как собрать комплект.
Теперь настало время внимательнее изучить комплект, а также операционную систему на базе BalenaOS Linux, оптимизированную для запуска контейнеров Docker на встроенных устройствах, и службами balenaCloud для управления парком устройств с веб-панели мониторинга.
Следуем инструкциям из руководства по началу работы, которые можно найти здесь и здесь, и будем описывать, что нам нужно было сделать, чтобы подготовить образ, перенести его на плату и загрузить образец приложения Docker локально и через balenaCloud.
Загрузка и настройка BalenaOS для balena Fin
Вы найдете BalenaOS на странице загрузки. Хотя мы используем оборудование на базе вычислительного модуля Raspberry Pi, обязательно выберите «Fin» вместо «Raspberry Pi».
Сначала скачиваем версию «Production» вместо версии «Development», но, оглядываясь назад, лучше сначала перейти на последнюю, объясним позже почему.
Как только мы получим наш файл, мы можем разархивировать прошивку:
1 |
unzip balena.img.zip |
Следующим шагом является установка Balena CLI, инструмента командной строки на основе node.js, используемого для разработки контейнеров приложений на основе balenaOS. Сначала нам понадобится последняя версия node.js & npm, которую мы установим с помощью сценария nvm (Node Version Manager):
1 |
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash |
Выйдем из текущего терминала и перезапустим его, чтобы установить узел:
1 |
nvm install node |
и, наконец, мы можем установить сам balena-cli:
1 2 3 |
sudo chown -R $USER:$GROUP ~/.npm sudo chown -R $USER:$GROUP ~/.config npm install --global --production --unsafe-perm balena-cli |
Обратите внимание, что нам пришлось запустить две команды chown, чтобы избежать следующих проблем с разрешениями:
1 |
Unhandled rejection Error: EACCES: permission denied, open '/home/jaufranc/.npm/_cacache/tmp/6f8b51b1' |
Сначала мы попытались установить npm через apt, но возникли различные проблемы, поэтому рекомендуем придерживаться nvm.
На большинстве встроенных устройств вы можете прошить образ, затем загрузить устройство и настроить все на устройстве, но с BalenaOS все немного иначе. Сначала мы можем настроить образ balenaOS для подключения к сети WiFi, настроить хост-имя платы и отключить постоянное ведение журнала, чтобы продлить срок службы флэш-памяти eMMC с хост-компьютера:
1 2 3 4 5 6 7 |
$ sudo env "PATH=$PATH" balena local configure balena.img ? Network SSID CNX-SOFTWARE-ZTE ? Network Key superSecretPassword ? Do you want to set advanced settings? Yes ? Device Hostname cnxsoft-balena ? Do you want to enable persistent logging? No Done! |
Нам пришлось добавить env «PATH = $ PATH» в командную строку, иначе команда balena будет найдена sudo. Запуск от имени обычного пользователя также завершится неудачей.
Сохранение balema.img с прошивкой balena Etcher
Теперь, когда наш образ готов, мы можем прошить его через USB с помощью программы balena Etcher GUI. Нам кажется, что установка программы через apt это хорошая идея:
1 2 3 4 |
echo "deb https://deb.etcher.io stable etcher" | sudo tee /etc/apt/sources.list.d/balena-etcher.list sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61 sudo apt update sudo apt install balena-etcher-electron |
Но, потом мы поняли, что в настоящее время устанавливается balena Etcher v1.4.9, а прошивка Raspberry Pi CM3 + была добавлена только в версию 1.5.0. Вместо этого мы скачали «AppImage» для Linux x64, чтобы получить последнюю версию v1.5.19 на нашем компьютере.
После подключаем плату к компьютеру через порт micro USB и прилагаемый USB-кабель (для этого шага источник питания не требуется),
Мы можем выбрать образ (balena.img) и должны иметь возможность выбора вычислительного модуля в balena Etcher.
Плата правильно обнаружена.
1 2 3 4 5 6 |
[43548.078939] usb 1-2.1: new high-speed USB device number 8 using xhci_hcd [43548.279965] usb 1-2.1: config index 0 descriptor too short (expected 55, got 32) [43548.281093] usb 1-2.1: New USB device found, idVendor=0a5c, idProduct=2764, bcdDevice= 0.00 [43548.281096] usb 1-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [43548.281098] usb 1-2.1: Product: BCM2710 Boot [43548.281100] usb 1-2.1: Manufacturer: Broadcom |
Поэтому открываем терминал и запускаем инструмент с помощью sudo:
1 |
sudo ./balenaEtcher-1.5.19-x64.AppImage |
и … успех!
Инициализация вычислительного модуля займет несколько секунд, после чего он отобразится как устройство хранения объемом 7,82 ГБ, и мы, наконец, можем щелкнуть “Сохранить”, чтобы завершить установку, которая здесь заняла около 4 минут.
Плата не будет работать от USB-порта, поэтому нам нужно подключить ее к предоставленному источнику питания, чтобы она работала, а затем, через несколько секунд, мы можем попытаться пропинговать её:
1 2 3 4 5 6 7 8 9 10 11 |
ping cnxsoft-balena.local PING cnxsoft-balena.local (192.168.1.7) 56(84) bytes of data. 64 bytes from cnxsoft-balena (192.168.1.7): icmp_seq=1 ttl=64 time=85.0 ms 64 bytes from cnxsoft-balena (192.168.1.7): icmp_seq=2 ttl=64 time=3.91 ms 64 bytes from cnxsoft-balena (192.168.1.7): icmp_seq=3 ttl=64 time=1.91 ms 64 bytes from cnxsoft-balena (192.168.1.7): icmp_seq=4 ttl=64 time=1.93 ms 64 bytes from cnxsoft-balena (192.168.1.7): icmp_seq=5 ttl=64 time=1.92 ms ^C --- cnxsoft-balena.local ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4003ms rtt min/avg/max/mdev = 1.914/18.941/85.022/33.049 ms |
Все отлично. Это означает, что плата может автоматически подключаться к WiFi-роутеру. Теоретически, мы также должны иметь возможность подключиться непосредственно к плате через ssh:
1 |
sudo env "PATH=$PATH" balena local ssh mydevice.local --host |
Но, это не сработало:
1 |
root@cnxsoft-balena.local: Permission denied (publickey). |
Поэтому попробуем альтернативную команду без sudo:
1 |
ssh root@cnxsoft-balena.local -p22222 |
Но, результат тот же. Изучив проблему, мы обнаружили, что это может работать только с версией разработчика BalenaOS.
Поэтому, повторяем описанные выше шаги с версией разработчика balenaOS и, наконец, нам удается войти в систему и выполнить несколько команд:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
sudo env "PATH=$PATH" balena local ssh cnxsoft-balena.local --host root@cnxsoft-balena:~# uname -a Linux cnxsoft-balena 4.14.98 #1 SMP Fri Mar 22 07:02:01 UTC 2019 armv7l armv7l armv7l GNU/Linux root@cnxsoft-balena:~# balena-engine version Client: Version: 17.12.0-dev API version: 1.35 Go version: go1.9.7 Git commit: fe78e2c9a69313007c53c83fff4b5525fbc2ba45 Built: Mon Mar 11 15:28:35 2019 OS/Arch: linux/arm Experimental: false Orchestrator: swarm Server: Engine: Version: 17.12.0-dev API version: 1.35 (minimum version 1.12) Go version: go1.9.7 Git commit: fe78e2c9a69313007c53c83fff4b5525fbc2ba45 Built: Mon Mar 11 15:28:35 2019 OS/Arch: linux/arm Experimental: true root@cnxsoft-balena:~# |
Мы столкнулись с рядом проблем, хотя мы планировали просто установить образ, но, наконец, все установлено.
Запуск контейнера в balena Fin
Теперь мы можем создать копию демо-проекта на нашем хост-компьютере:
1 |
git clone https://github.com/balena-io-projects/multicontainer-getting-started.git |
Войдите в каталог и введите команду для сборки и загрузки демо-версии на плату:
1 2 |
cd multicontainer-getting-started/ balena push 192.168.1.7 |
Обратите внимание, что нам нужно использовать IP-адрес вместо хост-имени (т.е. cnxsoft-balena.local).
Вот результат нашей первой попытки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[Info] Starting build on device 192.168.1.7 [Info] Compose file detected [Build] [data] Step 1/7 : FROM balenalib/fincm3-debian-node:10-stretch-run [Build] [frontend] Step 1/12 : FROM balenalib/fincm3-debian-node:10-stretch-run [Build] [proxy] Step 1/3 : FROM arm32v6/haproxy:1-alpine [Build] [proxy] ---> 4e28d48faf2e [Build] [proxy] Step 2/3 : COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg [Build] [proxy] ---> bb68b59f16e3 [Build] [proxy] Step 3/3 : LABEL "io.resin.local.image"='1' "io.resin.local.service"='proxy' [Build] [proxy] ---> Running in 598214b13ea1 [Build] [proxy] Removing intermediate container 598214b13ea1 [Build] [proxy] ---> 6b45ce51a36e [Build] [proxy] Successfully built 6b45ce51a36e [Build] [proxy] Successfully tagged local_image_proxy:latest Some services failed to build: frontend: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout data: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout Additional information may be available in debug mode. Prefix the command line with DEBUG=1, i.e.: DEBUG=1 balena ... If you need help, don't hesitate in contacting our support forums at https://forums.balena.io For bug reports or feature requests, have a look at the GitHub issues or create a new one at: https://github.com/balena-io/balena-cli/issues/ |
Некоторое время ожидания было вызвано проблемой сети, но нам все же пришлось перезапустить команду с DEBUG = 1:
1 |
DEBUG=1 balena push 192.168.1.7 |
и на этот раз все может закончиться:
1 2 3 4 5 6 7 8 9 10 11 |
[Logs] [4/10/2019, 8:00:37 PM] [frontend] [Logs] [4/10/2019, 8:00:37 PM] [frontend] > resin-websocket@1.0.0 start /usr/src/app [Logs] [4/10/2019, 8:00:37 PM] [frontend] > node index.js [Logs] [4/10/2019, 8:00:37 PM] [frontend] [Logs] [4/10/2019, 8:00:37 PM] [data] [Logs] [4/10/2019, 8:00:37 PM] [data] > resin-websocket@1.0.1 start /usr/src/app [Logs] [4/10/2019, 8:00:37 PM] [data] > node index.js [Logs] [4/10/2019, 8:00:37 PM] [data] [Logs] [4/10/2019, 8:00:38 PM] [frontend] server is listening on port 80 [Logs] [4/10/2019, 8:00:40 PM] Started service 'proxy sha256:6b45ce51a36e917161594bf5ed5b307012c0ee6516e4abadfb451183cb674ef9' [Logs] [4/10/2019, 8:00:39 PM] [proxy] [NOTICE] 099/130039 (1) : New worker #1 (7) forked |
Так, ранее, у нас действительно была проблема с сетью. Нажмите здесь, чтобы посмотреть полный журнал.
Приложение создает график средней загрузки ЦП нашего устройства и использования памяти, доступ к которому можно получить в веб-браузере, просто набрав IP-адрес или введя хост-имя в адресной строке.
Управление balenaFin из balenaCloud
Использование balenaCloud не является обязательным, но это действительно удобно, поскольку вы легко работаете с приложением, отправляете его в облако и переносите его на все ваши устройства по беспроводной сети.
После регистрации учетной записи balenaCloud (бесплатно до 10 устройств), нажимаем кнопку «Создать приложение», заполняем имя приложения (например, мультиконтейнер), выбираем тип устройства Balena Fin (CM3), а также запуск приложения перед нажатием на кнопку «Создать новое приложение» .
Теперь нажимаем «Добавить устройство», выбираем версию для разработки, включаем Ethernet + WiFi (если вы планируете использовать WiFi), вводим учетные данные WiFi и нажимаем кнопку «Загрузить balenaOS» . После завершения загрузки мы можем перенести его на плату, как мы это делали ранее. Также есть возможность загрузить файл конфигурации, и, в нашем случае, это могло бы быть лучше, так как ранее мы уже перезагружали ОС. Вероятно можно просто отправить файл в /boot/config.json (через SSH), чтобы обновить плату (TBC).
Теперь мы можем вернуться в наш каталог multicontainer-Getting-Start, который мы извлекли из Github в предыдущем разделе, чтобы загрузить его в нашу учетную запись balenaCloud:
1 |
git remote add balena <username>@git.balena-cloud.com:<username>/<applicationname>.git |
Где <username> – это имя пользователя вашей учетной записи balenaCloud, а applicationname – имя вашего приложения, определенного на панели инструментов, и в данном случае «multicontainer». Эта команда заняла чуть более минуты и завершилась успешно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
[Success] Successfully uploaded images [Success] Release successfully created! [Info] Release: 89ae9a1f756843db93cf0fa02ce7f2c4eb4db6ea (id: 868612) [Info] ┌──────────┬────────────┬────────────┐ [Info] │ Service │ Image Size │ Build Time │ [Info] ├──────────┼────────────┼────────────┤ [Info] │ frontend │ 191.04 MB │ 50 seconds │ [Info] ├──────────┼────────────┼────────────┤ [Info] │ proxy │ 16.95 MB │ 5 seconds │ [Info] ├──────────┼────────────┼────────────┤ [Info] │ data │ 191.66 MB │ 14 seconds │ [Info] └──────────┴────────────┴────────────┘ [Info] Build finished in 1 minute, 8 seconds \ \ \\ \\ >\/7 _.-(6' \ (=___._/` \ ) \ | / / | / > / j < _\ _.-' : ``. \ r=._\ `. <`\\_ \ .`-. \ r-7 `-. ._ ' . `\ `, `-.`7 7) ) \/ \| \' / `-._ || .' \\ ( >\ > ,.-' >.' <.'_.'' <' To git.balena-cloud.com:cnxsoft/multicontainer.git * [new branch] master -> master |
Через некоторое время мы увидим, что наша плата balena Fin обновляется с помощью нашего приложения docker прямо на панели инструментов.
Как только это будет сделано, мы можем нажать на название устройства «Ancient-Tree», чтобы получить доступ к дополнительной информации, и включить «PUBLIC DEVICE URL»
Нажмите на восходящую синюю стрелку рядом с ним, чтобы открыть новое окно браузера, показывающее среднюю загрузку процессора и использование памяти.
Идея с balenaCloud заключается в том, что вы можете добавить все устройства из вашего компьютерного парка, связать их с конкретными приложениями по мере необходимости, и легко прозрачно обновить их все после завершения начальной настройки.
Чтобы продолжить, вы можете изучить документацию, которая поможет вам разрабатывать, развертывать и управлять приложениями в Docker с экосистемой Balena.
Рассмотренный здесь комплект разработчика balena Fin продается в магазине balena по цене 199 долларов США плюс доставка. Если вам не нужен корпус на DIN-рейку, вы можете сэкономить 20 долларов, выбрав вариант «без корпуса».
Выражаем свою благодарность источнику из которого взята и переведена статья, сайту cnx-software.com.
Оригинал статьи вы можете прочитать здесь.