あけおめ!
去年やってブログに書き忘れたことをほそぼそ書くシリーズ。
- mrubyのプロジェクトでCIでビルド・テストを回したい
- バイナリを作成するツールなので、バイナリのリリースも自動でやりたい
こういう時の設定例です。
続きを読むあけおめ!
去年やってブログに書き忘れたことをほそぼそ書くシリーズ。
こういう時の設定例です。
続きを読むLinux Advent Calendar 2019 12日目の記事です。
今日はCRIUに関わる自作ツールの話をします。
Checkpoint and Restore In Userspace の略で、プロセス(や特殊なプロセスであるところのコンテナ)の動いているメモリ状態などをイメージにダンプし、またそのイメージからのリストア起動を実現するLinux向けのツールです。
詳細は、 TenForward さんの記事が詳しいです。
任意の状態のプロセスのセーブポイントや、 kvm などでいうライブマイグレーションのような用途での利用を想定しているようです。
で、この技術、やれることはとても魅力的なのですが、使い方がかなり難しいことでも有名です。
雑にプロセスを立ち上げてそのPIDをダンプしようとしてもエラーが出たり、
$ sudo criu dump -t 25010 Warn (compel/arch/x86/src/lib/infect.c:280): Will restore 25011 with interrupted system call Warn (compel/arch/x86/src/lib/infect.c:280): Will restore 25018 with interrupted system call Error (criu/tty.c:1859): tty: Found dangling tty with sid 5228 pgid 25010 (pts) on peer fd 0. Task attached to shell terminal. Consider using --shell-job option. More details on http://criu.org/Simple_loop Error (criu/cr-dump.c:1743): Dumping FAILED.
言われた通り --shell-job
をつけてもリストアでまたエラー。
$ sudo criu dump -t 25010 --shell-job Warn (compel/arch/x86/src/lib/infect.c:280): Will restore 25011 with interrupted system call Warn (compel/arch/x86/src/lib/infect.c:280): Will restore 25018 with interrupted system call $ sudo criu restore 25058: Error (criu/tty.c:412): tty: Found slave peer index 1 without correspond master peer Error (criu/cr-restore.c:1457): 25058 killed by signal 9: Killed Error (criu/cr-restore.c:2333): Restoring FAILED. $ sudo criu restore --shell-job pie: 25058: Error (criu/pie/restorer.c:1811): Unable to create a thread: 25060 pie: 25058: Error (criu/pie/restorer.c:1951): Restorer fail 25058 Error (criu/cr-restore.c:1454): 25058 exited, status=1 Error (criu/cr-restore.c:2333): Restoring FAILED.
エラーも見慣れないもので何もわからん...。ちなみに、ホストのプロセスをダンプする場合、 PID含めて リストアしようとするため、そのPIDがすでに別のプロセスに取られていた場合そもそもリストアができない(回避方法はないようです...)などの問題もあります。
また、 images-dir
などの必要な設定など、いろいろな規約を自分で決めたり、ちょっと触りたいだけではなかなか面倒な印象を持つかもしれません。
やりたいことは普通にプロセスの状態のスナップショットをとって、戻したりしたいだけなのに...。
LXD のような場合は実は標準の checkpoint
コマンドを経由することもできますが、「普通にVMで立ち上げてるアプリやプロセス」の場合は周辺の準備が面倒そうですよね。CRIUは基本的に非常にレイヤの低いオプションやAPIを提供するので、現実の用途のためには色々とラップする必要が出てきます。
ということで、普通のプロセス向けに、こういうツールを書いています。
続きを読むこの記事はCfP Advent Calendar 2019の9日目です!
1日勘違いしていました!
カンファレンスではないですが「Rubyアソシエーション 開発助成金2019」への応募内容をここで公開します。って、していいものなのでしょうか...「アウトプットを期待」とのことだったのできっと大丈夫!
現在、YARV開発者の笹田耕一さんをメンターに迎えて、RubyでLinuxの高機能トレス技術 eBPF のライブラリである BCC を使えるようにすべく移植実装と、+アルファの考え中です。それが RbBCC プロジェクトです。
将来は iovisor プロジェクトに寄贈したいと考えてもいるんですが、まずは完成度を上げねばという感じです...。
で、このRubyアソシエーション 開発助成、毎年なかなか募集に苦労している印象があり、一つはどういう感じで出せばいいかという情報が少ないのはあるのかな〜と思っております。次回の応募数増に寄与すべく、一番肝であろう「プロジェクトの詳細」の応募時の内容をここに公開します。
続きを読むPepabo Adovent Calender 3日目の記事です。
@udzura です。こないだDuolingoの話をガッツリしてしまったせいで記事に書くネタがなかったんですが、某ruby-jpで話題に出て気になったので当該の内容について調べてみました。
これで妥当な結果が出ているかどうか、適切なやり方かどうかのツッコミをお待ちしております...。
strace は -c オプションのみだとsystem時間のみなので、ファイルシステム操作の全体の時間を計測するには -w オプションが必要だというご指摘がありました!
全体に初稿と比べて計測しなおしています。
FROM debian:10-slim RUN apt install curl strace rsync gnupg2 ruby ruby-dev \ libxml2-dev libxslt-dev zlib1g-dev libsqlite3-dev nodejs && \ gem install bundler && \ ( curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - ) && \ ( echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list ) && \ apt update && \ apt install yarn ENV RAILS_ENV production
こういう感じのDockerfileを作成します。
以下のようにホストの一部を bind mount した上で、 /app1
/app2
それぞれに全く同じRailsのアプリを構築します。今回は、 rails 6.0.1 で rails new
したばかりのものを用意します。
docker run --privileged -ti -v /home/vagrant/app1:/app1 udzura/pepabo-calender-sample bash
こうすると、 /app1
はホストと同じ ext4 ファイルシステム、 /app2
は overlay ファイルシステム、他の条件は同じ環境が作れます。
root@0a78c58c2694:/# stat -f /app1 File: "/app1" ID: ac226b50631a0a89 Namelen: 255 Type: ext2/ext3 # と表示されてしまう ... root@0a78c58c2694:/# mount | grep /app1 /dev/sda1 on /app1 type ext4 (rw,relatime) root@0a78c58c2694:/# stat -f /app2 File: "/app2" ID: ac226b50631a0a89 Namelen: 255 Type: overlayfs ...
また、gem類はbundler経由で /app$N/vendor/bundle
にインストールし同じファイルシステムに存在させます。
事前に、ホスト側のdenrty/inodeキャッシュをすべて破棄します。
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
その上でコンテナ側で以下のコマンドをそれぞれ実施し、 rails runner を起動させ単純な処理を行わせます。
追記: これ以降、初稿と比べて strace の結果はすべて -w
オプションを追加して更新しています。
( cd /app1; strace -cfw bin/rails runner 'puts Rails::VERSION::STRING' ) ( cd /app2; strace -cfw bin/rails runner 'puts Rails::VERSION::STRING' )
まず生のstraceの結果を以下に貼ります。
ただ、このままだとタイマースレッドの内部で使われている(ですよね?) poll(2)
が支配的なので、ファイルシステムの操作系システムコールに絞ってもう一度測ります。
( cd /app1; strace -cfw -eopen,openat,read,write,close,stat,lstat,access,fstat,fcntl,ioctl,getdents64 bin/rails runner 'puts Rails::VERSION::STRING' ) ( cd /app2; strace -cfw -eopen,openat,read,write,close,stat,lstat,access,fstat,fcntl,ioctl,getdents64 bin/rails runner 'puts Rails::VERSION::STRING' )
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 32.17 1.287973 50 25462 160 lstat 29.44 1.178614 248 4738 4 read 17.74 0.710357 121 5833 1680 openat 5.24 0.209720 50 4157 close 4.76 0.190622 47 4000 fstat 4.68 0.187523 75 2490 350 stat 2.34 0.093868 45 2046 fcntl 2.27 0.090997 44 2030 2026 ioctl 1.34 0.053530 125 428 getdents64 0.01 0.000211 52 4 2 access 0.00 0.000142 47 3 write ------ ----------- ----------- --------- --------- ---------------- 100.00 4.003556 51191 4222 total
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 35.27 1.525725 59 25462 160 lstat 26.56 1.149017 242 4735 2 read 16.55 0.716034 122 5833 1680 openat 5.48 0.237068 57 4157 close 5.31 0.229482 57 4000 fstat 4.54 0.196336 78 2490 350 stat 2.50 0.108297 53 2030 2026 ioctl 2.49 0.107764 52 2046 fcntl 1.29 0.055666 130 428 getdents64 0.01 0.000225 56 4 2 access 0.00 0.000084 83 1 write ------ ----------- ----------- --------- --------- ---------------- 100.00 4.325698 51186 4220 total
次が、lstat,openat,read,getdents64(12/4 追記)に絞った 50回 の最大/最小/平均消費時間です。
こういうスクリプト を実行して計測しています。
------------------------ openat read lstat getdents64 AVG: 0.72845068 1.21160682 1.24938920 0.04721996 MAX: 1.05511000 1.68140700 2.08819100 0.08118800 MIN: 0.45633100 0.94886000 0.17389800 0.02756000
openat read lstat getdents64 AVG: 0.81789664 1.33113000 1.67242892 0.05575284 MAX: 1.20938100 1.84313600 2.71643400 0.08448400 MIN: 0.50309500 1.08326800 0.68068100 0.03279700
overlayfsにおいて若干の上振れが観測できるようです。ただし、かなり幅があります。
これを見ると平均はともかく、ばらつきの傾向も違うようにも予想されるので、回数を増やしてヒストグラムとかにするともっと面白いのかなあなどと思います。
各種キャッシュがスラブに乗った状態ではあまり差が出ない結果となります。というよりさらにバラついて、ファイルシステムよりヒット率をあげたほうがい良さそうという風になります。
root@0a78c58c2694:/# ( cd /app1; strace -cfw -eopen,openat,read,write,close,stat,lstat,access,fstat,fcntl,ioctl,getdents64 bin/rails runner 'puts Rails::VERSION::STRING' ) strace: Process 3435 attached strace: Process 3436 attached 6.0.1 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 49.51 1.445510 56 25462 160 lstat 11.73 0.342558 58 5833 1680 openat 9.89 0.288693 60 4738 4 read 8.12 0.236989 57 4157 close 7.63 0.222684 55 4000 fstat 4.63 0.135284 54 2490 350 stat 4.20 0.122545 59 2046 fcntl 3.44 0.100308 49 2030 2026 ioctl 0.85 0.024687 57 428 getdents64 0.00 0.000092 46 2 write 0.00 0.000085 21 4 2 access ------ ----------- ----------- --------- --------- ---------------- 100.00 2.919436 51190 4222 total
root@0a78c58c2694:/# ( cd /app2; strace -cfw -eopen,openat,read,write,close,stat,lstat,access,fstat,fcntl,ioctl,getdents64 bin/rails runner 'puts Rails::VERSION::STRING' ) strace: Process 3428 attached strace: Process 3429 attached 6.0.1 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 49.30 1.378959 54 25462 160 lstat 12.99 0.363430 62 5833 1680 openat 9.63 0.269296 56 4738 4 read 7.58 0.211899 50 4157 close 7.42 0.207520 51 4000 fstat 5.17 0.144577 58 2490 350 stat 3.60 0.100618 49 2046 fcntl 3.53 0.098801 48 2030 2026 ioctl 0.76 0.021386 49 428 getdents64 0.02 0.000439 109 4 2 access 0.00 0.000068 34 2 write ------ ----------- ----------- --------- --------- ---------------- 100.00 2.796993 51190 4222 total
非常に大雑把なので書いていて恐ろしくなったんですが、突っ込みください!
明日は @kenchan による M5Stackの中にpixelaの草を出現させる です。