aobench
runc

runC で aobench を動かす

More than 2 years have passed since last update.

漢なら runC で aobench を動かしたいですよね!

Requirements

Ubuntu 14.04 or later や, CoreOS, docker-machine で作られるコンテナ対応済みイメージを使うのがオススメです.

runC では checkpoint 機能を使う場合, checkpoint 対応 Linux カーネルと CRIU が必要になります.

また, 最近では runC に seccomp がデフォルトで有効になりましたが, CRIU 側の seccomp 対応が未だである(CRIU 1.7 時点)ですので, checkpoint 機能を使う場合は seccomp 無効で runC をビルドする必要があります.

Build

docker-machine の google ドライバでコンテナ対応済み linux イメージを立てていると仮定します.

まず runC をビルドします. 参考となる Dockerfile は以下の通りです.

$ cat Dockerfile

FROM ubuntu:14.04
MAINTAINER syoyo@lighttransport.com

ENV HOME /root
ENV GOPATH /root/go
ENV PATH /root/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

RUN apt-get update
RUN apt-get install -y build-essential git wget curl
RUN apt-get install -y libseccomp-dev seccomp

RUN mkdir -p $GOPATH

RUN wget -qO- https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz | tar -C /usr/local -xzf -

# Build runc
RUN mkdir $GOPATH/src
RUN mkdir $GOPATH/src/github.com
RUN mkdir $GOPATH/src/github.com/opencontainers

# Workaround for invalidate cache for git clone.
ADD dummyfile /data/

RUN cd $GOPATH/src/github.com/opencontainers; git clone https://github.com/opencontainers/runc

# seccomp を無効にする場合は make BUILDTAG="" とする.
RUN cd $GOPATH/src/github.com/opencontainers/runc; make
RUN cd $GOPATH/src/github.com/opencontainers/runc; make install

runC 用 aobench イメージを作る.

すでに aobench イメージが Docker registory にありますので取得し, tar 形式に変換します.

$ sudo docker pull syoyo/aobench 
$ sudo docker export $(sudo docker create syoyo/aobench) > aobench.tar
$ tar -c aobench_dist -xf aobench.tar
$ runc spec  # runc を実行するディレクトリは aobench_dist ディレクトリではない

config.json を編集し, rootfs のパスを aobench_dist に変更, process/args/bin/ao にします.

runC で実行する.

config.json のあるディレクトリで runc start します.

$ sudo runc start
ao: ao.c:321: saveppm: Assertion `fp' failed. 

おおっと! ファイルシステムへの書き込みで失敗してしまいました...

config.jsonroot/readonlytrue になっているのが原因そうです. とりあえず false に変えてみます.

$ sudo runc start
ao: ao.c:321: saveppm: Assertion `fp' failed. 

ぐぬぬ... ルートファイルシステムは readonly = false でもダメのようです...
(runtime.json では mounts/cgroupsro フラグが付いているからでしょうか)

適当に tmpfs を作りマウントするようにします.

runtime.jsontmpfs マウントの情報を mounts に追加します.

{
        "mounts": {
                "cgroup": {
                        "type": "cgroup",
                        "source": "cgroup",
                        "options": [
                                "nosuid",
                                "noexec",
                                "nodev",
                                "relatime",
                                "ro"
                        ]
                },
                ...
                "tmpfs": {
                        "type": "tmpfs",
                        "source": "tmpfs",
                        "options": [
                                "nosuid",
                                "noexec",
                                "nodev",
                                "mode=1777",
                                "size=65536k"
                        ]
                },

config.json/tmp のマウント情報を記載します. また, CWD を /tmp に設定して, /tmp/bin/ao を実行するようにします.

        "process": {
                ...
                "args": [
                        "/bin/ao"
                ],
                "cwd": "/tmp"
        },

        "mounts": [
                {
                        "name": "proc",
                        "path": "/proc"
                },
                ...
                {
                        "name": "tmpfs",
                        "path": "/tmp"
                },

再度実行します.

$ sudo runc start
Output ao.ppm

Voila! runC で aobench が動きました!

プロセスの pause/resume を試す.

pause, resume でプロセスの中断と再開を行うことができます.

$ sudo runc start
$ sudo runc pause

# 別のターミナルを開く
$ sudo runc resume

Cool!

pause すると, top で見ると計算がストップしているのが確認できます.

Checkpointing を試す.

Checkpoint 機能を使うことで, プロセスの状態をファイルにダンプし, 別のマシンに転送してリストアすることでプロセスのマイグレーションができます.

Checkpoint 機能を使うには, システムに CRIU http://criu.org/Main_Page がインストールされている必要があります. 今回は CRIU 1.7 で確認しました.

config.json にて,

  • process/terminal = false
  • root/readonly = false

を設定しておく必要があります.

$ sudo runc start
$ sudo runc checkpoint # 別ターミナル
criu failed: type DUMP errno 0
log file: /run/opencontainer/containers/tmp/criu.work/dump.log

ぐぬぬ... dump に失敗してしまいました.

https://github.com/xemul/criu/issues/25

seccomp 対応の runC では, CRIU 側がまだ対応できていないのが原因でした.
とりあえず runC を seccomp 無効でビルドしてみます(runc の Makefile で BUILDTAG を編集する). また, runtime.json での seccomp セクションを削除しておきます.

seccomp 無効の runC で再度実行してみます.

$ sudo runc start
$ sudo runc checkpoint # 別ターミナル
# checkpoint/ ディレクトリにプロセスのダンプが書かれます.
$ sudo runc restore

Voila! プロセスのチェックポイント実行に成功しました!

To be continued...

TODO

  • aobench の結果ファイルの回収(ネットワーク or stdout に流す?)
  • checkpoint を異なるマシン間で試す.