ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

IPC Namespaceをまたいだプロセス間で、pipeでやりとりする。mrubyで。

Introduction to Linux namespaces - Part 2: IPC | Yet another enthusiast blog!

こういうブログ記事があって、元記事はC言語なんだけど、これと同じことをmrubyでもやってみたサンプル。なお元記事は clone(2) だけど今回はforkしてから unshare(2) している。clone未実装なんで。。

reader, writer = IO.pipe
puts " - Hello ?"

p = Process.fork do
  Namespace.unshare(Namespace::CLONE_NEWUTS | Namespace::CLONE_NEWIPC)

  writer.close
  reader.read # blocking

  system "hostname 'In-Namespace'"
  puts " - World !"
  Exec.exec "/bin/bash"
end

10.times do
  sleep 0.5
  print "."
end
puts
writer.close

Process.waitpid p

(build_configはこんな感じで)

MRuby::Build.new do |conf|
  toolchain :gcc
  conf.gembox 'full-core'
  conf.gem github: 'haconiwa/mruby-exec'
  conf.gem github: 'iij/mruby-process'
  conf.gem github: 'iij/mruby-io'
  conf.gem github: 'haconiwa/mruby-namespace'
end

めちゃくちゃハマっていたのは、forkするんでwriter FDが親子プロセスともにコピーされるため、両方クローズしないとreadでブロックし続けるよね...というところ...。

[vagrant@localhost vagrant]$ sudo ./mruby/bin/mruby sample/ipc_ns.rb 
 - Hello ?
..........
 - World !
[root@In-Namespace vagrant]# 

unshare(Namespace::CLONE_NEWIPC) は成功しているが、プロセス間でやりとりをやっていけているようだ。 (mruby はこういう挙動をサクッと試せて便利)


Linuxプログラミングインタフェース

Linuxプログラミングインタフェース

とにかくこれを読まないとダメな気がする、このままでは俺はダメになる気がするこの頃。

haconiwaの室内楽 - Re: 自作Linuxコンテナの時代

haconiwa という、いわゆるLinuxコンテナに関する様々な技術を組み合わせて、自分のためのコンテナを作ることができるRuby製のツールと、そのDSLを作った。ひとまずこれぐらいはやりたいということができていそうなので、バージョン 0.2.0 としてリリースした。

github.com

使い方

ほぼREADMEの日本語版。

前提として、以下のライブラリとコマンドが必要になるので入れておいて欲しい。

  • libcap (libcap.so.2FFI 経由で使う)
  • nsenter (yum install util-linux とかそういう感じで入れる)

ひとまず動かしたい場合は、rbenvなどが整った環境で、gemとして入れるのがいいと思う。多分Ruby 2.0 以降で動く気がする。

$ gem install haconiwa
$ rbenv rehash

そして、現在のhaconiwaはファイルシステムに関しては何も機能がないので、別のツール、例えば debootstraplxc-create などで準備しておく。

$ lxc-create -t centos -n sample --dir /tmp/udzura

で、ひとまず以下のようなRubyDSLファイルを new_haconiwa001.haco とでもして保存する。

Haconiwa::Base.define do |config|
  config.name = "new-haconiwa001" # to be hostname

  config.cgroup["cpu.cfs_period_us"] = 100000
  config.cgroup["cpu.cfs_quota_us"]  =  30000

  config.mount_independent_procfs
  config.chroot_to "/tmp/udzura"

  config.namespace.unshare "ipc"
  config.namespace.unshare "uts"
  config.namespace.unshare "mount"
  config.namespace.unshare "pid"

  config.capabilities.allow :all
  config.capabilities.drop "CAP_SYS_TIME"
end

このコンテナを立ち上げるには以下のようにする。

$ haconiwa run new_haconiwa001.haco -- /bin/bash
[root@foobar hacotest]# haconiwa run example001.haco -- /bin/bash
unshare(2) flag: 0xc020000
[root@new-haconiwa001 /]# New container: Name = new-haconiwa001, PID = 17782

[root@new-haconiwa001 /]# 
[root@new-haconiwa001 /]# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  selinux  srv  sys  tmp  usr  var
[root@new-haconiwa001 /]# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 115384  2048 ?        S    10:34   0:00 /bin/bash
root        12  0.0  0.0 151028  1700 ?        R+   10:34   0:00 ps auxf
[root@new-haconiwa001 /]# cat /etc/centos-release
CentOS Linux release 7.2.1511 (Core) 
[root@new-haconiwa001 /]# exit
exit
Successfully exit container.

この環境は、普通にCentOS 7のマシンのように扱えるはず。yumコマンドも打てる。 あるいは、cgroupの制限が効いているので、CPUを使うような処理をしても利用率は30%以下に抑えられるだろうし、また、capabilityも落とされているので、例えばコンテナの中で date -s を走らせようとしてもうまくいかなかったりする。

[root@new-haconiwa001 /]# date -s 10:00
date: cannot set date: Operation not permitted

コンテナで「initプロセス」として長時間動作するプロセスを立ち上げておいて、別のプロセスから以下のようにアタッチすることもできる。

[root@foobar hacotest]# haconiwa run example001.haco -- /bin/sleep 1000
unshare(2) flag: 0xc020000
New container: Name = new-haconiwa001, PID = 17975

## 別プロセスから

