Google Chrome の Namespace 利用のメモ
(2016-05-16 Chromium の参考ページが移動していたので更新)
過去に勉強会なんかで「Linux 版の Chrome は Namespace を使ってる」という話をしたことあるけど、そういえば確認したことはなかったので確認したメモ。
参考はこの辺り。
pidns と netns を使ってそうです。
まず Google Chrome を起動します。最近 Linux 版は重くて使ってないけど。
$ pstree -p :(snip) |-chrome(29616)-+-chrome-sandbox(29618)---chrome(29620)-+-chrome(29630)-+-chrome(29701)-+-{chrome}(29702) | | | | |-{chrome}(29720) :(snip) | | `-chrome-sandbox(29624)---nacl_helper(29625) :(snip)
chrome-sandbox ってのがこの辺り作りそうですね。
まずはinitの名前空間を確認します。
# ls -l /proc/1/ns 合計 0 lrwxrwxrwx 1 root root 0 3月 9日 19:02 ipc -> ipc:[4026531839] lrwxrwxrwx 1 root root 0 3月 9日 19:02 mnt -> mnt:[4026531840] lrwxrwxrwx 1 root root 0 3月 9日 19:02 net -> net:[4026531956] lrwxrwxrwx 1 root root 0 3月 9日 19:02 pid -> pid:[4026531836] lrwxrwxrwx 1 root root 0 3月 9日 19:02 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 3月 9日 19:02 uts -> uts:[4026531838]
次に chrome-sandbox の子プロセスの chrome の ns を確認。
# ls -l /proc/29620/ns 合計 0 lrwxrwxrwx 1 karma users 0 3月 9日 20:06 ipc -> ipc:[4026531839] lrwxrwxrwx 1 karma users 0 3月 9日 20:06 mnt -> mnt:[4026531840] lrwxrwxrwx 1 karma users 0 3月 9日 20:06 net -> net:[4026532408] lrwxrwxrwx 1 karma users 0 3月 9日 20:06 pid -> pid:[4026532406] lrwxrwxrwx 1 karma users 0 3月 9日 20:06 user -> user:[4026531837] lrwxrwxrwx 1 karma users 0 3月 9日 20:06 uts -> uts:[4026531838]
net と pid が異なるのが、上記の特殊なシンボリックリンク先でわかりますね (数字が違う)。他は同じです (数字が同じ)。
実際この Namespace 内に入ってみましょう。
# nsenter -t 29620 -n -p
まずは netns の確認。
# ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
新たに netns を作ったので、インターフェースはループバックしかありません。
次に pidns の確認。ps とかのこの辺り確認するコマンドは /proc を見ますので、このままだと親 ns の結果が出ますので使えません (うっかりしててハマった ^^;)。新たに procfs をマウントしてみます。
# mount -t proc proc /mnt # ls /mnt 1/ acpi/ dma key-users mtrr sysrq-trigger 11/ asound/ driver/ keys net@ sysvipc/ 21/ buddyinfo execdomains kmsg pagetypeinfo thread-self@ 28/ bus/ fb kpagecount partitions timer_list 3/ cgroups filesystems kpageflags sched_debug tty/ 4/ cmdline fs/ loadavg scsi/ uptime 58/ config.gz interrupts locks self@ version 6/ consoles iomem meminfo slabinfo vmallocinfo 82/ cpuinfo ioports misc softirqs vmstat 9/ crypto irq/ modules stat zoneinfo 93/ devices kallsyms mounts@ swaps 97/ diskstats kcore mpt/ sys/
pidns 内の PID=1 はこんなです。
# cat /mnt/1/cmdline ; echo /opt/google/chrome/chrome --type=zygote
LXD でリモートの LXD ホストのコンテナを操作してみる
LXD 0.1 がリリースされたのでLXD を試してみた続きです。
LXD の特徴は複数の LXD ホストをリモートから管理できることです。というわけでリモートの LXD ホストの操作を試してみました。とりあえず動くのを確かめただけです。
- テスト用の LXD ホストは Ubuntu 14.04.1 LTS です。README通りに設定してあります
- lxc コマンドを実行するホストは前回のエントリ]で使った Plamo 5.3 ホストです
LXD サーバ
lxd をオプションなしで起動すると、Unix ドメインソケットのみのローカルからの接続のみを受け付けるモードで起動します。リモートから受け付ける場合は "--tcp" オプションを使います。
$ cd ~/go/bin $ ./lxd --tcp=10.200.200.200:8443 & (10.200.200.200のアドレスのホストの8443番ポートで待ち受け)
リモートから受け付ける際のパスワードを設定します。
$ ./lxc config set pasword hogehoge (パスワードをhogehogeに設定)
クライアント側
クライアントからリモートの LXD ホストを操作する場合は、まずリモートホストを登録します。これでリモートホストの証明書がダウンロードされ、クライアントの証明書が LXD ホストにも登録されます (たぶん)。
$ ./lxc remote add lxdhost 10.200.200.200:8443 (10.200.200.200 のホストを "lxdhost" という名前で登録) Certificate fingerprint: 8c ea 8b a3 a0 64 dd 9f 5e fb 28 dd f6 89 c6 58 7c 8b e0 ab 62 c1 14 f5 50 dc 44 16 06 83 fa 85 ok (y/n)? y Admin password for lxdhost: ("lxdhost" で設定したパスワードを入れる) Client certificate stored at server: lxdhost
これで準備 OK です。あとはローカルとほぼ同じです。コンテナを指定するときに登録したホスト名の後にコロンをつけて、コンテナ名を指定します。
$ ./lxc init ubuntu lxdhost:test01 ("test01" コンテナを "lxdhost" に作成) $ ./lxc list lxdhost: ("lxdhost" のコンテナ一覧) test01 $ ./lxc start lxdhost:test01 ("lxdhost"上の"test01"コンテナの起動) $ ./lxc exec lxdhost:test01 -- /bin/uname -a ("lxdhost"上の"test01"コンテナでunameコマンド実行) Linux test01 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
LXD を試してみた
- 公式ページに簡単なクライアントプログラムの使い方が載りました (2015-02-27 更新)
LXD 0.1 がリリースされましたので LXD を試してみました。
こちらも参考に。ただし、現時点では以下とは少しコマンドが違うようです。
Plamo 5.3 で試しています (kernel は独自ビルドの 3.19)。go コマンドはインストール済み。
構築
lxd/README.md at master · lxc/lxd · GitHub の通りです。
$ mkdir -p ~/go $ export GOPATH=~/go $ go get github.com/lxc/lxd $ cd $GOPATH/src/github.com/lxc/lxd $ go get -v -d ./... $ make
これで ~/go/bin 以下にコマンドができました。
$ ls ~/go/bin fuidshift* lxc* lxd*
デーモン起動
これも書いてある通り。
$ sudo mkdir -p /var/lib/lxd $ sudo chown karma:users /var/lib/lxd
subuid, subgid は設定済みです
$ cat /etc/subuid karma:100000:65536 $ cat /etc/subgid karma:100000:65536
とりあえず verbose モードで起動してみました。
$ ~/go/bin/lxd --help Usage: lxd [options] Options: --debug (= false) Enables debug mode. --group (= "") Group which owns the shared socket --help (= false) Print this help message. --tcp (= "") TCP address <addr:port> to listen on in addition to the unix socket (e.g., 127.0.0.1:8443) -v (= false) Enables verbose mode. --version (= false) Print LXD's version number and exit.
非特権コンテナのようですから、Plamo の場合、lxd コマンドを動かすシェルを読み書きできる cgroup に登録しないといけません(Ubuntuだとsystemd-logind辺りが作ったグループがあるのでそれを使いますのでこれは不要)。その後おもむろに lxd 起動
$ for d in /sys/fs/cgroup/* > do > echo $$ > $d/karma/tasks > done $ ~/go/bin/lxd -v
コマンド
$ cd ~/go/bin $ ./lxc help Usage: lxc [subcommand] [options] Available commands: config - Manage configuration. delete - lxc delete <resource> exec - exec specified command in a container. file - Manage files on a container. finger - Fingers the lxd instance to check if it is up and working. help - Presents details on how to use lxd. list - Lists the available resources. remote - Manage remote lxc servers. restart - Changes a containers state to restart. snapshot - Create a read-only snapshot of a container. start - Changes a containers state to start. stop - Changes a containers state to stop. version - Prints the version number of lxd.
コンテナ作成
イメージを勝手に落としてきてコンテナ作ります。help に init がないよw
$ ./lxc init ubuntu test01 $ ./lxc list test01
コンテナ起動
特にひねりはありません。素直に start。
$ ./lxc start test01 $
コンテナの状態確認
特に何もなく起動しているようですが、起動している様子を表示することができません ^^;
$ ./lxc info test01 error: unknown command: info :(snip)
プロセスを見てみると
$ pstree -p :(snip) | |-bash(24780)---lxd(17197)-+-{lxd}(17198) | | |-{lxd}(17199) | | |-{lxd}(17202) | | `-{lxd}(17203) :(snip) |-lxd(17207)---init(17218)-+-cron(18639) | |-getty(18626) | |-getty(18628) | |-getty(18629) | |-getty(18670) | |-getty(18673) | |-rsyslogd(17673)-+-{rsyslogd}(17684) | | `-{rsyslogd}(17685) | |-systemd-udevd(17564) | |-upstart-file-br(17670) | |-upstart-socket-(17669) | `-upstart-udev-br(17540)
確かに Plamo の上で Ubuntu が起動しているようです。
試してみると lxc のコマンドが使えそうです。
$ lxc-ls -P /var/lib/lxd/lxc -f NAME STATE IPV4 IPV6 GROUPS AUTOSTART ---------------------------------------------- test01 RUNNING - - - NO $ lxc-info -P /var/lib/lxd/lxc -n test01 Name: test01 State: RUNNING PID: 17218 CPU use: 1.17 seconds BlkIO use: 248.00 KiB Memory use: 3.94 MiB KMem use: 0 bytes
コマンド実行
$ ./lxc exec test01 -- /bin/uname -a Linux test01 3.19.0-plamo64-karma #2 SMP PREEMPT Mon Feb 9 16:13:40 JST 2015 x86_64 x86_64 x86_64 GNU/Linux
lxc-attach コマンドも使えます。
$ lxc-attach -P /var/lib/lxd/lxc -n test01 -- uname -a Linux test01 3.19.0-plamo64-karma #2 SMP PREEMPT Mon Feb 9 16:13:40 JST 2015 x86_64 x86_64 x86_64 GNU/Linux
コンテナの停止
普通にできます。
$ ./lxc stop test01 $ lxc-ls -P /var/lib/lxd/lxc -fNAME STATE IPV4 IPV6 GROUPS AUTOSTART ---------------------------------------------- test01 STOPPED - - - NO
(続く)
2014年振り返りコンテナ編
今年は2014年を振り返るみたいなブログやらFacebookの書き込みをよく見かける気がするので私も。もう今年も残り少ないので手短に。
Docker が春くらいからそれまで以上に盛り上がりはじめて、そこら中のベンダーがサポートを表明してましたね。その盛り上がりのおかげというわけでもないのですが、gihyo.jp で コンテナとLXCに関する連載 をさせていただきました。つたない文章ですが、それなりにご覧いただいていたようでありがとうございました。
それと第2回 以降、急激に参加人数の増えた コンテナ型仮想化の情報交換会 は、かなり私の趣味に走った勉強会にも関わらず今年も毎回色々な方にお話いただき、多数の方に参加いただき、色々な方と知り合うことができ、色々な勉強ができました。ありがとうございました。
この勉強会をきっかけに他の勉強会に呼んでいただいて登壇できたのも良い経験でした。
どちらかというと人見知りで初めての方とお話するのが苦手な私でも、勉強会主催とか登壇者となるとたくさんの方が話しかけて下さるので、世界も広がったような気がします。
私はコンテナやcgroupなどに関して広く知られて盛り上がる前から調べていたので、今色々偉そうに話したり書いたりできていますが、実際持っている知識はたいしたことがありません。コンテナが盛り上がっている今では、私より頭の良い色々知識が豊富な方が私の興味のある分野について色々なところでお書きになったりお話になったりするようになっていますし、今後はますますそうなっていくでしょうから、今後はそれを勉強させてもらう方が多くなるような気がしています。それはそれで楽しみだなあ、と思ってます。
今年一年どうもありがとうございました。来年もよろしくおねがいたします!!良い年をお迎えください!!
コンテナの歴史と Linux カーネルのコンテナ関連機能についての割とどうでも良い愚痴
この記事は Linux Advent Calendar 2014 の 18 日目のエントリとして書いています。
Docker が盛り上がって、Docker が使ってる「コンテナ」という技術が盛り上がって、Doker の解説がそこら中にあふれるようになったので「Docker? そんなの FreeBSD が jail でずっと前からできてたぞ」というちょっと的外れな発言を見かけることは少なくなりました。一方でコンテナの歴史を追って見る的な企画をみかけるようになりました。
みかけた歴史の解説でいくつか「ちょっと違うやろー」というものを見かけたのでここで愚痴ります。
コンテナの歴史として大体書かれているのが
1979 年 | chroot(2) システムコールの Version 7 Unix への導入 |
1983 年 | chroot(2) システムコールの 4.2BSD への導入 |
2000 年 | FreeBSD jail が FreeBSD 4.0 に導入 |
2005 年 | Solaris Containers 登場 |
2008 年 | Cgroup が Linux カーネル 2.6.24 にマージ |
2014 年 | Docker 1.0 リリース |
というものです。
もちろん「chroot → FreeBSD jail → Linux のコンテナ」という大きな流れを否定するつもりはありません。しかし、前述の年表のようなものにはかなり違和感を覚えます。
しかも私が見たいくつかの記事では「FreeBSD jail (相当|と同様) の機能として cgroup が実装」「ここで初めてLinuxにコンテナの機能が実装された」というような説明がなされています。つまり「FreeBSD jail≒Linux Cgroup≒Linuxカーネルに実装されたコンテナ」というわけですな。これはおかしい!!
どこが!? そう、LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術:連載|gihyo.jp … 技術評論社 を読んでいただいている方はおわかりいただけるのではないでしょうか!? (宣伝)
Linux カーネルに実装されているコンテナ関連の機能
Linux カーネルに実装されているコンテナ関連の機能の主要なものは大きく 2 つあると言えるでしょう。もちろん Cgroup はその一つです。しかし Cgroup だけではコンテナは実現できません。
ここでその 2 つの機能のおさらいです。
- Cgroup
- コンピュータに備わる物理的なリソース(cpu, memory, etc)を隔離/制限するための機能
- Namespace(名前空間)
- カーネル/OSが扱うリソース(ホスト名、ネットワークスタック、PID、etc)を隔離するための機能
そう、この 2 つです。なんで Cgroup だけが取り上げられるん? (もちろんこの2つの他にも使っている技術は様々あります)
そもそも前述の流れだと FreeBSD jail からの流れになっており、FreeBSD jail 相当の機能として Cgroup となっています。FreeBSD jail ってディレクトリツリーとかプロセスとかネットワークスタックとか (これは Vimage か) の隔離ですよね?
この流れからいくと取り上げるべきは Cgroup ではなく Namespace じゃないですか? 今の所 6 つある Namespace のうち、最初にカーネルにマージされたのは Mount Namespace で、なんと 2.4.19 でのマージです (2002 年)。*1
jail 相当とも言える PID Namespace が導入されたのは 2.6.24 で 2008 年なので、前述の年表で「Linuxのコンテナ機能がとりあえず実装されたとき」として 2008 年を取り上げるのは問題ないと思いますが、jail に対応する機能としては Namespace を取り上げるべきなのです。
歴史を語るのは重要なんですが、ちゃんと機能を理解して書いてほしいなあというわりとどうでもよい愚痴でした。
ああ、Linux Advent Calendar 2014 の他のに比べて著しくレベル低いですね… (^^;)