[Raspberry Pi]ラズパイ2でDockerコンテナを実行する

2015.02.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、大瀧です。
先日発売されましたRaspberry Pi 2 Model B、Dev.IOでも早速セットアップ記事が公開されましたが、皆さん触ってますか?
初回ロットが即完売になるかと思ったのですが、秋葉原の店頭在庫はまだちらほら見かけますので気になる方はゲットしましょう!どうでもいい話ですが、RS Components版よりもelement14版の方がパッケージが可愛かったので個人的にはちょっと後悔しています *1

rpi2

さて、手に入ったらいろいろ試したくなるのが人情というもので、Dockerコンテナを実行できないか調べてみたのでレポートします。

Dockerは動くのか

結論から言うと動きます。が、実用的ではないです。それは、DockerコンテナはDockerホストと同じCPUアーキテクチャでないと動作しないからです。

Dockerはホストと同じカーネルを利用するコンテナ仮想化ですので、Dockerホストと同じカーネル前提のバイナリ/ライブラリを備える必要があります。現在Docker Hubで公開されているほとんどのDockerイメージはx86_64アーキテクチャのため、Raspberry Piのarmv7lアーキテクチャ上でx86_64のコンテナを実行することはできません。armv7lアーキテクチャのDockerイメージはかなり少ないという状況です。

ただ、armv7lアーキテクチャベースのDockerイメージを用意すれば良いという話なので、自分で1からビルドする場合は気にする必要はありませんし、今後広く使われるようになれば困ることも無くなるかもしれませんので、まずはベースとなるディストリビューションの公式イメージの登場が待たれます。ちなみに、有志が作成したRaspberry Pi向けのDockerイメージはrpi-から始まるイメージ名にするのが慣例のようですので、Docker Hubで検索してみるといくつかひっかかることがわかるでしょう。

また、Raspberry PiのブートデバイスはMicro SD Cardを用いるのが一般的ですが、SD Cardは書き込み回数の上限があるため、コンテナ操作による書き込み数が気になるところです。/var/lib/dockerをUSB外付けHDD/SSDなどでマウントすると良いかもしれません。

Dockerコンテナを動かしてみた

動作確認環境

「Raspberry Pi Docker」などで検索してみると、いくつか動作報告のブログ記事がひっかかると思いますが、今回は最も簡単に試せる方法でやってみました。以下のブログ記事の手順に沿った通りです。

この記事では、Raspbian Weezyをベースに最近DockerがサポートしたOverlayFSとそれを実行するためのLinuxカーネル3.18にすげ替えたカスタムイメージを公開しているので、今回はこのカスタムイメージを用いた手順をご紹介します。

イメージのダウンロードとSD Cardへの書き込み

上記ページにある「Docker-Pi-Image」のリンクからディスクイメージをダウンロードしZipを展開して生成されるhypriot-rpi-20150208-015447.imgがイメージファイルです。カードリーダーにSD Cardを設置し以下の通りSD Cardに書き込みます。

あらかじめディスクユーティリティーの[情報]から「ディスク識別子」をメモしておき、以下のddコマンドの書き込みデバイス名(/dev/diskX)を置き換えてください。

rpi2-01

SD Cardの性能にも依りますが4〜5分かかります。

$ sudo dd if=hypriot-rpi-20150208-015447.img of=/dev/diskX
2000000+0 records in
2000000+0 records out
1024000000 bytes transferred in 717.827972 secs (1426526 bytes/sec)
$

書き込みが完了したら、ディスクユーティリティーからデバイスを右クリック、[ディスクを取り外す]を選択してSD Cardを取り外します。

Raspberry Piの起動

SD Cardスロットは裏側にあるので差し込みます。バネ構造になっているので、差し込んで少し戻ってくる感じで設置完了です。HDMIでディスプレイに接続、任意のUSBポートにキーボードを設置します。このイメージは起動時にDHCPサーバーにリクエストを創出するので、RJ45にLANケーブルを接続するのも忘れないようにしましょう。準備ができたら、向かって左下のmicro USBにUSB電源を接続して起動します。

rpi3

初回起動でパーティション拡張が実行され、自動で再起動します。しばらく様子を見ましょう。

ログインプロンプトが表示されたら、ログインします。初期ユーザー名はroot、パスワードはhypriotです。既定でPermitRootLogin=Yesでsshdが起動するので、今回はSSHで接続します。

