[root@namespace-01 ~]# ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x2e011e55 0 root 644 0 0
显示当前进程pid
[root@namespace-01 ~]# echo $$
1459
* terminal-2
在另一个终端中创建新的ipc namespace和uts namespace
[root@localhost ~]# unshare --uts --ipc bash
修改hostname便于区分
[root@localhost ~]# hostname namespace-02 && exec bash
确保不在同一个namespace
[root@namespace-02 ~]# readlink /proc/$$/ns/{uts,ipc}
uts:[4026532501]
ipc:[4026532502]
查看当前namespace的ipc对象,无法看到msqid为0的MQ
[root@namespace-02 ~]# ipcs
------ Message Queues --------
key msqid owner perms used-bytes messages
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
* terminal-3
在namespace01中执行新的bash
[root@localhost ~]# nsenter --target 1459 --uts --ipc bash
查看inode number,确保与terminal-1中一致
[root@namespace-01 ~]# readlink /proc/$$/ns/{uts,ipc}
uts:[4026532499]
ipc:[4026532500]
查看ipc对象信息
[root@namespace-01 ~]# ipcs
------ Message Queues --------
key msqid owner perms used-bytes messages
0x2e011e55 0 root 644 0 0
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
>
> * ipc namespace与uts namespace都不存在嵌套或者上下级关系
> * 这里使用了三个终端和两个ipc namespace,为便于观察,分别设置了两个hostname
>
>
>
### 4、pid namespace
pid namespace是用来隔离进程号的,也就是说,同一个系统中,在不同的namespace下可以存在相同pid的两个进程。比如两个pid都为1的两个进程。
在Linux系统中,pid为大于等于1的整数,且不能重复,进程退出后,pid将回收利用。pid为1的进程是内核启动的第一个进程,通常为init或者systemd。后续启动的其他进程都是该进程的子进程,当init或者systemd进程退出时,系统也就退出了。
查看当前系统状态的进程树信息,其实进程为systemd(1),括号内为pid
[root@localhost ~]# pstree -pl
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(657)
├─auditd(614)───{auditd}(615)
├─crond(653)
├─dbus-daemon(641)───{dbus-daemon}(646)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(490)
├─master(1259)─┬─pickup(1265)
│ └─qmgr(1266)
├─polkitd(639)─┬─{polkitd}(648)
│ ├─{polkitd}(649)
│ ├─{polkitd}(652)
│ ├─{polkitd}(658)
│ └─{polkitd}(661)
├─rsyslogd(970)─┬─{rsyslogd}(974)
│ └─{rsyslogd}(975)
├─sshd(969)───sshd(1421)───bash(1425)───pstree(1630)
├─systemd-journal(462)
├─systemd-logind(640)
├─systemd-udevd(498)
└─tuned(968)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)
在每个pid namespace中都存在着一颗类似的进程树,都有一个pid为1的进程。当某个进程(pid != 1)退出时,内核会指定pid为1的进程成为其子进程的父进程。当pid为1的进程停止时,内核会杀死该namespace中的所有的其他进程,namespace销毁。
pid namespace允许嵌套,存在上下级关系。新创建的namespace属于创建进程所在namespace的下级,上级namespace可以看到\*\*\*所有下级\*\*\*namespace的进程信息,无法看到上级或者平级namespace的进程信息。
与其他namespace不同,进程的pid namespace无法更改,即使调用setns(2)也只会影响当前进程的子进程。
* terminal-1
创建新的pid namespace、uts namespace和mnt namespace,运行bash,–fork表示以(unshare的)子进程运行bash程序
[root@localhost ~]# unshare --pid --uts --mount --fork bash
设置hostname以便于区分
[root@namespace-01 ~]# hostname namespace-01 && exec bash
查看进程树,依然可以看到完整的进程树,因为pstree读取/proc目录的信息,而/proc继承自unshare所在的mount namespace
[root@namespace-01 ~]# pstree -pl
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(657)
├─auditd(614)───{auditd}(615)
├─crond(653)
├─dbus-daemon(641)───{dbus-daemon}(646)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(490)
├─master(1259)─┬─pickup(1812)
│ └─qmgr(1266)
├─polkitd(639)─┬─{polkitd}(648)
│ ├─{polkitd}(649)
│ ├─{polkitd}(652)
│ ├─{polkitd}(658)
│ └─{polkitd}(661)
├─rsyslogd(970)─┬─{rsyslogd}(974)
│ └─{rsyslogd}(975)
├─sshd(969)───sshd(1421)───bash(1425)───unshare(1792)───bash(1793)───pstree(1816) # bash进行的父进程是unshare(1792),当前进程为bash(1793)
├─systemd-journal(462)
├─systemd-logind(640)
├─systemd-udevd(498)
└─tuned(968)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)
查看进程号,当前进程号为1
[root@namespace-01 ~]# echo $$
1
查看inode number,此时的$$读取的进程信息为unshare所在的mount namespace对应的inode信息
[root@namespace-01 ~]# readlink /proc/$$/ns/{pid,uts,mnt}
pid:[4026531836]
uts:[4026531838]
mnt:[4026531840]
[root@namespace-01 ~]# readlink /proc/1793/ns/{pid,uts,mnt}
pid:[4026532501]
uts:[4026532500]
mnt:[4026532499]
重新挂载proc
[root@namespace-01 ~]# mount --types proc proc /proc/
再次查看进程树,仅能看到当前namespace的进行信息
[root@namespace-01 ~]# pstree -pl
bash(1)───pstree(45)
查看$$对应的namespace的inode,显示1793对应的信息
[root@namespace-01 ~]# readlink /proc/$$/ns/{pid,uts,mnt}
pid:[4026532501]
uts:[4026532500]
mnt:[4026532499]
* terminal-2
查看进程树,依然显示完整的进程树信息,说明上级namespace可以看到夏季namespace的pid信息,且显示相对于当前namespace的pid
[root@localhost ~]# pstree -pl
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(657)
├─auditd(614)───{auditd}(615)
├─crond(653)
├─dbus-daemon(641)───{dbus-daemon}(646)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(490)
├─master(1259)─┬─pickup(1812)
│ └─qmgr(1266)
├─polkitd(639)─┬─{polkitd}(648)
│ ├─{polkitd}(649)
│ ├─{polkitd}(652)
│ ├─{polkitd}(658)
│ └─{polkitd}(661)
├─rsyslogd(970)─┬─{rsyslogd}(974)
│ └─{rsyslogd}(975)
├─sshd(969)─┬─sshd(1421)───bash(1425)───unshare(1792)───bash(1793)
│ └─sshd(1848)───bash(1852)───pstree(1867)
├─systemd-journal(462)
├─systemd-logind(640)
├─systemd-udevd(498)
└─tuned(968)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)
查看inode number
[root@localhost ~]# readlink /proc/$$/ns/{pid,uts,mnt}
pid:[4026531836]
uts:[4026531838]
mnt:[4026531840]
创建namespace02并默认挂载proc
[root@localhost ~]# unshare --pid --uts --mount --fork --mount-proc bash
设置hostname以便于区分
[root@localhost ~]# hostname namespace-02 && exec bash
查看inode number
[root@namespace-02 ~]# readlink /proc/$$/ns/{pid,uts,mnt}
pid:[4026532504]
uts:[4026532503]
mnt:[4026532502]
查看当前namespace的进程树,无法看到namespace01的进行信息
[root@namespace-02 ~]# pstree -pl
bash(1)───pstree(19)
* terminal-1
回到namespace01查看进行树信息,依然只有自身namespace下的进程信息,无法看到上级或者namespace02的进行
[root@namespace-01 ~]# pstree -pl
bash(1)───pstree(50)
在namespace01的基础上创建namespace03
[root@namespace-01 ~]# unshare --pid --uts --mount --fork --mount-proc bash
修改hostname以便于区分
[root@namespace-01 ~]# hostname namespace-03 && exec bash
查看inode number,确保为新namespace
[root@namespace-03 ~]# readlink /proc/$$/ns/{pid,uts,mnt}
pid:[4026532507]
uts:[4026532506]
mnt:[4026532505]
查看进程树信息
[root@namespace-03 ~]# pstree -pl
bash(1)───pstree(20)
* terminal-2
回到namespace02查看进程树信息
[root@namespace-02 ~]# pstree -pl
bash(1)───pstree(21)
* terminal-3
查看进程树信息
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(657)
├─auditd(614)───{auditd}(615)
├─crond(653)
├─dbus-daemon(641)───{dbus-daemon}(646)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(490)
├─master(1259)─┬─pickup(1812)
│ └─qmgr(1266)
├─polkitd(639)─┬─{polkitd}(648)
│ ├─{polkitd}(649)
│ ├─{polkitd}(652)
│ ├─{polkitd}(658)
│ └─{polkitd}(661)
├─rsyslogd(970)─┬─{rsyslogd}(974)
│ └─{rsyslogd}(975)
├─sshd(969)─┬─sshd(1421)───bash(1425)───unshare(1792)───bash(1793)───unshare(1929)───bash(1930)
│ ├─sshd(1848)───bash(1852)───unshare(1905)───bash(1906)
│

本文详细介绍了Linux Namespace的概念,通过示例演示了如何创建和管理IPC、UTS、PID、Mount、Network等多个Namespace,展示了如何在不同Namespace中独立运行进程、隔离资源,并讨论了Namespace之间的交互和网络配置,包括IP Forwarding、NAT设置,以及通过veth pair实现跨Namespace通信。此外,文章还探讨了在不同Namespace中设置hostname、查看进程树和管理进程的方法,揭示了Namespace在系统管理和容器技术中的重要应用。
最低0.47元/天 解锁文章
2180

被折叠的 条评论
为什么被折叠?



