Namespace (Linux)
avashe.icon 古い情報は随時修正お願いします
table:カーネル4.1時点での名前空間
名前空間の名前 隔離されるリソース 実装
Mount名前空間 マウントの集合,操作 fs/mount.h
UTS名前空間 ホスト名、ドメイン名 include/linux/utsname.h
PID名前空間 プロセスID(PID) include/linux/pid_namespace.h
IPC名前空間 SysV IPCオブジェクト、POSIXメッセージキュー include/linux/ipc_namespace.h
User名前空間 UID、GID、それに紐づく特権 include/linux/user_namespace.h
Net名前空間 ネットワークデバイス,アドレス,ポート,ルーティングテーブル,フィルタなど include/net/net_namespace.h
CPUやメモリなどを扱うわけではない
新たに名前空間を加えた時の挙動
元の名前空間のコピーを作る
e.g. Mount名前空間
データがなく、完全新規に作る
e.g. Net名前空間
カーネル側ではNSProxyという構造体で名前空間を管理する
親プロセスからの名前空間からの独立はいつでも可能だが例外あり
名前空間は、ユーザ空間へはファイルで見える
/proc/<pid>/ns/<namespace-name>
これらはカーネル空間にある実体ファイルへのリンク
名前空間に対してできる操作
親プロセスの名前空間を共有
親プロセスの名前空間からの分離
別プロセスの名前空間への移動
親プロセスgetpid(2)の値がいきなり変わると多くのプログラムが壊れるのでPID名前空間の分離は制限がある
unshare(2)やsetns(2)は実行してもプロセス自体のPIDは変わらず、その子プロセスから変わるようになる
User名前空間は他のすべてのの名前空間から見えている
User名前空間以外の各空間は互いに独立である
User名前空間以外の名前空間の構造体はUser名前空間へのポインタを持っている
Linux Kernelでの実装
NSProxy構造体
User名前空間以外の一元管理
自身の参照数カウンタと、各名前空間へのポインタを保持
task_struct構造体(Linuxのスレッド/プロセスを表す構造体)は必ず1つNSProxyへの参照を持つ
cred構造体
User名前空間の管理
各名前空間の構造体
これらは大体以下のデータが共通している
参照カウンタ
カウントするのは参照しているNSProxyの数
ns_common構造体
ユーザ空間にexportしたファイルのinodeから名前空間構造体にアクセスする機能を提供する
procfsに関連するデータを持つ
inode
proc_ns_operations構造体
実際に操作を提供している
user_namespace構造体
User名前空間を表す構造体
nsfs
各名前空間をユーザ空間に見せる
setns(2)がこれを利用している
unshare(2)やclone(2)は直接カーネル空間でtask_structからNSProxyを参照する
先ほどから出ている/proc/<pid>/ns以下のファイル
実は独立したファイルシステム
これ実装以前から同様の処理はしていた
ユーザ空間(ファイル)から対応するNSProxyにアクセスするための機能が提供されている
実際にファイルを読み書きするような作業はやってない
vfsのインターフェースに併せてNSProxyを読む機能を実装した代物
task_struct <--> NSProxy <-> 名前空間構造体 でそれぞれの矢印がN:Nのグラフになっている
親子間で参照するNSProxyを変えない場合、NSProxyの参照数が増える
システムコールで1つでも名前空間を変えると、変えたNSProxyが新規に作成され、各名前空間の参照数も増える
削除されたときは省略
avashe.icon特にこの辺をカウントするツールはないので、bpftraceの練習問題とかにいいかもしれない
各名前空間は基本コンパイル時に初期化されるが、Mount名前空間だけは実行時に初期化される
参考文献
終盤に名前空間使用時のオーバーヘッドを計測した話もある
観測できる程度にはあるが、チューニングの対象にならない程度に少ない印象