namespaces - Linux 名前空間の概要
名前空間は、
グローバルシステムリソースを抽象化層で覆うことで、
名前空間内のプロセスに対して、
自分たちが専用の分離されたグローバルリソースを持っているかのように見せる仕組みである。
グローバルリソースへの変更は、
名前空間のメンバーである他のプロセスには見えるが、
それ以外のプロセスには見えない。
名前空間の一つの利用方法はコンテナーの実装である。
Linux
では以下の名前空間が提供される。
名前空間 |
定数 |
分離対象 |
IPC |
CLONE_NEWIPC |
System V IPC, POSIX
メッセージキュー |
Network |
CLONE_NEWNET |
ネットワークデバイス、スタック、ポートなど |
Mount |
CLONE_NEWNS |
マウントポイント |
PID |
CLONE_NEWPID |
プロセス ID |
User |
CLONE_NEWUSER |
ユーザー ID
とグループ ID |
UTS |
CLONE_NEWUTS |
ホスト名と NIS
ドメイン名 |
このページでは、各種の名前空間と関連する
/proc
ファイルの説明と、名前空間とともに動作する
API の概要を紹介する。
後で説明する種々の
/proc
ファイル以外に、名前空間
API
として以下のシステムコールがある。
-
clone(2)
-
clone(2)
システムコールは新しいプロセスを作成する。
呼び出し時に flags
引き数で以下のリストにある
CLONE_NEW*
のフラグを一つ以上指定すると、
各フラグに対応する新しい名前空間が作成され、
子プロセスはこれらの名前空間のメンバーになる。
(このシステムコールは名前空間とは関係のない機能も多数実装している。)
-
setns(2)
-
setns(2)
システムコールを使うと、呼び出したプロセスを既存の名前空間に参加させることができる。
参加する名前空間は、
以下で説明する
/proc/[pid]/ns
ファイルのいずれか一つを参照するファイルディスクリプターを使って指定する。
-
unshare(2)
-
unshare(2)
システムコールは、
呼び出したプロセスを新しい名前空間に移動する。
呼び出し時の flags
引き数に以下のリストにある
CLONE_NEW*
フラグを一つ以上指定すると、
各フラグに対応する新しい名前空間が作成され、
呼び出したプロセスがこれらの名前空間のメンバーになる。
(このシステムコールは名前空間とは関係のない機能も多数実装している。)
clone(2) と
unshare(2)
を使った新しい名前空間の作成のほとんどの場合で
CAP_SYS_ADMIN
ケーパビリティが必要である。
ユーザー名前空間は例外で、
Linux 3.8
以降ではユーザー名前空間を作成するのに特権が不要である。
各プロセスには
/proc/[pid]/ns/
サブディレクトリがあり、
このサブディレクトリには
setns(2)
での操作がサポートされている名前空間単位にエントリーが存在する。
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 net -> net:[4026531956]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 pid -> pid:[4026531836]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 user -> user:[4026531837]
lrwxrwxrwx. 1 mtk mtk 0 Jan 14 01:20 uts -> uts:[4026531838]
このディレクトリ内のファイルのいずれかをファイルシステムの他のどこかにバインドマウント
(
mount(2) 参照)
することで、
その名前空間のすべてのプロセスが終了した場合でも、
pid
で指定したプロセスの対応する名前空間を保持することができる。
このディレクトリ内のファイルのいずれか
(またはこれらのファイルのいずれかにバインドマウントされたファイル)
をオープンすると、
pid
で指定されたプロセスの対応する名前空間に対するファイルハンドルが返される。
このファイルディスクリプターがオープンされている限り、
その名前空間のすべてのプロセスが終了した場合であっても、
その名前空間は存在し続ける。
このファイルディスクリプターは
setns(2)
に渡すことができる。
Linux 3.7
以前では、これらのファイルはハードリンクとして見えていた。
Linux 3.8
以降では、これらはシンボリックリンクとして見える。
2
つのプロセスが同じ名前空間に所属している場合、
これらのプロセスの
/proc/[pid]/ns/xxx
シンボリックリンクの
inode 番号は同じになる。
アプリケーションは、
stat(2) が返す
stat.st_ino
フィールドを使ってこれを確認することができる。
シンボリックリンクの内容は、
以下の例にあるように、名前空間種別と
inode
番号を含む文字列である。
$ readlink /proc/$$/ns/uts
uts:[4026531838]
このサブディレクトリのファイルは以下のとおりである。
-
/proc/[pid]/ns/ipc (Linux 3.0 以降)
- このファイルはそのプロセスの
IPC
名前空間の操作用である。
-
/proc/[pid]/ns/mnt (Linux 3.8 以降)
- このファイルはそのプロセスのマウント名前空間の操作用である。
-
/proc/[pid]/ns/net (Linux 3.0 以降)
- このファイルはそのプロセスのネットワーク名前空間の操作用である。
-
/proc/[pid]/ns/pid (Linux 3.8 以降)
- このファイルはそのプロセスの
PID
名前空間の操作用である。
-
/proc/[pid]/ns/user (Linux 3.8
以降)
- このファイルはそのプロセスのユーザー名前空間の操作用である。
-
/proc/[pid]/ns/uts (Linux 3.0 以降)
- このファイルはそのプロセスの
UTS
名前空間の操作用である。
IPC 名前空間は、 特定の
IPC
リソース、すなわち、System
V IPC オブジェクト (
svipc(7)
参照)、(Linux 2.6.30 以降では) POSIX
メッセージキュー (
mq_overview(7) 参照)
を分離する。
これらの IPC
機構に共通の特徴は、
IPC
オブジェクトがファイルシステムのパス名以外の方法で識別されるという点である。
各 IPC
名前空間はそれぞれ、
独自の System V IPC
識別子の集合と独自の
POSIX
メッセージキューファイルシステムを持つ。
IPC
名前空間に作成されたオブジェクトは、
その名前空間のメンバーの他のすべてのプロセスにも見えるが、
他の IPC
名前空間のプロセスには見えない。
以下の
/proc
インターフェースは各
IPC
名前空間で別のものとなる。
- *
-
/proc/sys/fs/mqueue の POSIX
メッセージキューインターフェース。
- *
-
/proc/sys/kernel の System V IPC
インターフェース。
すなわち、 msgmax, msgmnb,
msgmni, sem, shmall, shmmax, shmmni,
shm_rmid_forced。
- *
-
/proc/sysvipc の System V IPC
インターフェース。
IPC
名前空間が破棄されたときに
(すなわち、その名前空間のメンバーの最後のプロセスが終了したときに)、
その名前空間内のすべての
IPC
オブジェクトが自動的に破棄される。
IPC
名前空間を使用するには、設定
CONFIG_IPC_NS
が有効になったカーネルが必要である。
ネットワーク名前空間は、
ネットワークに関連するシステムリソースの分離を提供する。
分離されるリソースは、
ネットワークデバイス、
IPv4 と IPv6
のプロトコルスタック、
IP
ルーティングテーブル、
ファイアウォール、
/proc/net ディレクトリ、
/sys/class/net ディレクトリ、
(ソケットの)
ポート番号などである。
物理ネットワークデバイスは
1
つのネットワーク名前空間にのみ属すことができる。
仮想ネットワークデバイス
("veth") ペアは、
ネットワーク名前空間間のトンネルを作成するのに使うことができるパイプ風の抽象概念で、
別の名前空間に属す物理ネットワークデバイスへのブリッジを作成するのに使用できる。
ネットワーク名前空間が解放されたときに
(すなわち、その名前空間の最後のプロセスがしゅうりょうしたときに)、
その名前空間に属していた物理ネットワークデバイスは初期ネットワーク名前空間に戻される
(プロセスの親プロセスに戻されるわけではない)。
ネットワーク名前空間を使用するには、設定
CONFIG_NET_NS
が有効になったカーネルが必要である。
マウント名前空間はファイルシステムのマウントポイントの集合を分離する。
つまり、別のマウント名前空間のプロセスには別のファイルシステム階層が見えるということである。
マウント名前空間内のマウントの集合は
mount(2) と
umount(2)
で変更される。
/proc/[pid]/mounts ファイル (Linux 2.4.19
以降に存在) は、
そのプロセスのマウント名前空間で現在マウントされている全ファイルシステムの一覧を表示する。
このファイルのフォーマットは
fstab(5)
に記載されている。
カーネルバージョン
2.6.15
以降では、このファイルをポーリングすることができる。
すなわち、このファイルを読み出し用にオープンした後、
このファイルの変化
(ファイルシステムのマウントやアンマウント)
が発生すると、
select(2)
はファイルディスクリプターが読み出し可能になったと印を付け、
poll(2) や
epoll_wait(2)
はファイルがエラー状態になったかのように印を付ける。
/proc/[pid]/mountstats ファイル (Linux 2.6.17
以降に存在) は、
そのプロセスのマウントポイントに関する情報
(統計情報、設定情報)
を公開する。
このファイルはプロセスの所有者だけが読み出し可能である。
このファイルの各行は以下の形式である。
device /dev/sda7 mounted on /home with fstype ext3 [statistics]
( 1 ) ( 2 ) (3 ) (4)
各行のフィールドは以下のとおりである。
- (1)
- マウントされているデバイス名
(もしくは、対応するデバイスがない場合は
"nodevice")。
- (2)
- ファイルシステムツリー内のマウントポイント。
- (3)
- ファイルシステム種別
- (4)
- 統計情報と設定情報。
オプションフィールドである。
現在のところ (Linux 2.6.26
時点)、NFS
ファイルシステムだけがこのフィールドで情報を公開している。
pid_namespaces(7) 参照。
user_namespaces(7) 参照。
UTS 名前空間は、
ホスト名と NIS
ドメイン名の 2
つのシステム識別子を分離する。
これらの識別子は
sethostname(2) と
setdomainname(2)
を使って設定でき、
uname(2),
gethostname(2),
getdomainname(2)
を使って取得できる。
UTS
名前空間を使用するには、設定
CONFIG_UTS_NS
が有効になったカーネルが必要である。
名前空間は Linux
独自の機能である。
user_namespaces(7) 参照。
nsenter(1),
readlink(1),
unshare(1),
clone(2),
setns(2),
unshare(2),
proc(5),
credentials(7),
capabilities(7),
pid_namespaces(7),
user_namespaces(7),
switch_root(8)
この man ページは Linux
man-pages
プロジェクトのリリース
3.79 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。