Raspberry PiでDockerコンテナを動かす

いまさらながら、Raspberry Pi 2を買ってみました。

しばらく、オフィシャルOSのRaspbianをインストールして遊んでいましたが、Raspbery Pi 2にDockerを導入してみたくなったのでやってみました。

以下では、Raspberry Pi 2をDocker導入済みのimageで起動し、hubotをDockerコンテナとして動かしてslackに接続してみます。

参考

概要

まず、Raspberry Pi 2におけるDocker利用可否については、[Raspberry Pi]ラズパイ2でDockerコンテナを実行する に詳しくまとめられています。

ポイントは以下のとおりです。

  • Hypriot Docker Imageを導入することで手軽にdockerを利用可能
  • しかし、armv7アーキテクチャのRaspberry Piでは一般的なx86_64のDockerイメージを利用できない

また、この記事が書かれた以降に、Hypriot Docker Image および、専用のDockerパッケージがアップデートされ、現状では、ラズパイ上で docker 1.8.0-rc3 を使うことができます。

Hypriot Docker Image でラズパイを起動する

イメージファイルをダウンロードし、microSDに書き込みます。

Hypriotのサイトの記事 Getting started with Docker on your Raspberry Pi に、Windows / OS X / Linux、それぞれの導入手順について詳しく書いてあります。

以下では、Mac OS X で実際に導入した手順を紹介します。

1. microSDのデバイス名を確認

まず、MacにmicroSDを挿入し、接続されているデバイス名を確認します(microSDはPNY製の64GBのものを使いました)

$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage                         250.1 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
...
(省略)
...
/dev/disk2
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *64.5 GB    disk2
   1:                 DOS_FAT_32 BOOT                    64.5 GB    disk2s1

microSDが/dev/disk2として認識されていることが分かります。

2. microSDをアンマウント

microSDにイメージを書き込むための準備として、microSDをアンマウントします。

$ diskutil unmountdisk /dev/disk2
Unmount of all volumes on disk2 was successful

アンマウントしてもmicroSDは挿したままにしておきます。

3. イメージのダウンロード

microSDに書き込むHypriot Docker Imageをダウンロードします。
最新は Version 0.5 (beta) となっていますが、手元では3回ほど試しましたがうまく起動しないため Version 0.4 をダウンロードして展開します。(COMMUNITYを見るとイメージを修正してるような書き込みがあるので、近日中に修正されそうです)

$ curl -O http://downloads.hypriot.com/hypriot-rpi-20150416-201537.img.zip
$ unzip hypriot-rpi-20150416-201537.img.zip

これで、ディレクトリに hypriot-rpi-20150416-201537.img が作成されます。

4. イメージの書き込み

展開したイメージをddコマンドで書き込みます。

ifに書き込むイメージファイル名を指定し、ofに書き込み先のmicroSDのデバイス名を指定します。
(注:指定するデバイス名のdiskの前にrを付けます /dev/disk2 なら /dev/rdisk2 )
bs=1mはイメージを書き込む際のブロックサイズを指定しています。

ofは、各自のデバイス名に読み替えて実行してください。

$ sudo dd if=hypriot-rpi-20150727-151455.img of=/dev/rdisk2 bs=1m

書き込みには結構時間がかかりました。書き込みが終わるまでターミナルの表示が変化しないため動いてるのか不安になりますが落ち着いて待ちます。自分の場合は10分ちょっとかかりました。

書き込みが終わったあとに再度microSDをアンマウントし取り外します。

5. 起動

イメージの書き込みが終わったら、ラズパイに挿して起動してださい。Hypriot Docker Image は、起動するとDHCPでIPアドレスを取得します。初期ユーザ名は root、パスワードは hypriot です。

キーボードとHDMIを接続して画面を見ながらログインしてもいいし、取得したIPアドレスを調べてSSHログインしてもよいです。

さっそくDockerをつかってみる

Hypriot Docker Imageを起動して、ログインできたら、さっそくDockerを使ってみます。

$ docker run -d -p 80:80 hypriot/rpi-busybox-httpd

ラズパイに振られたIPアドレスが192.168.1.20であれば、ブラウザからhttp://192.168.1.20:80/にアクセスするとこんな画面が見えます。

using-docker-on-raspberry-pi

簡単ですね!

ラズパイでhubotのコンテナを起動する

以降では、拙作ですが、ラズパイ上で動かすために調整したhubotをDockerfile含めて用意しましたので、これを使って解説します。
(x86_64環境では動作しないのでご注意ください)

1. ソースの取得

GitHubから knjcode/rpi-hubot-docker-template をクローンします。

$ git clone https://github.com/knjcode/rpi-hubot-docker-template
$ cd rpi-hubot-docker-template

2. Dockerのコンテナイメージをビルドする

ソースをクローンしたディレクトリにてイメージをビルドします。

$ docker build -t rpi-hubot .

このDockerイメージは hypriot/rpi-node を元にビルドします。
hypriotのみなさんは、OSのイメージだけでなく、node, iojs, python, java, golang等、様々な環境をarm用にビルドしてくれています。大変ありがたいですね。

