CRIUを使ってDockerのsnapshotを取る

スポンサード リンク

CRIU はプロセスのスナップショットを取れるツールであり, これを使えばDockerのコンテナのスナップショットも取れるという。

スナップショット機能を使えば起動後のコンテナの状態をイメージ化して保存できるため, コンテナの起動時間短縮や,ライブマイグレーションに役立つ。

この記事では CRIU を統合した開発版Dockerをコンパイルして docker snapshot サブコマンドを使えるようにすることを目指す。 現時点では成功していないが,近いところまでは来ている。

環境

Amazon EC2 Ubuntu Server 14.04 LTS Kernel 3.11

CRIUのインストール

Ubuntu 14.04(trusty)ではapt-getでcriuをインストールできない。 そこでソースからコンパイルする。 ちなみに,Ubuntu 16.04(xenial)ならapt-getでcriuをインストールでるので,xenialを使うほうが楽。

まずはCRIUが必要とする機能を有効にして,カーネルを再コンパイルする。 詳細は下記サイトを参照すること。 CRIUを使ってDockerコンテナの停止/再開に挑戦 | kim hirokuni

sudo -s
apt-get -y install libncurses-dev build-essential libncurses-dev build-essential fakeroot kernel-package linux-source bc libssl-dev
cd /usr/src/linux-source-<kernel version>
tar xvjf linux-source-<kernel version>.tar.bz2
cd ./linux-source-<kernel version>
curl https://gist.githubusercontent.com/kimh/c93f42981d14a33c63c0/raw/a73af0f7f745c2538253ef153a62a8ba1a2d97be/.config -o .config
export LC_CTYPE=C
make-kpkg clean
CONCURRENCY_LEVEL=4 make-kpkg --rootcmd fakeroot --initrd --revision=`date +%Y%m%d` kernel_image kernel_headers
cd ../
dpkg -i linux-headers-<kernel version>_amd64.deb
dpkg -i linux-image-<kernel version>_amd64.deb
reboot

CRIUをコンパイルしてインストールする。

curl http://download.openvz.org/criu/criu-2.4.tar.bz2 | tar -jxf-
cd criu
sudo apt-get install -y bsdmainutils build-essential linux-headers-generic libprotobuf-dev libprotobuf-c0-dev protobuf-c-compiler protobuf-compiler python-protobuf libnl-3-dev libcap-dev asciidoc
make
sudo make install

CRIUの動作確認

criuには動作確認用にcheckサブコマンドがある。

sudo criu check --all

checkすると以下のように細かいエラーは出るが,Looks good と表示されれば動作には十分である。

Info  prctl: PR_SET_MM_MAP_SIZE is not supported
Warn  (cr-check.c:227): prctl: PR_SET_MM_MAP_SIZE is not supported
Error (cr-check.c:640): Kernel doesn't support PTRACE_O_SUSPEND_SECCOMP
Error (cr-check.c:684): Dumping seccomp filters not supported: Input/output error
Error (timerfd.c:52): timerfd: No timerfd support for c/r: Inappropriate ioctl for device
Error (cr-check.c:318): fdinfo doesn't contain the mnt_id field
Error (cr-check.c:782): AIO remap doesn't work properly: Invalid argument
Error (cr-check.c:795): fdinfo doesn't contain the lock field
Error (cr-check.c:913): cgroupns not supported. This is not fatal.
Error (cr-check.c:846): autofs not supported.
Looks good but some kernel features are missing
which, depending on your process tree, may cause
dump or restore failure.

試しに適当なプロセスのsnapshot作成とrestoreを行ってみる。 まずは適当にカウントアップするシェルスクリプトを作成する。

mkdir -p ~/tmp/test
cd ~/tmp/test
echo 'for i in `seq 1 1000` ; do echo $i ; sleep 1s ; done ' > test.sh
bash test.sh

snapshotを作成する。lsしてみるといろいろなファイルが作成されていることがわかる。

export PID=`pgrep -f for`
sudo criu dump -t $PID --images-dir ~/tmp/test --shell-job
ls

作成したsnapshotから再開してみる。 先ほど中断した値からカウントアップが始まれば成功だ。

sudo criu restore -t $PID --images-dir ~/tmp/test  --shell-job

dockerのインストール

開発版Dockerはコンテナ内でコンパイルするようになっている。 まずはコンパイル用にDockerをインストールする。

sudo wget -qO- https://get.docker.com/ | sh
sudo usermod -aG docker ubuntu

開発版Dockerのコンパイル

開発版Dockerをgithubからダウンロードしてコンパイルする。 docker-checkpoint-restore ブランチがCRIUの統合されたコードである。

sudo apt-get install git make golang lvm2 -y
git clone https://github.com/boucher/docker.git
cd docker
git checkout docker-checkpoint-restore
sed -i 's/DOCKER_EXPERIMENTAL/DOCKER_EXPERIMENTAL=1/' Makefile
make all
sudo make install

開発版Dockerのインストール

export AUTO_GOPATH=1
sudo -E make install

Docker snapshotの動作確認

dockerのdaemonを起動する。 devicemapperが動作しない場合は,aufsを使う。

sudo service docker stop
sudo /usr/local/bin/dockerd -s aufs

違うシェルでコンテナを実行する。

docker run --security-opt seccomp:unconfined --name counter ubuntu:14.04 /bin/bash -c 'for i in `seq 0 10000`; do echo $i ; sleep 1 ; done'

違うシェルでスナップショットの作成と起動を試す。 私の環境では criu のエラーでcheckpointの作成がうまくいかない。 解決できたら追記する。

docker checkpoint create counter counter_checkpoint
docker start --checkpoint counter_checkpoint counter2
docker attach counter2

Comments !

social