$ ssh root@192.168.2.2
root@192.168.2.2's password:
Linux hypriot-pi 3.18.6-v7+ #2 SMP PREEMPT Sun Feb 8 00:55:10 UTC 2015 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Feb 11 07:03:38 2015 from 192.168.2.1
root@hypriot-pi:~#

ログインできました!

Dockerコンテナの操作

本イメージには既にDockerがインストール済みなので、その辺りを見てみます。

root@hypriot-pi:~# docker version
Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8-dirty
OS/Arch (client): linux/arm
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8-dirty
root@hypriot-pi:~# docker info
Containers: 3
Images: 7
Storage Driver: overlay
Execution Driver: native-0.2
Kernel Version: 3.18.6-v7+
Operating System: Raspbian GNU/Linux 7 (wheezy)
CPUs: 4
Total Memory: 925.2 MiB
Name: hypriot-pi
ID: N6YP:P23S:5MTG:K643:2OWE:SFK7:VGYT:6MRJ:TJPG:IQ6S:VZZO:Z4OB
Debug mode (server): true
Debug mode (client): false
Fds: 10
Goroutines: 10
EventsListeners: 0
Init SHA1: 93273764da162083337ffe38cbd8f1e5b54fe673
Init Path: /usr/lib/docker/dockerinit
Docker Root Dir: /var/lib/docker
root@hypriot-pi:~#

Docker 1.4.1がStorage Driver: overlayで動作していることがわかりますね。では、DockerイメージをPullし、実行してみます。今回はお試しでDocker Hubで公開されているRaspbianイメージを利用します。

root@hypriot-pi:~# docker pull perlan/rpi-raspbian
Pulling repository perlan/rpi-raspbian
cefe36af75d8: Download complete
511136ea3c5a: Download complete
30598dc9156c: Download complete
Status: Downloaded newer image for perlan/rpi-raspbian:latest
root@hypriot-pi:~# docker run -ti perlan/rpi-raspbian
root@70d69136acf8:/# ls
bin  boot  dev	etc  home  lib	media  mnt  opt  proc  root  run  sbin	selinux  srv  sys  tmp	usr  var
root@70d69136acf8:/# exit
exit
root@hypriot-pi:~#

動きました!操作自体はPCやサーバーの場合と変わりなく、キビキビ動いてくれている印象です。なお、別の遅いmicro SD (Class 4 4GB)で同様の操作をしたところdocker runコマンドの実行に数秒かかったので、Class 10以上のmicro SDを使っていただくことをおすすめします。
ついでに、無理とは知りつつ怖いもの見たさに、Dockerオフィシャルのubuntu:latest(x86_64)も試してみます。

root@hypriot-pi:~# docker pull ubuntu:latest
ubuntu:latest: The image you are pulling has been verified
27d47432a69b: Pull complete
5f92234dcf1e: Pull complete
51a9c7c1f8bb: Pull complete
5ba9dab47459: Pull complete
511136ea3c5a: Already exists
Status: Downloaded newer image for ubuntu:latest
root@hypriot-pi:~# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
perlan/rpi-raspbian   latest              cefe36af75d8        2 days ago          86.39 MB
perlan/rpi-raspbian   wheezy              cefe36af75d8        2 days ago          86.39 MB
ubuntu                latest              5ba9dab47459        13 days ago         192.7 MB
root@hypriot-pi:~# docker run -ti ubuntu
exec format errorFATA[0001] Error response from daemon: Cannot start container 963be7469f14e9e4de38c744f4247e1fe08137d515bce722f2311621f2f0450d: exec format error
root@hypriot-pi:~#

やっぱりダメでした。

まとめ

Raspberry Pi 2 Model BでDockerを実行する様子をご紹介しました。低消費電力で安価なRaspberry Piも、2になってパワーアップしDockerの実行も耐えうるスペックになっていると思います。開発環境と本番環境でのDockerイメージの共通化がDockerのメリットだと思うので、ARMな開発環境が出てくることがあれば便利かもしれませんね!(無いかも

ちなみに、今回利用したカスタムイメージは以下のスレッドによると今後ビルドスクリプトが公開されるようなので、それを使ってさらにカスタムして使うのも良いかもしれません。

脚注

  1. RS版は秋月、el14版は千石1号店2Fで見かけました。