目的
- Docker が所属する Namespace を理解する
手段
killercodaで手を動かす
環境
killercoda
Namespace とは
マンションの部屋というイメージです。部屋で同居する人もいれば、単身で暮らす人もいます。
マンションの部屋の中は他の部屋から見えないので、Namespace が異なるコンテナ間はプロセスやファイルシステムが見えない(別になる)ということです。
Namespace 作成
まず、Linux 上の Namespace を確認します。
controlplane:~$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Sep 18 08:16 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 mnt -> 'mnt:[4026531841]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 net -> 'net:[4026531840]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 time -> 'time:[4026531834]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 time_for_children -> 'time:[4026531834]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Sep 18 08:16 uts -> 'uts:[4026531838]'
# icp, mnt, net, pid 等の Namespace が存在します
docker からコンテナを一つ立ち上げてみます。
docker run -d --name app1 nginx:alpine sh -c 'sleep infinity'
# コンテナ起動
controlplane:~$ docker exec -it app1 ls -l /proc/self/ns
total 0
lrwxrwxrwx 1 root root 0 Sep 18 08:17 cgroup -> cgroup:[4026532791]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 ipc -> ipc:[4026532789]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 mnt -> mnt:[4026532787]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 net -> net:[4026532792]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 pid -> pid:[4026532790]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 pid_for_children -> pid:[4026532790]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 time -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 time_for_children -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Sep 18 08:17 uts -> uts:[4026532788]
# Linux 上で確認した Namespace とコンテナが所属している Namespace は異なります
# Linux : 4026531836
# コンテナ(app1) : 4026532790
もう一つ別名でコンテナを立ち上げます。
controlplane:~$ docker run -d --name app2 nginx:alpine sh -c 'sleep infinity'
858a7eafae545dddd6e511dcf6daf25e9416dd8e8fd0732ca79144ad8ffde12a
controlplane:~$ docker exec -it app2 ls -l /proc/self/ns
total 0
lrwxrwxrwx 1 root root 0 Sep 18 08:18 cgroup -> cgroup:[4026532855]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 ipc -> ipc:[4026532853]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 mnt -> mnt:[4026532851]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 net -> net:[4026532856]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 pid -> pid:[4026532854]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 pid_for_children -> pid:[4026532854]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 time -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 time_for_children -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Sep 18 08:18 uts -> uts:[4026532852]
# Linux : 4026531836
# コンテナ(app1) : 4026532790
# コンテナ(app2) : 4026532854
# 想定通り異なる Namespace(pid)に所属しています
既存 Namespace にコンテナを所属させる場合を確認します。
controlplane:~$ docker run -d --name app3 --pid=container:app1 nginx:alpine sleep infinity
6af15d8e14455539cfcf2d4394137d3ab159406993f40d21ded43f3499e6382a
controlplane:~$ docker exec -it app3 ls -l /proc/self/ns
total 0
lrwxrwxrwx 1 root root 0 Sep 18 08:21 cgroup -> cgroup:[4026532918]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 ipc -> ipc:[4026532917]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 mnt -> mnt:[4026532915]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 net -> net:[4026532919]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 pid -> pid:[4026532790]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 pid_for_children -> pid:[4026532790]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 time -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 time_for_children -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Sep 18 08:21 uts -> uts:[4026532916]
# Linux : 4026531836
# コンテナ(app1) : 4026532790
# コンテナ(app2) : 4026532854
# コンテナ(app3) : 4026532790
# 想定通り異なる app1 と app3 は同じ Namespace(pid)に所属しています。
# Namespace(pid)以外は異なるNamespaceに所属しています
同じ Namespace(pid)に所属させるには --pid=container:{container_name}
オプションを付与する必要があります。
また、podman も全く同じコマンドで対応可能です。
controlplane:~$ podman run -d --name app1 nginx:alpine sleep infinity
controlplane:~$ podman run -d --name app2 --pid=container:app1 nginx:alpine sleep infinity
934ab68f2603e26e5261bb91e3379a8b47db0c74ca3f22a68737547c48cc01b6
controlplane:~$ podman exec -it app2 ps aux
PID USER TIME COMMAND
1 root 0:00 sleep infinity
9 root 0:00 sleep infinity
17 root 0:00 ps aux
# app2 の Namespace(pid)で二つの sleep プロセスが確認できます
あとがき
アウトプットは良いですね!