Contenu connexe
Similaire à MINCS – containers in the shell script (20)
MINCS – containers in the shell script
- 8. 8
MINCS
Minimum Container Shell-scripts
https://github.com/mhiramat/mincs
基本機能
PID/Net/UTS/Mount 名前空間
Overlayfs によるレイヤリング
その他 Capabilities 、 CPUSET など
POSIX shell script (not bash script)
busybox shell/dash などでも動作可能
- 10. 10
フロントエンドスクリプト
MINCS のフロントエンドコマンド
Minc : 指定したコマンドをコンテナ内で動かす
Marten : マルチレイヤのコンテナイメージを管理する
Polecat : 自己実行形式のシングルバイナリコンテナアプリを作る
フロントエンドコマンドは基本的にパラメタのパースのみ
環境変数に変換してバックエンドを呼び出す
Marten/minc-farm の関係だけはまだちゃんとできていない
- 12. 12
minc: Usage
Usage: minc [options] [command]
Options:
-r/--root ROOTDIR rootfs とするディレクトリを指定。省略時は / を使う。
-t/--temp TEMPDIR 作業ディレクトリを指定( -k 有効)。省略すると mktemp で作成。
-k mktemp で作った作業ディレクトリを消さない
--name UTSNAME コンテナ内で使うホスト名を指定する
--debug デバッグ用にログを出す
Command は省略すると (root ユーザの )$SHELL を実行
- 13. 13
Dive into the shell script
minc コマンドがどうやってコンテナを作るか覗いてみよう
ステップ 1 :コマンドライン処理と環境変数の設定
ステップ 2 : minc-exec の実行
netns と cpumask の設定
新しい名前空間への移行
PID の保存と uts の設定
コンテナ用 rootfs のセットアップ
デバイスファイルのバインド
不要なマウントポイントの削除
新しい rootfs への移行と capabilities の設定
- 14. 14
Minc: コマンドライン処理
シンプルな case 文と while ループで処理
getopts は使いにくいので使っていない
While と shift コマンドでコマンドラインを処理するだけ
主に環境変数の設定
知らない引数が出てきたら取り敢えずコマンドと解釈 :)
ループ後の処理
必要なら後述する minc-farm を使って UUID からイメージを取り出す
trap コマンドで後処理を設定
Minc-exec を呼び出す
- 16. 16
Minc-exec(2) : netns/cpuset
netns の設定
MINC_NETNS で指定された名前の netns を ip netns コマンドで作る
終了時に Trap コマンドで削除
一応仮想 eth pair だけは作成(でも IP アドレスは割り当てていない)
Docker のような iptables 対応はしない
pipework などがあるため
CPUSET で CPU マスクを設定
taskset コマンドで実行する CPU を指定する
cgroups のような細かい設定はなし
- 17. 17
閑話休題: Trap コマンド
Trap コマンドは偉大
シグナルによる割り込みとシェルスクリプト終了をハンドリングできる
スクリプト内の関数も呼び出せる
→ 後処理関数を作れる
minc では積極的に trap を活用
一時ファイル /PID ファイルの削除
終了時の info 表示
Ctrl+c の抑制
- 18. 18
Minc-exec(3) : unshare による名前空間移動
Unshare コマンドで名前空間を移動
自分自身を指定して起動
Pid, mount, ipc, uts の名前空間を分離
unshare -iumpf $0 “$@”
netns だけは ip netns exec を使う
ip netns exec $MINC_NETNS unshare -iumpf $0 “$@”
- 19. 19
Minc-exec(4) : PID と utsname の処理
PID の取得
後でコンテナ外から PID を知るために使う
Unshare は fork してしまうのでコンテナ内からしか分からない :)
実は procfs を remount しない限り /proc はコンテナ外と同じ
/proc/self が参照できるのだ!
utsname の設定
MINC_UTSNAME で設定した名前を hostname に指定
- 20. 20
Minc-exec(5): マウント名前空間とオーバレイ
mount 名前空間の完全隔離
unshare で mount 名前空間を隔離しても、他の名前空間に操作が伝搬する!
何だこの仕様・・・。
Mount --make-rprivate / を実行
/ 以下でのマウント操作を他の名前空間に通知しない
Minc-coat でオーバレイを行う
Minc-coat バックエンド(後述)で rootfs に作業ディレクトリを被せる
この後の作業が元になる rootfs に変更をしないようにする
rootfs を壊していい場合は --direct オプションを付ける
- 21. 21
Minc-coat :オーバレイの実装
一時的ディレクトリに root, storage, work を作成
root : overlayfs をマウントするマウントポイント → $RD
storage: コンテナ内の作業結果が記録されるディレクトリ → $UD
work: overlayfs 用の Workdir (ファイルシステムが使う) → $WD
Overlay ファイルシステムで新しい rootfs を作る
名前空間の分離だけでなく、レイヤを作ってストレージを分離
カーネルバージョンによって少しオプションが違うので注意が必要
Upstream カーネルに対応するマウントコマンド
mount -t overlay -o upperdir=$UD,lowerdir=$BASEDIR,workdir=$WD overlayfs $RD
Ubuntu14.10 用の overlayfs に対応するマウントコマンド
mount -t overlayfs -o upperdir=$UD,lowerdir=$BASEDIR overlayfs $RD
- 22. 22
Minc-exec(6) :特殊ファイルの処理
特殊ファイル・ディレクトリの処理
まず /etc, /dev, /sys, /proc を minc-coat で作ったディレクトリに作成
/dev 以下のバインドマウント
ダミーファイルを作って mount --bind で実体とバインドする( symlink みたいなもの)
/dev/console, /dev/null, /dev/zero, /dev/random, /dev/urandom, /dev/mqueue
正直このあたりは使う人が勝手に書き換えてほしい
/dev/pts だけは newinstance オプションで新規作成
/proc のマウント
元の /proc はリードオンリーにしておく
此処から先は他のプロセス PID が見えなくなる
/proc/sys など書き込まれたくないものは、元の /proc (既に ro 化済)の物を見せる
/sys のバインドマウント
バインドマウントを使ってマウント(これも ro 化が必要かも)
- 24. 24
Minc-exec(7) : mountpoint の後処理
不要な mountpoint を消す
残しておくと chroot 後にも見えてしまう
umount 出来ないものがあるので pivot_root で処理を行う
動作を見るために df -h を挟んでモニタしてみるとよくわかる
- 25. 25
Minc-exec(7) : mountpoint の後処理
不要な mountpoint を消す
残しておくと chroot 後にも見えてしまう
umount 出来ないものがあるので pivot_root で処理を行う
Filesystem Size Used Avail Use% Mounted on
devtmpfs 740M 0 740M 0% /dev
tmpfs 748M 0 748M 0% /dev/shm
tmpfs 748M 8.5M 740M 2% /run
tmpfs 748M 0 748M 0% /sys/fs/cgroup
/dev/sda2 15G 8.6G 6.5G 58% /
minc実行前
- 26. 26
Minc-exec(7) : mountpoint の後処理
不要な mountpoint を消す
残しておくと chroot 後にも見えてしまう
umount 出来ないものがあるので pivot_root で処理を行う
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 15G 8.6G 6.5G 58% /
devtmpfs 740M 0 740M 0% /dev
tmpfs 748M 0 748M 0% /dev/shm
tmpfs 748M 0 748M 0% /sys/fs/cgroup
tmpfs 748M 8.5M 740M 2% /run
overlayfs 15G 8.6G 6.5G 58% /tmp/minc1012-NpuyIA/root
tmpfs 748M 0 748M 0% /tmp/minc1012-NpuyIA/root/dev
devtmpfs 740M 0 740M 0% /tmp/minc1012-NpuyIA/root/dev/console
devtmpfs 740M 0 740M 0% /tmp/minc1012-NpuyIA/root/dev/null
devtmpfs 740M 0 740M 0% /tmp/minc1012-NpuyIA/root/dev/zero
devtmpfs 740M 0 740M 0% /tmp/minc1012-NpuyIA/root/dev/random
devtmpfs 740M 0 740M 0% /tmp/minc1012-NpuyIA/root/dev/urandom
特殊ファイルを用意
- 27. 27
Minc-exec(7) : mountpoint の後処理
不要な mountpoint を消す
残しておくと chroot 後にも見えてしまう
umount 出来ないものがあるので pivot_root で処理を行う
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 15G 8.6G 6.5G 58% /.orig
devtmpfs 740M 0 740M 0% /.orig/dev
tmpfs 748M 0 748M 0% /.orig/dev/shm
tmpfs 748M 0 748M 0% /.orig/sys/fs/cgroup
tmpfs 748M 8.5M 740M 2% /.orig/run
overlayfs 15G 8.6G 6.5G 58% /
tmpfs 748M 0 748M 0% /dev
devtmpfs 740M 0 740M 0% /dev/console
devtmpfs 740M 0 740M 0% /dev/null
devtmpfs 740M 0 740M 0% /dev/zero
devtmpfs 740M 0 740M 0% /dev/random
devtmpfs 740M 0 740M 0% /dev/urandom
1回目のpivot_root
ではこの辺りが残る
- 28. 28
Minc-exec(7) : mountpoint の後処理
不要な mountpoint を消す
残しておくと chroot 後にも見えてしまう
umount 出来ないものがあるので pivot_root で処理を行う
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 15G 8.6G 6.5G 58% /.orig
overlayfs 15G 8.6G 6.5G 58% /
tmpfs 748M 0 748M 0% /dev
devtmpfs 740M 0 740M 0% /dev/console
devtmpfs 740M 0 740M 0% /dev/null
devtmpfs 740M 0 740M 0% /dev/zero
devtmpfs 740M 0 740M 0% /dev/random
devtmpfs 740M 0 740M 0% /dev/urandom
古い/devなどを
削除する
- 29. 29
Minc-exec(7) : mountpoint の後処理
不要な mountpoint を消す
残しておくと chroot 後にも見えてしまう
umount 出来ないものがあるので pivot_root で処理を行う
Filesystem Size Used Avail Use% Mounted on
overlayfs 15G 8.6G 6.5G 58% /
tmpfs 748M 0 748M 0% /dev
devtmpfs 740M 0 740M 0% /dev/console
devtmpfs 740M 0 740M 0% /dev/null
devtmpfs 740M 0 740M 0% /dev/zero
devtmpfs 740M 0 740M 0% /dev/random
devtmpfs 740M 0 740M 0% /dev/urandom
古い/にpivotしなおした後
新しい/にchrootした
- 30. 30
Minc-leash
Leash 関数 = “Least capabilities shell”
Linux ケーパビリティの制限と chroot を行う
capsh(libcap) を利用
実行ユーザも変更
gid と uid で変更
ケーパビリティを変更しないなら Chroot だけ実行
Wash 関数
シェルスクリプト間でやり取りしてきた環境変数を消す
env と grep で MINC_* を取り出して unset
- 32. 32
Boot2minc
自家製最小 ISO イメージ+ MINCS
https://github.com/mhiramat/boot2minc
Minimal Linux Live ( https://github.com/ivandavidov/minimal )から fork
boot2minc に含まれるもの
Linux kernel
Busybox(+unshare パッチ )
MINCS
以上 :)
カーネル含めて 8MB ぐらいのイメージ (Qemu-kvm で起動可能 )
Busybox とカーネルの config の絞り込みを行えば更に小さくできる
- 33. 33
Marten: コンテナイメージの管理
コンテナは実行環境の分離
minc はコンテナ機能のみを提供
-r オプションで rootfs の指定が可能
毎回 debootstrap とかで再構築するの? Fedora とか CentOS はどうする?
-t オプションで指定した作業結果の再利用が面倒
今回作成した作業結果を反映させたい・・・
Overlayfs ベースのコンテナイメージ管理をしよう
Docker っぽく UUID っぽいもので識別
イメージ間の依存関係をシェルスクリプトで整理しよう
Docker export/save したイメージの再利用
- 35. 35
TODO
minc
TTY を screen/tmux 経由でサポート
pipework とのコラボ (netns なんとかしよう )
cgroups によるメモリや CPU 利用量の制限 (minc-cage)
btrfs や dm-thin のサポート (plugin 方式? )
marten
コンテナの export と署名添付機能の追加( O.C.I. 互換?)
UUID ベースのコンテナ起動機能追加(より Docker っぽく)
- 39. 39
Docker 連携の例
# docker save centos | gzip - > centos.tar.gz
# marten import centos.tar.gz
Importing image: centos
511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
5b12ef8fd57065237a6833039acc0e7f68e363c15d8abb5cacce7143a1f7de8a
8efe422e6104930bd0975c199faa15da985b6694513d2e873aa2da9ee402174c
# marten images
ID SIZE NAME
511136ea3c5a 4.0K (noname)
5b12ef8fd570 4.0K (noname)
8efe422e6104 224M centos
# minc -r centos /bin/bash