一つコンピュータを複数の人で使うのに、最近はなぜか仮想マシンが流行みたいなのですが、いろいろもったいないで、OS上で仲良く使えばいいのにと。OSのユーザとパーミッションくらいで仲良く使える世の中がいいと思うのですが、せち辛いのか・物騒なのか、File Systemやネットワークはオレ専用がいいとか、アイツがCPUやメモリを独り占めするのは許さねえ、とかが問題なんでしょうか。
namespaceがもろもろのオレ専用(isolation)、cgroupが独り占め関連(リソース分配)みたいな話なんじゃないかと。
1. namespace概要
参考文献は、Namespaces in operation, part 1: namespaces overview あたりかと。
kernelバージョン依存ですが、ざっと、以下を分離して使うことができるようです。
namespace | プログラムのflag | kernel | 分離するもの |
---|---|---|---|
Mount | CLONE_NEWNS | 2.4.19 | マウントポイント(というかファイルシステム) |
UTS | CLONE_NEWUTS | 2.6.19 | nodename/domainname(というかホスト名/NISドメイン名) |
IPC | CLONE_NEWIPC | 2.6.19 | System V IPCとPOSIX message queues |
PID | CLONE_NEWPID | 2.6.24 | プロセスID(pid)空間 |
Network | CLONE_NEWNET | (2.6.24) 2.6.29 | ネットワークデバイス |
User | CLONE_NEWUSER | (2.6.23) 3.8 | ユーザやグループ(uidとかgidとか) |
例えば、Cのプログラムの中で、
unshare(CLONE_NEWNS | CLONE_NEWNET)
とか引数に好きなのを並べると、それ以降の処理はnamespace分離されて動作するって感じかと。(cloneとかでも)
2. cgroup (control group)
参考文献は、CGROUPS, CGROUPまわりその他資料, Redhat(RHEL6)の資料などなど。
cgroupを作って、pidをcgroupにひもづけることで、プロセス毎のリソース利用制限ができます。作ったcgroupに対してできること(リソース制限設定など)は、環境依存ですが、ざっと、以下です。
sybsystem | できることの例 |
---|---|
cpu | 1秒に N micro secondまでとか、全部で N micro secondまでとかの、半分ずつシェアしようとかの制限 |
cpusets | 何番目のCPUを使うとか、どのメモリノードを使うとかの、制限 |
memory | N byteまでとかの制限 |
hugetlb | N byteまでとかの制限 |
blkio | ブロックIO制限で、HDDとかのデバイス毎に、読み込み N byte/secondまで、とかの制限 |
devices | どのデバイスが使えるとかの制限 |
freezer | 処理を止めちゃう。 |
net_cls | ネットワークパケットに印をつける。(その印をもとに、別途、tc(linux traffic control)が流量制限したりする) |
net_prio | ネットワークデバイス毎のプライオリティ設定 |
cgroupを使う、cgroupに制限を設定する、プロセスをcgroupにひもづけるなんかは、
コマンド、特別なディレクトリ(subsys_mount_point)の操作、静的設定・ルール設定、プログラムから、
とかの方法があります。
利用には、少し準備が必要かもです。
CentOS6あたりでは、
yum -y install libcgroup service cgconfig start chkconfig cgconfig on プログラムで遊ぶなら yum -y install libcgroup-devel 確認(subsys_mount_pointを見てみる)は、 ls -la /cgroup/ total 8 drwxr-xr-x. 10 root root 4096 Sep 11 21:27 . dr-xr-xr-x. 23 root root 4096 Sep 11 21:26 .. drwxr-xr-x. 2 root root 0 Sep 11 21:27 blkio drwxr-xr-x. 3 root root 0 Sep 11 21:27 cpu drwxr-xr-x. 2 root root 0 Sep 11 21:27 cpuacct drwxr-xr-x. 2 root root 0 Sep 11 21:27 cpuset drwxr-xr-x. 2 root root 0 Sep 11 21:27 devices drwxr-xr-x. 2 root root 0 Sep 11 21:27 freezer drwxr-xr-x. 3 root root 0 Sep 11 21:27 memory drwxr-xr-x. 2 root root 0 Sep 11 21:27 net_cls
Ubuntu12.04あたりでは、
apt-get -y install cgroup-lite プログラムで遊ぶなら apt-get -y install libcgroup-dev 確認(subsys_mount_pointを見てみる)は、 ls -la /sys/fs/cgroup/ total 0 drwxr-xr-x 10 root root 200 Aug 30 05:49 . drwxr-xr-x 6 root root 0 Aug 30 05:29 .. drwxr-xr-x 2 root root 0 Aug 30 05:49 blkio drwxr-xr-x 2 root root 0 Aug 30 05:49 cpu drwxr-xr-x 2 root root 0 Aug 30 05:49 cpuacct drwxr-xr-x 2 root root 0 Aug 30 05:49 cpuset drwxr-xr-x 2 root root 0 Aug 30 05:49 devices drwxr-xr-x 2 root root 0 Aug 30 05:49 freezer drwxr-xr-x 2 root root 0 Aug 30 05:49 memory drwxr-xr-x 2 root root 0 Aug 30 05:49 perf_event
3. プログラムから使う
namespaceは、cloneやunshareでflag指定するだけ、
cgroupは、libcgroupで、グループを作ったり、グループにプロセスを割り当てたり、
する感じです。
3-1. namespaceの例
#include <sched.h> ... unshare(CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWUTS); // 以降、指定したnamespaceが分離されて実行される
例えば、pivot_rootと一緒に使うと、ファイルシステムも別な感じでいいのじゃないかと思うんですが、正解の自身がないです。
#include <stdio.h> #include <sched.h> #include <sys/mount.h> ... int r; r = unshare(CLONE_NEWNS); if(rc != 0){ perror("unshare"); exit(1);} mkdir("/var/tmp/myjail01"); mkdir("/var/tmp/myjail01/old_root"); chdir("/var/tmp/myjail01"); r = pivot_root("/var/tmp/jail1", "/var/tmp/jail1/old_root"); if(rc != 0){ perror("pivot_root"); exit(2);} chdir("/"); umount2("old_root", MNT_DETACH); // 以降、マウントポイントが分離され、勝手なルートディレクトリで動作するつもり
3-2. cgroupの例
mycgroup01を作って、CPU共有の重み500、メモリ制限1MBにして、プログラム自身を、mycgroup01内で実行(=制限をうける)する例です。
#include <libcgroup.h> // gcc test.c -lcgroup ... // 初期化 cgroup_init(); // cgroupをふわっと作る struct cgroup *cg1 = cgroup_new_cgroup("mycgroup01"); // 制限を追加 struct cgroup_controller * cg1cpu = cgroup_add_controller(cg1, "cpu"); cgroup_add_value_int64(cg1cpu, "cpu.shares", 500); struct cgroup_controller * cg1mem = cgroup_add_controller(cg1, "memory"); cgroup_add_value_int64(cg1mem, "memory.limit_in_bytes", 1234000); // cgroupをほんとうに作る cgroup_create_cgroup(cg1, 0); // このタスク自身を、今作ったcgroupに入れる(上記制限の配下に入れる) cgroup_attach_task(cg1); ...以降、上記制限の配下に入るので、 ・制限(1234000byte)を超えたmallocとかmemsetとかしてみると、止まる ・無限ループとかにしてcpu.shares値をかえたバージョンと二つ同時に動かすと、shares値の割合どおりにCPUが使われる とか
4. 応用
ちらほら見たところでは、以下で使われているらしく、
libvertでKVM使うとcgroupついてくるとか、
LXCのバックエンドはこんなんじゃないかとか、
OpenStackとやらもネットワーク部分で使われているらしい
ほかには、
あやしい人のshellを置き換えたり、いまいち怪しいブラウザをラップしたり、
あやしい人のプログラムを隔離して実行したり(Webアプリとか、自分の自信の無いプログラムとかも)
とか、OSだけで昔ながらのシンプルなサーバー共同利用がいいなあ、と。
--
以上
返信削除Awesome article. It is so detailed and well formatted that i enjoyed reading it as well as get some new information too.
SAP ABAP Training in Chennai
SAP HR training in Chennai
I simply couldn’t depart your site before suggesting that I really enjoyed the usual information an individual supply in your visitors? Is going to be again steadily to check out new posts.
返信削除GRE Coaching in Chennai
I simply couldn’t depart your site before suggesting that I really enjoyed the usual information an individual supply in your visitors? Is going to be again steadily to check out new posts.
返信削除GRE Coaching in Chennai