Raspberry Piで「簡単に」コンテナ!(Raspberry PiでRunC)


 
Raspberry Piでコンテナを動かしたい!
と思うことが最近よくあります.
普段サーバではコンテナでアプリをデプロイしてるのでベアメタルに直接いろいろアプリを入れるのやだなーと.
でもRaspberry PiでDockerって結構面倒なんですよね.それ専用のイメージにしたり...
そもそもDockerのイメージ管理とかあればいいけど必須ではない.
aufsとか使うとSDカードだとパフォーマンスめっちゃ落ちる...

というわけでRunC(https://runc.io/)が使えないかなと.
これなら普通のRaspbianですぐ使えるし,パフォーマンスの劣化も少なそう(未確認)
早速やってみました.

準備

Go言語インストール
こことか参考にGo langをraspbianにインストール!

$ sudo apt-get install -y mercurial gcc libc6-dev
$ hg clone https://code.google.com/p/go/ $HOME/go
$ cd $HOME/go/src  
$ ./make.bash

うむうむ
ただこれだと$HOME以下にGoのバイナリが入っちゃうので(別にいいなら良し)Goのバイナリを/usr/local以下に移動
$GOPATHになるディレクトリを作成

$ sudo mv $HOME/go /usr/local
$ mkdir $HOME/go

でGoに関わる環境変数を~/.bashrcに追加

export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin
export GOROOT=/usr/local/go
export GOPATH=$HOME/go

を追記

$ go version

でちゃんとGoのバージョンが表示されればOK

RunCビルド

次にRunCをビルドします.
go getで普通に取ってこれます

$ go get github.com/opencontainers/runc

多分エラーが出ますが無視して改めてビルドします.

$ cd go/src/github.com/opencontainers/runc/
$ make BUILDTAGS=""
$ sudo make install

ここでBUILDTAGS=""を指定しておかないとエラーになります.
Raspbianがseccompに未対応だからだそうです.

これでrunc -vとかするとRunCのバージョンが表示されるはずです.

コンテナのファイルシステム作成

これでRunCがインストールされました.
一応すぐにもコンテナは作成可能なのですが,先に言ったようにRunCはアプリ実行環境のパッケージング機能がないので実行環境を別途用意して上げる必要があります.
それもarm用の(!)
ああ面倒くさい.これがネックでした.いっそraspbianのシステムファイル全部コピーでもしようかなと...

ですがよく考えるとarmアーキテクチャのVMを作ったりする必要すらありませんでした.
方法は至極簡単.普通のx86アーキテクチャのDockerホストでraspi用のDockerイメージをpullしてexportするだけ.
boot2dockerでもなんでも使いましょう.

*x86 Dockerホスト上
$ docker pull sdhibit/rpi-raspbian
$ docker run --name=rsptest sdhibit/rpi-raspbian /bin/bash

ちなみにraspi用のイメージが慣習的に頭にrpi-がついています.
当然x86では実行できないと起こられますが,気にせず

*x86 Dockerホスト上
$ docker export rsptest > raspbian.tar

でraspbian.tarにイメージのファイルシステムをexportします.
これでarm用のraspbianのファイルシステムがtarで固められた状態で手にはいります.
もちろん他のDockerイメージ(Raspberry Pi用)でもOK.
このraspbian.tarを先ほどRunCを入れたraspberry piに送って,rootfsというディレクトリに展開します.

$ mkdir ~/rpi-raspbian
$ mkdir ~/rpi-raspbian/rootfs
$ sudo tar xvf raspbian.tar -C ~/rpi-raspbian/rootfs

そしてrootfsと同階層にRunCのコンフィグファイルを生成します.

$ sudo runc spec
$ ls
config.json  rootfs  runtime.json

ここで注意.今回RunCのビルド時にseccompを無効化していますのでconfigファイルでもその設定を行う必要があります.
210行目付近の

 "seccomp": {
     "defaultAction": "SCMP_ACT_ALLOW",
     "architectures": null,
     "syscalls": []
 },

を削除します.
これで

sudo runc start

とするとコンテナが立ち上がりまっさらなraspbianが立ち上がります.
ただip linkとかするとわかりますがこのままではネットワークネームスペースも分離されていますので,ほとんど何もできません...
今回私はファイルシステムだけ分離されていればよかったのでネットワークネームスペースは分離させないようconfig.jsonを変更します.
runtime.jsonの130行目付近の

"type": "network",
    "path": ""
},

を削除します.ちなみにその付近のpidやらがそれぞれのネームスペースなので隔離しないものを削除してください.
あとconfig.jsonの最後に

                "capabilities": [
                        "CAP_NET_RAW",
                        "CAP_NET_BIND_SERVICE",
                        "CAP_AUDIT_WRITE",
                        "CAP_DAC_OVERRIDE",
                        "CAP_SETFCAP",
                        "CAP_SETPCAP",
                        "CAP_SETGID",
                        "CAP_SETUID",
                        "CAP_MKNOD",
                        "CAP_CHOWN",
                        "CAP_FOWNER",
                        "CAP_FSETID",
                        "CAP_KILL",
                        "CAP_SYS_CHROOT",
                        "CAP_NET_BROADCAST",
                        "CAP_SYS_MODULE",
                        "CAP_SYS_RAWIO",
                        "CAP_SYS_RAWIO",
                        "CAP_SYS_ADMIN",
                        "CAP_SYS_NICE",
                        "CAP_SYS_RESOURCE",
                        "CAP_SYS_TIME",
                        "CAP_SYS_TTY_CONFIG",
                        "CAP_AUDIT_CONTROL",
                        "CAP_MAC_OVERRIDE",
                        "CAP_MAC_ADMIN",
                        "CAP_NET_ADMIN",
                        "CAP_SYSLOG",
                        "CAP_DAC_READ_SEARCH",
                        "CAP_LINUX_IMMUTABLE",
                        "CAP_IPC_LOCK",
                        "CAP_IPC_OWNER",
                        "CAP_SYS_PTRACE",
                        "CAP_SYS_BOOT",
                        "CAP_LEASE",
                        "CAP_WAKE_ALARM"
                ]

とか書いとけばDockerで言うところのprivilegeになります.
Dockerが簡単に動けばそっちの方が楽かもしれませんが軽量な分raspiなんかには調度良いかなと思います!

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中