Namespace | Linux
Namespaceはプロセスが参照するPID(プロセスID)番号空間やマウントポイントなど、カーネルリソースを他のプロセスと隔離し、独立したOS環境のように見せる機能です。
Namespaceはすべてのプロセスに関連付けられていて、指定がない限り親プロセスと同じNamespaceを参照します。新しくNamespaceが作成されていない環境において、全てのプロセスはPID1と同じNamespaceを参照し、プロセス間で共通のカーネルリソースを扱います。
ref. コンテナ技術入門 - 仮想化との違いを知り、要素技術を触って学ぼう
種類
Namespace は 7 つの種類がる。
Mount Namespace: マウントポイントを隔離してプロセス独自のファイルシステムを扱えるようにします。
PID Namespace: PID番号空間を隔離してユニークなPIDを持ちます。新しいNamespaceで最初に作成されたプロセスはPID1となり、通常のPID1プロセスと同様の特性を持ちます。
Network Namespace: ネットワークスタックを隔離します(後に解説あり)。
IPC Namespace: SysV IPCオブジェクト、 POSIXキューを隔離します。
UTS Namespace: ホスト名やNISドメイン名など、 unameシステムコールで返される情報を隔離します。
User Namespace: User ID, Group IDを隔離します。Namespace内ではUser IDが0で特権ユーザーである一方、他のNamespaceからは非特権ユーザーとして扱われる、という状態を持つことができます。
Cgroup Namespace: cgroupルートディレクトリを隔離します。新しくCgroup Namespaceを作成すると現在のcgroupディレクトリがcgroupルートディレクトリになります。
ref. コンテナ技術入門 - 仮想化との違いを知り、要素技術を触って学ぼう
Inter Process Communication(IPC)はプログラムの実行単位であるプロセスの間で行われるデータ交換のことを指します。
ref. https://qiita.com/MoriokaReimen/items/5c4256ef620499a88bb3
Namespace 一覧
Amazon の Ubuntu 22.04.4 LTS デフォルトで lsns を実行。
$ sudo lsns
NS TYPE NPROCS PID USER COMMAND
4026531834 time 96 1 root /sbin/init
4026531835 cgroup 96 1 root /sbin/init
4026531836 pid 96 1 root /sbin/init
4026531837 user 96 1 root /sbin/init
4026531838 uts 92 1 root /sbin/init
4026531839 ipc 96 1 root /sbin/init
4026531840 net 96 1 root /sbin/init
4026531841 mnt 89 1 root /sbin/init
4026531862 mnt 1 19 root kdevtmpfs
4026532223 mnt 1 153 root /lib/systemd/systemd-udevd
4026532224 uts 1 153 root /lib/systemd/systemd-udevd
4026532226 mnt 1 313 systemd-network /lib/systemd/systemd-networkd
4026532227 mnt 1 315 systemd-resolve /lib/systemd/systemd-resolved
4026532228 mnt 2 383 _chrony /usr/sbin/chronyd -F 1
4026532229 uts 2 383 _chrony /usr/sbin/chronyd -F 1
4026532285 mnt 1 413 root /lib/systemd/systemd-logind
4026532286 uts 1 413 root /lib/systemd/systemd-logind
個別プロセスの Namespace を確認
- プロセス ID を取得
- /proc//ns を確認
// ps auxf | grep などで プロセス ID を取得
$ ll /proc//ns
total 0
dr-x--x--x 2 ubuntu ubuntu 0 Apr 20 00:09 ./
dr-xr-xr-x 9 ubuntu ubuntu 0 Apr 20 00:09 ../
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 cgroup -> 'cgroup:[4026531835]' <--- 例えば cgroup はデフォルトの 4026531835
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 mnt -> 'mnt:[4026531841]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 net -> 'net:[4026531840]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:19 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 time -> 'time:[4026531834]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:19 time_for_children -> 'time:[4026531834]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 user -> 'user:[4026531837]'
lrwxrwxrwx 1 ubuntu ubuntu 0 Apr 20 00:09 uts -> 'uts:[4026531838]'
## Namespace 確認
プロセスの Namespace は `/proc/PID/ns` で確認できる。
## コマンド
- clone
- unshare
- setns
- lsns
### unshare
## unshare
```shell
# プロセスを隔離
$ unshare --mount-proc -uipr --fork /bin/sh
–mount-proc[=mountpoint] Just before running the program, mount the proc filesystem at mountpoint (default is /proc). This is useful when creating a new PID namespace. It also implies creating a new mount namespace since the /proc mount would otherwise mess up existing programs on the system. The new proc filesystem is explicitly mounted as private (with MS_PRIVATE|MS_REC).
-u, –uts[=file] Create a new UTS namespace. If file is specified, then the namespace is made persistent by creating a bind mount at file.
-i, –ipc[=file] Create a new IPC namespace. If file is specified, then the namespace is made persistent by creating a bind mount at file.
-p, –pid[=file] Create a new PID namespace. If file is specified, then the namespace is made persistent by creating a bind mount at file. (Creation of a persistent PID namespace will fail if the –fork option is not also specified.)
-r, –map-root-user Run the program only after the current effective user and group IDs have been mapped to the superuser UID and GID in the newly created user namespace. This makes it possible to conveniently gain capabilities needed to manage various aspects of the newly created namespaces (such as configuring interfaces in the network namespace or mounting filesystems in the mount namespace) even when run unprivileged. As a mere convenience feature, it does not support more sophisticated use cases, such as mapping multiple ranges of UIDs and GIDs. This option implies –setgroups=deny and –user. This option is equivalent to –map-user=0 –map-group=0.
-f, –fork Fork the specified program as a child process of unshare rather than running it directly. This is useful when creating a new PID namespace. Note that when unshare is waiting for the child process, then it ignores SIGINT and SIGTERM and does not forward any signals to the child. It is necessary to send signals to the child process.