[root@foobar hacotest]# haconiwa attach example001.haco -- /bin/bash
Attached to contanier: Runner PID = 17991
[root@new-haconiwa001 /]# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         3  0.0  0.0 113120  1184 ?        S    10:50   0:00 /bin/bash /tmp/haconiwa-attacher-17977-1464864637.sh20160602-17977-wcpyet
root         4  0.0  0.1 115384  1988 ?        S    10:50   0:00  \_ /bin/bash
root        13  0.0  0.0 151028  1704 ?        R+   10:50   0:00      \_ ps auxf
root         1  0.0  0.0 107896   616 ?        S+   10:50   0:00 /bin/sleep 1000

詳細は、 examplesディレクトリ配下 、より詳しくはソースコードを見て欲しい。

また、このgemは、基本的にCentOS 7上で開発しているが、 Fukuoka.rb の有志で試して頂いたところ、Debian sidでも割と動いているようだ(Thanks @minimum2scp)。いろいろな環境で試して欲しいかも...。

なぜ作ったか?

「自作Linuxコンテナの時代」を読んでめっちゃ影響されたこと、先日のコンテナ勉強会@福岡に参加して改めて自分の中でコンテナ技術が盛り上がったことが大きい。

blog.yuuk.io

ct-study.connpass.com

実際、業務でもDrone経由でDockerを運用したり、 Sqale というサービスを見ていてLXCをいじったりして、コンテナ的なことが欲しいけれど、実際に必要なことは例えばリソースを制限したり、ファイルシステムを隔離したり、などと一部分だけだったりとか、いろいろ思うところがあったので、この手の技術を「簡単に組み合わせること」にフォーカスしたコンテナツールがあると良いのでは、と思って作ってみた。

例えば、 matsumotoryさんの rcon のように使ったり、たくさんのコンテナで同じrootfsをマウントして共有しまくったり、などといったニッチな要件を比較的容易にできる(ようにしたい)。

コンテナ周りのお話は面白い。でもDockerが出現してからは「Dockerをこう使いました」みたいな話が多いような印象があって、それはそれで非常に興味深いし貴重なんだけれど、一方でコンテナを支える技術要素を見てみると、それぞれは非常にシンプルで、綺麗に組み合わせられるようになっている。

クリシェ的な表現となってしまうが、「UNIXの哲学」的である。

ということで、この界隈は、Docker的な「全部入り」の使い方のみでなく、いろいろな可能性があるような気がしている。haconiwaの開発を通して改めてその思いが強まった。

今後

正直な話、何度も「CのAPI直接叩きたいよ〜〜」と思ったので、この実装はこの実装として、mrubyで書き直そうかな?などと思ったり。現在、例えば別途nsenterコマンドがないとダメだったりするが、そういう依存も軽くしたい。

また、現在のCRubyは基本的にマルチスレッドで動作するので、namespace関連のシステムコールと相性が良くない。このお話はもう少しまとまったら書きます...。

setns(2) - Linux manual page

A process may not be reassociated with a new mount namespace if it is multithreaded.

などなど。そういう意味でもmrubyで書いた方が綺麗になりそう。

何より、さすがにこのコンテナで本番っぽいアプリを動かすのは安心感がないし、微妙な挙動も随所に見られるので、しばらく自作コンテナで遊びつつ地道に直していこうかな〜という感じ。

今の所、あくまでもPoCに過ぎないツールという扱いだけれど、おためしください。

最後に

haconiwa の中には container の con が入っています。箱庭自体は、僕の敬愛する変拍子系ローファイプログレバンド「箱庭の室内楽」から拝借しました。コンテナとかgemとかどうでもいいんで聞いてください。

www.youtube.com

開発にあたり、 capsh 、 libcontanier や nsenter の実装、そして @matsumoroty さん自身とそのソフトウェアからたくさんのアドバイス、ヒントをいただきました。この場を借りて感謝を。

WEB+DB PRESS vol.92 に書きました

よろしくお願いします。

よろしくお願いします........!!!!!

gihyo.jp


なん年ぶりの記事かな〜と思って調べると、2014年の79号以来なので2年ちょっとぶりですね。

思えば、最初に #wdpress に書いたのも、実は新人応援号の記事だったりしたのでした。

ぼくは、冒頭の総括的な内容を書かせていただいて、あとは若手の方々に譲る気持ちでいたのですが、なんかこう、エモい感じが膨れ上がってしまい、結果的に4ページの予定が6ページになってしまっていました。まあ、ご勘弁下さいということで......。

ちなみに最初の案の原稿だと7ページ超えてました...。

内容としては、広く(アプリ、フロント、インフラ、そしてネイティブにも言及)、しかも手を動かしながらウェッブ開発者の全体像を掴めるようにできているので、楽しく学べるような教材としていい感じじゃないかな〜と思っております。 特にフロントエンドの章はぼくも勉強になりました。 @kurotaky くんお疲れ様でした。


最後に、執筆した同僚各位の記事を紹介しておきます。

tech.pepabo.com

ten-snapon.com

mapyo.hatenablog.com

ravelll.hatenadiary.jp

shiro-16.hatenablog.com

「WEB+DB PRESS Vol.92」に寄稿しました - 準二級.jp

みんな最高だったぜ!!1 担当編集の池田さんにも感謝。

第9回 コンテナ型仮想化の情報交換会@福岡 やっていきました

ct-study.connpass.com


お疲れ様でした。

同僚のものも含め、素晴らしい発表ばかりだった中、個人的には、tahira氏の発表が、いろいろな意味でよかったなあと思って感動していました。ホスティングカジュアルにも期待しています。

あと、 id:y_uuki さんの存在を確認し、老害として若手に倒される任務を果たしてきました。

続きを読む