接續昨天的實驗,我們用 unshare
指令做出了一個新的 PID namespace,其 id 為 4026532207:
$ sudo lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026531836 pid 111 1 root /sbin/init
4026532207 pid 1 42009 root /bin/bash
讓我們在這個 4026532207 PID namespace 中執行一些時間比較長的指令,例如睡個幾千秒好了:
root@ip-xxx:/home/ubuntu# sleep 2000 &
[1] 13
root@ip-xxx:/home/ubuntu# sleep 2001 &
[2] 15
root@ip-xxx:/home/ubuntu# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 15:35 pts/1 00:00:00 /bin/bash
root 13 1 0 15:54 pts/1 00:00:00 sleep 2000
root 15 1 0 16:05 pts/1 00:00:00 sleep 2001
root 16 1 0 16:05 pts/1 00:00:00 ps -ef
透過 ps
指令可以觀察到,在這個新的 PID namespace 中,可以看到在這個 namespace 啟動的所有 processes,且除了 /bin/bash
(PID 為 1) 的其他 processes 的 PPID 皆為 1。
回到 Host 看一下:
ubuntu@ip-xxx:~$ sudo ps -e -o pidns,pid,ppid,args
PIDNS PID PPID COMMAND
4026531836 1 0 /sbin/init
...略
4026531836 42007 41758 sudo unshare --pid --fork --mount-proc /bin/bash
4026531836 42008 42007 unshare --pid --fork --mount-proc /bin/bash
4026532207 42009 42008 /bin/bash
...略
4026532207 42050 42009 sleep 2000
4026532207 42088 42009 sleep 2001
4026531836 42090 41674 sudo ps -e -o pidns,pid,ppid,args
4026531836 42091 42090 ps -e -o pidns,pid,ppid,args
在 Host 是可以看到在新的這個 PID namespace 4026532207 中啟動的 3 個 processes: /bin/bash
, sleep 2000
與 sleep 2001
,在 Host 裡 /bin/bash
的 PID 是 42009,sleep 2000
跟 sleep 2001
的 PPID 也是 42009。
如果我們在這個新建立的 PID namespace 4026532207 中又再執行一次 unshare
會發生什麼事呢?
root@ip-xxx:/home/ubuntu# unshare --pid --fork --mount-proc /bin/bash
root@ip-xxx:/home/ubuntu#
看起來好像什麼事都沒發生?用 lsns
看看:
root@ip-xxx:/home/ubuntu# lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026532209 pid 2 1 root /bin/bash
可以看到,現在的 PID namespace 已經變成 4026532209 了,一樣啟動幾個時間比較長的 process 看看:
root@ip-xxx:/home/ubuntu# sleep 3000 &
[1] 9
root@ip-xxx:/home/ubuntu# sleep 3001 &
[2] 10
root@ip-xxx:/home/ubuntu# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 16:25 pts/1 00:00:00 /bin/bash
root 9 1 0 16:28 pts/1 00:00:00 sleep 3000
root 10 1 0 16:28 pts/1 00:00:00 sleep 3001
root 11 1 0 16:28 pts/1 00:00:00 ps -ef
回到 Host 看看:
ubuntu@ip-xxx:~$ sudo lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026531836 pid 111 1 root /sbin/init
4026532207 pid 4 42009 root /bin/bash
4026532209 pid 1 42196 root /bin/bash
ubuntu@ip-xxx:~$ sudo ps -e -o pidns,pid,ppid,args | grep 4026532209
4026532209 42196 42195 /bin/bash
4026532209 42208 42196 sleep 3000
4026532209 42209 42196 sleep 3001
4026531836 42216 41674 grep --color=auto 4026532209
果然成功地多了一個新的 PID namespace 了,而且也可以看到 sleep 3000
跟 sleep 3001
這兩個 processes。
如果我想觀察看看在 4026532207 中能不能觀察到 4026532209 中的 processes,那就要先回到 4026532207 這個 namespace 中,如果用 exit
指令離開的話,這會終止 /bin/bash
這個 PID 為 1 的 process,這個時候 PID namespace 4026532209 也就跟著不見了(這個之後應該會討論到),因為我目前也不知道其他方式,所以還是先用 exit
離開,並且用背景的方式重新做一個 namespace 出來:
root@ip-xxx:/home/ubuntu# unshare --pid --fork --mount-proc sleep 5000 &
[1] 23
root@ip-xxx:/home/ubuntu# lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026532207 pid 3 1 root /bin/bash
4026532209 pid 1 24 root sleep 5000
root@ip-xxx:/home/ubuntu# ps -e -o pidns,pid,ppid,args
PIDNS PID PPID COMMAND
4026532207 1 0 /bin/bash
4026532207 23 1 unshare --pid --fork --mount-proc sleep 5000
4026532209 24 23 sleep 5000
4026532207 26 1 ps -e -o pidns,pid,ppid,args
這邊可以看到,一樣是在 4026532207 PID namespace 中建立了一個新的 PID namespace 4026532209,而在 4026532207 這裡是可以看到 4026532209 裡正在跑的 sleep 5000
。
回到 Host 看一下:
ubuntu@ip-xxx:~$ sudo lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026531836 pid 116 1 root /sbin/init
4026532207 pid 2 42400 root /bin/bash
4026532209 pid 1 42438 root sleep 5000
到這邊,我們可以先整理幾個觀察與網路上讀到的資料:
讓我們從 root PID namespace 再去建立一個新的 PID namespace:
ubuntu@ip-xxx:~$ sudo unshare --pid --fork --mount-proc /bin/bash
root@ip-xxx:/home/ubuntu# sleep 4000 &
[1] 8
root@ip-xxx:/home/ubuntu# sleep 4001 &
[2] 9
root@ip-xxx:/home/ubuntu# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 16:44 pts/2 00:00:00 /bin/bash
root 8 1 0 16:45 pts/2 00:00:00 sleep 4000
root 9 1 0 16:45 pts/2 00:00:00 sleep 4001
root 10 1 0 16:45 pts/2 00:00:00 ps -ef
root@ip-xxx:/home/ubuntu# lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026532211 pid 4 1 root /bin/bash
在這個新的 PID namespace 4026532211 中是看不到其他 PID namespace 的 processes 的。
回到第一個被建立出來的 PID namespace 4026532207 中:
(實驗做太久,剛剛的 sleep 2000 已經睡醒了,重新跑一下,所以會排在後面)
root@ip-xxx:# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 16:56 pts/1 00:00:00 /bin/bash
root 23 1 0 17:03 pts/1 00:00:00 unshare --pid --fork --mount-proc sleep 5000
root 24 23 0 17:03 pts/1 00:00:00 sleep 5000
root 29 1 0 17:07 pts/1 00:00:00 sleep 2000
root 30 1 0 17:07 pts/1 00:00:00 sleep 2001
root 32 1 0 17:07 pts/1 00:00:00 ps -ef
這裡也一樣看不到 4026532211 中的 processes(但可以看到自已小孩 4026532209 裡的 process sleep 5000
喔)。
回到 Host:
ubuntu@ip-xxx:~$ sudo lsns -t pid
NS TYPE NPROCS PID USER COMMAND
4026531836 pid 116 1 root /sbin/init
4026532207 pid 4 42400 root /bin/bash
4026532209 pid 1 42438 root sleep 5000
4026532211 pid 3 42447 root /bin/bash
ubuntu@ip-xxx:~$ sudo ps -e -o pidns,pid,ppid,args | grep 4026532209
4026532209 42438 42437 sleep 5000
4026531836 42472 41674 grep --color=auto 4026532209
ubuntu@ip-xxx:~$ sudo ps -e -o pidns,pid,ppid,args | grep 4026532211
4026532211 42447 42446 /bin/bash
4026532211 42455 42447 sleep 4000
4026532211 42456 42447 sleep 4001
4026531836 42475 41674 grep --color=auto 4026532211
Host 中可以看到新建立出來的 3 個 PID namespaces,也可以看到 4026532211 中的 processes。
用圖片示意一下 PID namespace 的父子關係,到這裡也可以發現,上對下是一覽無遺的,但下無法看到上的,平輩之間的也看不到。
我們利用 unshare
這個指令手動作出了不同的 PID namespace,也在其中執行了一些 processes,好用來觀察這些 processes 在不同的 namespace 中的「可見」程度,之後將會試著用別的方式再驗證一次,也會討論這些實驗跟 container 之間的關聯,是不是很好玩也很期待呢?