3. ローカルで起動

まずは、ローカルでhubotを起動します。

$ docker run -i -t rpi-hubot

> rpi-hubot-docker-template@0.0.0 shell /hubot
> bin/hubot -a shell
[Tue Aug 11 2015 15:02:40 GMT+0000 (UTC)] INFO hubot-redis-brain: Using default redis on localhost:6379

hubot> hubot ping
hubot> PONG

無事に動きました。このイメージはコマンドなしで起動すると、shellアダプタを呼び出すようにしてあります。

4. hubotをslackに接続

次に、hubotを起動してslackに接続します。

まず、slackのhubot用トークンをHUBOT_SLACK_TOKEN環境変数に設定します。

$ export HUBOT_SLACK_TOKEN="your-hubot-slack-token"

次に、コンテナ起動時のコマンドとしてslackを指定すると、slackアダプタでhubotが起動します。

$ docker run -d --env HUBOT_SLACK_TOKEN rpi-hubot slack

無事slackに接続できました。

5. 外部からhubotへアクセス

外部からhubotにアクセスしたい場合には、EXPOSEされている8080ポートをホストの適当なポートに割り当ててください。

5000番ポートからhubotにアクセスしたい場合は以下のとおりです。

$ docker run -d --env HUBOT_SLACK_TOKEN -p 5000:8080 rpi-hubot slack

ちなみに、最近のhubotのslackアダプタはwebsocketでslackに接続するため、hubot自体に接続する必要がなければ、ホスト側にポートを割り当てなくても大丈夫です。

6. hubotの自動再起動

slack等の外部サービスに接続している場合に多いのですが、hubotとslack間の通信が一定時間途絶えるとhubotが落ちてしまいます。そんなときのためにコンテナの再起動オプションを指定しておきます。コンテナ停止時の挙動はdockerのrestartオプションで以下のように制御できます。

$ docker run -d --env HUBOT_SLACK_TOKEN --restart=always rpi-hubot slack

--restart=alwaysを指定すると、コンテナの終了コードを問わず再起動を試みます。

補足

その他、Hypriot Docker Image を使う際の補足です。

dockerのバージョンを上げる

今回導入したイメージには、初期状態で docker 1.6.0 が入っていましたが、
hypriotのwebサイトには、Raspi用にカスタムビルドしたdockerのパッケージがおいてあります。ここです

現在の最新はDocker 1.8.0-RC3で、以下のようにdpkgコマンドで導入して利用可能です。

$ curl -O http://downloads.hypriot.com/docker-hypriot_1.8.0-rc3-2_armhf.deb
$ dpkg -i docker-hypriot_1.8.0-rc3-2_armhf.deb

Logging driver に fluentd を使う

docker 1.8.0 からは、Logging driver に fluend が利用できるので便利です。

hubot起動時に以下のように指定すると、外部サーバに起動している fluend(192.168.1.10:24224)にログを送信できます。

$ docker run -d \
    --env HUBOT_SLACK_TOKEN \
    --log-driver=fluentd \
    --log-opt=fluentd-address=192.168.1.10:24224 \
    rpi-hubot slack

fluentd の Logging Driver については、Docker の Logging driver に fluentd が組み込まれるということでリリースを待ちきれずに試してみたメモ にて細かく解説されています。

dockerのラッパーツールの fugu を使う

mattes/fugu

fuguというdockerのラッパーツールを日頃便利に使っています。docker-composeは複数コンテナを管理するような用途に、fuguはコンテナ単体での利用に向いています。使い方もdocker-composeと同様ですが、fugu.ymlにdockerコマンドのオプションと似たような内容を書いて使います。

fuguはlog-driverオプションに対応していなかったのですが、fluentdのLogging Driverを使いたかったので実装してプルリクを出したところマージしてもらえました。

また、fuguはgoで実装されているので、armv7用にコンパイルすることでラズパイ上でも使えます。

自前でコンパイルしたものをこちらに置いてますので、よかったら使ってください。

以下のように、ラズパイに導入できます。

$ curl -O http://test.guit.net/fugu.v1.1.1.linux.armv7.tar.gz
$ tar xvf fugu.v1.1.1.linux.armv7.tar.gz
$ cp fugu.v1.1.1.linux.armv7 /usr/local/bin/fugu
$ chown root:root /usr/local/bin/fugu

おわりに

ARMアーキテクチャということで、大量にあるx86_64のDockerイメージが使えないというデメリットはありますが、hypriotのラズパイ用イメージを使うだけでも色々と遊べそうです。

まだ、4日ほどしか運用していませんが、hubotについては問題なく動いているように感じます。今後、hubotとラズパイ用の各種センサとを組み合わせてみるのも面白そうです。

また、あまり重いアプリでなければ、ラズパイにコンテナとして起動しておけば、低消費電力で場所も取らず便利です。Node.js以外にも、いろいろと使ってみて、ノウハウがたまれば共有しようと思います。

スポンサーリンク
レクタングル(大)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
レクタングル(大)