openBalenaを使ってみた

# openBalenaとは
DockerをベースにしたIoTのプラットホームで、デバイスの管理が行えるもの。
詳しくはこちら　https://www.balena.io/open/

いろいろ自分でIoTデバイスを作っていると同じものが増えてきて管理が面倒になってきたので、うまく管理に使えないかということで試してみた。ちょっといろいろは待ったので自分用にメモ。

# 環境
とりあえずConohaのVPSとfreenom( https://www.freenom.com/ja/index.html?lang=ja )の無料ドメインを使ってサーバサイドを構築する。デバイスはRaspberry Pi3を使った。

以下環境

サーバス：
　Conoha VPS
　CPU:2コア
　メモリ:1G
　SSD:50G
　OS:　Ubuntu 18.04

クライアント：
  Windows10 Pro

デバイス：
　Raspberry Pi 3

# セットアップ
まずドキュメント( https://www.balena.io/open/docs/getting-started )にそって設定を行う。

## ドメインの設定
ドメインで以下のものをDNSに登録しないと動作しない。
　api.mydomain.com
　registry.mydomain.com
　vpn.mydomain.com
　s3.mydomain.com

mydomain.comは自分のドメインに合わせて変更すること。
動作させる前に必ず設定が行われていることを確認すること。（設定されていないと接続できずにエラーになる）
また、DNSの変更をしても反映に時間がかかるので、VPSのIPがわかっていたら先にやってしまうほうがよさげ。

注：後述するbalena-cliでsshでログインする場合はssh.devices.mydomain.comという登録も必要っぽい

## サーバサイドのセットアップ
VPSの管理コンソールで構築したのち、ログインして以下の設定を行っていく。
今回は面倒なのですべてrootで作業を行った。

### 必要なツールのセットアップ

~~~
# apt update && apt-get install -y build-essential git
~~~

### ユーザー[balena]の追加と必要な権限の付加

~~~
# adduser balena
# usermod -aG sudo balena
~~~

### Dockerのインストールとグループの変更

~~~
# apt install docker.io
# usermod -aG docker balena
~~~

### Docker composeのインストール

~~~
# curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
~~~

### OpenSSL/Node.js/npmのインストール

~~~
# apt install libssl-dev
# apt-get install nodejs
# apt-get install npm
~~~

### OpenBalenaのインストールと初期設定の実行

~~~
# git clone https://github.com/balena-io/open-balena.git ~/open-balena
# cd open-balena
# ./scripts/quickstart -U <email@address> -P <password> -d <mydomain.com>
~~~

ここで```<email@address>``` ```<password>```  ```<mydomain.com>```は自分のものに置き換えること。
quickstart.shを実行すると./config/cert以下に接続に必要な証明書などが生成される。

### Docker Imageの起動
Docker imageを起動させる。

~~~
./scripts/compose up -d
~~~

以上でサーバ側の設定はおしまい。
Docker Imageを停止させる場合は```./scripts/compose stop```を実行する


## クライアントの設定
管理するためにクライアント(balena-cli)をインストールする必要がある。ここではWindows環境での設定手順を記載する。

### インストール
Windows用のインストーラはここ( https://github.com/balena-io/balena-cli/releases )からダウンロードできる。
通常のインストーラパッケージならダウンロード後、実行すればOK。
他のOSについてはこちら( https://github.com/balena-io/balena-cli/blob/master/INSTALL.md )のドキュメントを参照のこと。

### 接続先の設定
balena cliは設定ファイルで接続先を切り替えることができる。Windows環境の場合、以下の内容を_balenarc.ymlというファイル名で環境変数%UserProfile%で指定されるディレクトリに保存する。


~~~.balenarc.yml
balenaUrl: "mydomain.com"
~~~

### ROOT証明書のインストール
サーバで作成された署名をクライアントPCにインストールする。
証明書は以下のパスに生成されている。

~~~
~/open-balena/config/certs/root/ca.crt
~~~

これをダウンロードし、以下のコマンドでインストールする。このとき、PowerShellは管理者権限で実行されている必要があることに注意。

~~~
certutil -addstore -f "ROOT" ca.crt
~~~

### ログインの確認
ここまでの設定が終わったら```balena login```を実行し、正常に接続できるか確認する。
ログイン方法を選択するメニューが表示されるので、[Credential]を選択し、サーバ設定で使ったemailアドレス、パスワードを入力する。
正しく設定ができていればログインが行われる。

間違っていた場合、証明書が正しくインストールされていない、ドメイン設定がおかしい、設定ファイルの記述、Docker Imageが起動しているか、などを確認してみる。

エラーの種類：SELF_SIGNED_CERT_IN_CHAIN:
対策：以下のように証明書を指定する。

~~~
$env:NODE_EXTRA_CA_CERTS = "c:\Users\[User]\ca.crt"
~~~

# アプリケーションのデプロイ
## アプリケーションの登録
管理するアプリケーションの登録を行う。``` balena login```でログイン後、``` balena app create myApp```を実行する。
(myAppは自分で好きな名前に置き換えること)
実行するとデバイスを選択するメニューが表示されるので、自分で使いたいデバイスを選ぶ。
（ここではラズパイ3を選択する）

実行後、```balena apps```コマンドを実行してアプリケーションが登録されているか確認する。
こんな感じで表示されればOK。

~~~
PS C:\dev\balena\simple-server-python\src> balena apps
ID APP NAME DEVICE TYPE     ONLINE DEVICES DEVICE COUNT
1  myApp    raspberrypi3-64 1              1
~~~

## OSイメージのダウンロードとコンフィギュレーション
まずデバイスのOSイメージを以下のURLからダウンロードする。
https://www.balena.io/os/#download

ダウンロードしたら以下のコマンドで設定を行う。

~~~
balena os configure [ダウンロードしたイメージファイル名] --app myApp
~~~
実行するとネットワークの設定などを聞かれるので、画面の指示に従って設定する。
ここでネットワークの設定を間違えると永遠につながらないので注意。

終わったらSDカードにイメージを書き込む。
書き込みがわたっらラズパイ3にSDカードをさし、電源をONにする。
正常に起動し、ネットワークの接続などに問題がなければ数分後にbalenaの管理コンソールに状態が表示される。
確認は```balena devices```で行える。

~~~
$ balena devices
ID UUID    DEVICE NAME     DEVICE TYPE  APPLICATION NAME STATUS IS ONLINE SUPERVISOR VERSION OS VERSION
4  59d7700 winter-tree     raspberrypi3 myApp            Idle   true      7.25.3             balenaOS 2.22.1+rev1
~~~

こんな感じで表示されたらOK

## アプリケーションのデプロイ
サンプルのプロジェクトをデプロイしてみる。
( https://github.com/balena-io-playground/sense-snake.git )

デプロイするには以下のコマンドを実行する。

~~~
git clone https://github.com/balena-io-playground/sense-snake.git
cd sense-snake
balena deploy myApp --logs --source . --emulated
~~~

実行するとDocker Imageが生成され、サーバに転送される。
完了するとこんな画面が表示される。

~~~
[Info]    Compose file detected
[Info]    Everything is up to date (use --build to force a rebuild)
[Info]    Creating release...
[Info]    Pushing images to registry...
[Info]    Saving release...
[Success] Deploy succeeded!
[Success] Release: f62a74c220b92949ec78761c74366046

			    \
			     \
			      \\
			       \\
			        >\/7
			    _.-(6'  \
			   (=___._/` \
			        )  \ |
			       /   / |
			      /    > /
			     j    < _\
			 _.-' :      ``.
			 \ r=._\        `.
			<`\\_  \         .`-.
			 \ r-7  `-. ._  ' .  `\
			  \`,      `-.`7  7)   )
			   \/         \|  \'  / `-._
			              ||    .'
			               \\  (
			                >\  >
			            ,.-' >.'
			           <.'_.''
			             <'
~~~

ちなみにハロウィンのときはユニコーンがカボチャになったらしい。

これでしばらくするとデバイスにDocker Imageがダウンロードされ、アプリケーションが実行される。


同じデバイスが複数ある場合、デプロイとかアップデートが超簡単になるので良いのだが、イメージ転送とかはいるので、
データ転送量がけっこう多いのでLTE回線とかだと大変なことになりそう。
使いどころは考えないといけない感じかと。