unshareコマンドでLinuxのNamespaceに入門
Namespaceはコンテナで使われている技術の一つで、コンテナを理解深めるために知っておくとよいので調べてみた。 どんな使われ方をしているかというと、 例えばPID namespaceはPIDの number spaceを隔離する。 これは同じホスト上で実行されている2つのプロセスが同じPIDを持つことができるということになる。
namespaceがなくて隔離されてないとコンテナAがコンテナB、C、Dなどに filesystemのunmountやホスト名の変更、NWインターフェースの削除など できたりしてしまうので、必ず他のコンテナのプロセスがみれないようにする。
Namespace
Kernel/OSのリソースで、物理リソースは制限しない(cgroupsでする)が、 以下の項目についてNamespaceを分離する。 namespaceを分離した環境では、許可されたリソースしか見えなくなるので コンテナ内の要素だけ見えるように制限できる。
- Mount Namespace(ファイルシステムのマウントポイントを分離: Namespace 内の mount / umount が他の Namespace に影響を与えないようにする)
- UTS Namespace(ホスト名,ドメイン名の分離)
- PID Namespace(PID 空間の分離、新しい PID Namespace では PID 1 から始まる)
- IPC Namespace(セマフォ、MQ、共有メモリなどのプロセス間通信の分離)
- User Namespace(UID、GID Namespaceの分離)
- Network Namespace(インターフェース、ルーティングテーブル、ソケットなど)
- cgroup Namespace(cgroupのルートディレクトリを分離)
cgroups
cpuやmemory、ディスクなどの物理リソース制限は cgroupsと呼ばれるカーネル機能で計測されアクセス制限される。 cgroupsではタスクをグループ化したり、そのグループ内のタスクに対して 以下のような物理リソースを制限できる。使用量やアクセスを制限する。
unshareコマンドでNamespaceについて確認
unshare コマンドはparentから unshared されている namespaceを使用してプログラムを実行できるらしい。 unshare が新しいnamespace でどんなプログラムでも走らせることができるということ。実際にUTS Namespaceを例に unshareコマンドの動きを確認してみる。
$ unshare -h
Usage:
unshare [options] <program> [<argument>...]
Run a program with some namespaces unshared from the parent.
オプション:
-m, --mount unshare mounts namespace
-u, --uts unshare UTS namespace (hostname etc)
-i, --ipc unshare System V IPC namespace
-n, --net unshare network namespace
-p, --pid unshare pid namespace
-U, --user unshare user namespace
-f, --fork fork before launching <program>
--mount-proc[=<dir>] mount proc filesystem first (implies --mount)
-r, --map-root-user map current user to root (implies --user)
--propagation <slave|shared|private|unchanged>
modify mount propagation in mount namespace
-s, --setgroups allow|deny control the setgroups syscall in user namespaces
-h, --help display this help and exit
-V, --version output version information and exit
For more details see unshare(1).
UTS Namespaceは名前空間ごとにホスト名やドメイン名を独自に持つことができる。
以下で UTS Namespace を unshare コマンドで操作してみる。
unshare -u /bin/sh はUTS名前空間を指定してunshare実行している
これでホスト名、ドメイン名が分離されたので、
もとのホスト名は test-ozawa-dev01.amb-infra-dev.incvb.io だが、
unshare で切り替え後、 my-new-hostname に変更している。
もちろんこのホスト名は新たな namespace だけで有効なので、 unshareで起動したシェルを終了すると、ホスト名はもとに戻る。
$ sudo su # root userになる
# uname -n # 現在のhostnameを確認
test01
# unshare -u /bin/sh # 新しいUTS namespaceでshellを作成
sh-4.2# hostname my-new-hostname # hostnameを設定
sh-4.2# uname -n # 新しいhostnameを確認
my-new-hostname
sh-4.2# exit # 新しいUTS namespaceから出る
exit
# uname -n # 元のhostnameが変更されていないことを確認
test01