2024年运维最全Linux namespace简介_nmskp(1)

       ├─agetty(653)
       ├─auditd(614)───{auditd}(615)
       ├─crond(649)
       ├─dbus-daemon(638)───{dbus-daemon}(643)
       ├─firewalld(663)───{firewalld}(791)
       ├─lvmetad(489)
       ├─master(1261)─┬─pickup(1267)
       │              └─qmgr(1268)
       ├─polkitd(644)─┬─{polkitd}(655)
       │              ├─{polkitd}(656)
       │              ├─{polkitd}(657)
       │              ├─{polkitd}(660)
       │              └─{polkitd}(661)
       ├─rsyslogd(968)─┬─{rsyslogd}(973)
       │               └─{rsyslogd}(982)
       ├─sshd(970)───sshd(1421)───bash(1425)───bash(1717)───pstree(1726)   # 比上面多出一个bash(1717)
       ├─systemd-journal(462)
       ├─systemd-logind(646)
       ├─systemd-udevd(498)
       └─tuned(967)─┬─{tuned}(1362)
                    ├─{tuned}(1363)
                    ├─{tuned}(1364)
                    └─{tuned}(1378)

1717与1425的uts inode number不同,说明这两个线程处在不同的namespace

[root@localhost ~]# readlink /proc/$$/ns/uts /proc/1717/ns/uts
uts:[4026532418]
uts:[4026532418]

设置当前进程的hostname

[root@localhost ~]# hostname namespace-01

新的hostname不会立即生效,执行exec bash,使用新bash取代当前bash,使hostname生效

[root@localhost ~]# exec bash

查看hostname

[root@namespace-01 ~]# hostname
namespace-01


* terminal-2



在另一个终端中查看进程树

[root@localhost ~]# pstree -pl
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(653)
├─auditd(614)───{auditd}(615)
├─crond(649)
├─dbus-daemon(638)───{dbus-daemon}(643)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(489)
├─master(1261)─┬─pickup(1267)
│ └─qmgr(1268)
├─polkitd(644)─┬─{polkitd}(655)
│ ├─{polkitd}(656)
│ ├─{polkitd}(657)
│ ├─{polkitd}(660)
│ └─{polkitd}(661)
├─rsyslogd(968)─┬─{rsyslogd}(973)
│ └─{rsyslogd}(982)
├─sshd(970)─┬─sshd(1421)───bash(1425)───bash(1717) # terminal-1对应的进程信息
│ └─sshd(1740)───bash(1744)───pstree(1759) # 当前进程对应的信息
├─systemd-journal(462)
├─systemd-logind(646)
├─systemd-udevd(498)
└─tuned(967)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)

查看当前进程的uts

[root@localhost ~]# readlink /proc/$$/ns/uts /proc/1744/ns/uts
uts:[4026531838]
uts:[4026531838]

查看当前进程的hostname

[root@localhost ~]# hostname
localhost.localdomain

在termenal-2中创建新的uts namespace

[root@localhost ~]# unshare --uts bash

查看进程树

[root@localhost ~]# pstree -pl
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(653)
├─auditd(614)───{auditd}(615)
├─crond(649)
├─dbus-daemon(638)───{dbus-daemon}(643)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(489)
├─master(1261)─┬─pickup(1267)
│ └─qmgr(1268)
├─polkitd(644)─┬─{polkitd}(655)
│ ├─{polkitd}(656)
│ ├─{polkitd}(657)
│ ├─{polkitd}(660)
│ └─{polkitd}(661)
├─rsyslogd(968)─┬─{rsyslogd}(973)
│ └─{rsyslogd}(982)
├─sshd(970)─┬─sshd(1421)───bash(1425)───bash(1717)
│ └─sshd(1740)───bash(1744)───bash(1763)───pstree(1772) # 新进程1763
├─systemd-journal(462)
├─systemd-logind(646)
├─systemd-udevd(498)
└─tuned(967)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)

查看当前进程的uts

[root@localhost ~]# readlink /proc/$$/ns/uts /proc/1763/ns/uts
uts:[4026532499]
uts:[4026532499]

设置hostname

[root@localhost ~]# hostname namespace-02
[root@localhost ~]# exec bash

查看hostname

[root@namespace-02 ~]# hostname
namespace-02


目前的状态大概是这个样子:



                        +-----------------------------------+
                        |  hostname: localhost.localdomain  |
                    +---+  uts: 4026531838                  +---+
                    |   |  pid: 1425, 1744                  |   |
                    |   +-----------------------------------+   |
                    v                                           v
 +-----------------------------------+        +-----------------------------------+
 |  hostname: namespace-01           |        |  hostname: namespace-02           |
 |  uts: 4026532418                  |        |  uts: 4026532499                  |
 |  pid: 1717                        |        |  pid: 1763                        |
 +-----------------------------------+        +-----------------------------------+

三个namespace之间设置的hostname互不影响,所有进程退出之后,namespace将被自动删除,inode number回收利用:


* terminal-1



退出namespace-01对应的bash

[root@namespace-01 ~]# exit
exit

查看当前状态的进程树

[root@localhost ~]# pstree -pl
systemd(1)─┬─NetworkManager(664)─┬─{NetworkManager}(671)
│ └─{NetworkManager}(678)
├─agetty(653)
├─auditd(614)───{auditd}(615)
├─crond(649)
├─dbus-daemon(638)───{dbus-daemon}(643)
├─firewalld(663)───{firewalld}(791)
├─lvmetad(489)
├─master(1261)─┬─pickup(1785)
│ └─qmgr(1268)
├─polkitd(644)─┬─{polkitd}(655)
│ ├─{polkitd}(656)
│ ├─{polkitd}(657)
│ ├─{polkitd}(660)
│ └─{polkitd}(661)
├─rsyslogd(968)─┬─{rsyslogd}(973)
│ └─{rsyslogd}(982)
├─sshd(970)─┬─sshd(1421)───bash(1425)───pstree(1792) # 当前进程1425,1717进程已退出
│ └─sshd(1740)───bash(1744)───bash(1763)
├─systemd-journal(462)
├─systemd-logind(646)
├─systemd-udevd(498)
└─tuned(967)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)

查看hostname

[root@localhost ~]# hostname
localhost.localdomain

查看当前进程和1717进程的uts,仅显示localhost.localdomain的uts,且1717对应目录以被删除

[root@localhost ~]# readlink /proc/$$/ns/uts /proc/1717/ns/uts
uts:[4026531838]


Uts namespace不存在嵌套和上下级关系,***namespace本身并不是一个集合或者容器,而是进程的属性,属性值相同的进程同属于一个namespace~***


* terminal-1



在namespace-02中执行新的bash,1763为目标的进程pid,–uts表示与1763进程使用相同的uts namespace

[root@localhost ~]# nsenter --target 1763 --uts bash

新bash对应的uts namespace inode number与namespace-02相同

[root@namespace-02 ~]# readlink /proc/$$/ns/uts
uts:[4026532499]
[root@namespace-02 ~]# hostname
namespace-02


### 2、mnt namespace


Mount namespace的作用是隔离mount point,每个mnt namespace内的文件结构可以单独修改,互不影响。



当前进程所在的mnt namespace的所有挂载点信息记录在以下三个文件中

[root@localhost ~]# ll /proc/$$/mount*
-r–r–r–. 1 root root 0 Feb 20 12:24 /proc/1425/mountinfo
-r–r–r–. 1 root root 0 Feb 20 12:24 /proc/1425/mounts
-r--------. 1 root root 0 Feb 20 12:24 /proc/1425/mountstats

为接下来的操作准备两个目录,每个目录下一个文件

[root@localhost ~]# mkdir namespace01 && touch namespace01/namespace01.txt
[root@localhost ~]# mkdir namespace02 && touch namespace02/namespace02.txt


* terminal-1



创建新的mount namespace和uts namespace并运行bash

[root@localhost ~]# unshare --mount --uts bash

设置hostname以便于观察

[root@localhost ~]# hostname namespace-01 && exec bash

查看对应namespace的inode number

[root@namespace-01 ~]# readlink /proc/$$/ns/{uts,mnt}
uts:[4026532499]
mnt:[4026532418]

将上面创建的namespace01目录挂在到/mnt

[root@namespace-01 ~]# mount --bind namespace01/ /mnt/

查看/mnt目录下的文件

[root@namespace-01 ~]# ll /mnt/
total 0
-rw-r–r–. 1 root root 0 Feb 20 12:46 namespace01.txt


* terminal-2



在另一个终端上创建新的mount namespace和uts namespace,执行bash

[root@localhost ~]# unshare --mount --uts bash

设置对应的hostname以便于区别

[root@localhost ~]# hostname namespace-02 && exec bash

查看对应的inode number,确保与terminal-1中的进程不在同一个namespace

[root@namespace-02 ~]# readlink /proc/$$/ns/{uts,mnt}
uts:[4026532501]
mnt:[4026532500]

挂载namespace02之前,首先查看/mnt目录,证实namespace02无法看到与namespace01相同的内容

[root@namespace-02 ~]# ll /mnt/
total 0

将namespace02目录挂在到/mnt

[root@namespace-02 ~]# mount --bind namespace02/ /mnt/

查看/mnt目录下的文件

[root@namespace-02 ~]# ll /mnt/
total 0
-rw-r–r–. 1 root root 0 Feb 20 12:46 namespace02.txt


当新的mount namespace创建时,会从创建进程所在的namespace复制挂载点信息,所以namespace01和namespace02都可以看到相同的文件视图


* terminal-1



在terminal-1下继续创建namespace03

[root@namespace-01 ~]# unshare --mount --uts bash

修改hostname以便于区分

[root@namespace-01 ~]# hostname namespace-03 && exec bash

查看inode number,与上述namespace01和namespace02均不同

[root@namespace-03 ~]# readlink /proc/$$/ns/{uts,mnt}
uts:[4026532503]
mnt:[4026532502]

查看/mnt目录,视图与namespace01相同,无法看到namespace02的内容

[root@namespace-03 ~]# ll /mnt/
total 0
-rw-r–r–. 1 root root 0 Feb 20 12:46 namespace01.txt


关于shared subtrees:由上可知,在同一个namespace中挂载新设备时,其他namespace不受影响。但是,如果需要在所有namespace中挂着相同的设备时,就需要在每个namespace中执行相同的mount操作,非常麻烦,shared subtrees解决了这个问题。关于shared subtrees的更多内容[参考]( )。


### 3、ipc namespace


[IPC]( )(inter-process communication)namespace,主要用来隔离svipc - System V inter-process communication mechanisms和[POSIX]( )。IPC和POSIX都是用来实现进程之间的数据交换的。ipc mechanisms包括:message queues、semaphore sets、shared memory segments。POSIX与IPC的message queues功能类似,但实现方式不同。


* terminal-1



创建新的ipc namespace和uts namespace并运行bash

[root@localhost ~]# unshare --uts --ipc bash

修改hostname以便于区分

[root@localhost ~]# hostname namespace-01 && exec bash

查看inode number,确保新namespace创建成功

[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

------ Shared Memory Segments --------
key shmid owner perms bytes nattch status

------ Semaphore Arrays --------
key semid owner perms nsems

创建一个MQ

[root@namespace-01 ~]# ipcmk -Q
Message queue id: 0

查看MQ对象,-q参数表示仅显示MQ信息

[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)
│ └─sshd(1952)───bash(1956)───pstree(1971) # terminal-3对应的进程,当前进程
├─systemd-journal(462)
├─systemd-logind(640)
├─systemd-udevd(498)
└─tuned(968)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)

查看进程1793的inode number,1793对应namespace01

[root@localhost ~]# readlink /proc/1793/ns/{pid,uts,mnt}
pid:[4026532501]
uts:[4026532500]
mnt:[4026532499]

查看进程1930的inode number,1930对应namespace03

[root@localhost ~]# readlink /proc/1930/ns/{pid,uts,mnt}
pid:[4026532507]
uts:[4026532506]
mnt:[4026532505]

查看进程1906的inode number,1906对应namespace02

[root@localhost ~]# readlink /proc/1906/ns/{pid,uts,mnt}
pid:[4026532504]
uts:[4026532503]
mnt:[4026532502]

在namespace01中启动新的bash

[root@localhost ~]# nsenter --target 1793 --uts --mount --pid bash

查看namespace01中的进程树信息,多了一个unshare(51)和一个bash(52)

[root@namespace-01 /]# pstree -pl
bash(1)───unshare(51)───bash(52)

查看当前进程的inode number,对应namespace01

[root@namespace-01 /]# readlink /proc/$$/ns/{pid,uts,mnt}
pid:[4026532501]
uts:[4026532500]
mnt:[4026532499]

查看bash(52)进程的namespace的inode number,对应namespace03,因此证实namespace01可以查看namespace03中的进行信息,也就是上级可以查看下级的进行信息

[root@namespace-01 /]# readlink /proc/52/ns/{pid,uts,mnt}
pid:[4026532507]
uts:[4026532506]
mnt:[4026532505]


目前的状态大概是这个样子:



                          +-------------------------------+
                          |hostname: localhost.localdomain|
                      +---+pid namespace:4026531836       +---+
                      |   +-------------------------------+   |
                      |                                       |
      +---------------v---------------+       +---------------v---------------+
      |hostname: namespace-01         |       |hostname: namespace-02         |
      |pid namespace:4026532501       |       |pid namespace:4026532504       |
      +---------------+---------------+       +-------------------------------+
                      |
      +---------------v---------------+
      |hostname: namespace-03         |
      |pid namespace:4026532507       |
      +-------------------------------+

* terminal-2



查看进程树

[root@namespace-02 ~]# pstree -pl
bash(1)───pstree(23)

执行bash产生子进程

[root@namespace-02 ~]# bash

输出子进程号

[root@namespace-02 ~]# echo $$
24

在子进程中执行sleep,产生孙进程,后台进程,当前bash依然为bash(24)

[root@namespace-02 ~]# sleep 3600 &
[1] 33

查看进程树

[root@namespace-02 ~]# pstree -pl
bash(1)───bash(24)─┬─pstree(34)
└─sleep(33)

退出bash(24)

[root@namespace-02 ~]# exit
exit

查看进程树,由于bash(24)退出,sleep(33)的父进程变成了bash(1)

[root@namespace-02 ~]# pstree -pl
bash(1)─┬─pstree(35)
└─sleep(33)

退出namespace02的bash(1)

[root@namespace-02 ~]# exit
exit

查看完整进程树,没有sleep进程,说明namespace02中的bash(1)退出后,namespace02中的其他进程都被kill掉了

[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(2123)
│ └─sshd(1952)───bash(1956)───nsenter(1996)───bash(1997)
├─systemd-journal(462)
├─systemd-logind(640)
├─systemd-udevd(498)
└─tuned(968)─┬─{tuned}(1362)
├─{tuned}(1363)
├─{tuned}(1364)
└─{tuned}(1378)


* terminal-1



查看namespace01的进程树

[root@namespace-01 ~]# pstree
bash───pstree

执行bash产生子进程

[root@namespace-01 ~]# bash

输出进程号

[root@namespace-01 ~]# echo $$
143

执行bash产生子进程

[root@namespace-01 ~]# bash

输出进程号

[root@namespace-01 ~]# echo $$
152

执行sleep,后台执行

[root@namespace-01 ~]# sleep 3600 &
[1] 162

查看当前状态的进程树

[root@namespace-01 ~]# pstree -pl
bash(1)───bash(143)───bash(152)─┬─pstree(163)
└─sleep(162)

sleep为后台执行进程,当前bash进程为bash(152),退出当前进程

[root@namespace-01 ~]# exit
exit

查看当前状态进程树,sleep(162)的父进程变成bash(1),而不是bash(143)

[root@namespace-01 ~]# pstree -pl
bash(1)─┬─bash(143)───pstree(164)
└─sleep(162)


### 5、net namespace


net namespace是用来隔离网络空间的,包括:网络设备、路由表、iptables、sockets等。也就是说每个net namespace都拥有自己独立的网络环境。


一个网络设备只能出现在一个net namespace中,无论是物理设备还是虚拟设备。net namespace之间可以通过veth pair进行通信,需要手动配置,默认的net namespace只有一个状态为down的loop back设备。


* terminal-1



查看inode number

[root@localhost ~]# readlink /proc/$$/ns/{net,uts}
net:[4026531956]
uts:[4026531838]

创建net namespace和uts namespace,运行bash

[root@localhost ~]# unshare --net --uts bash

设置hostname

[root@localhost ~]# hostname namespace-01 && exec bash

查看inode number

[root@namespace-01 ~]# readlink /proc/$$/ns/{net,uts}
net:[4026532501]
uts:[4026532499]

查看网络设备信息

[root@namespace-01 ~]# ip addr
1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
[root@namespace-01 ~]# ping 127.0.0.1
connect: Network is unreachable

启动loop back

[root@namespace-01 ~]# ip link set dev lo up

查看设备信息

[root@namespace-01 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever

再次测试loop back

[root@namespace-01 ~]# ping -c 5 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.061 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.060 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.061 ms

— 127.0.0.1 ping statistics —
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 0.036/0.055/0.061/0.012 ms

查看当前进程的pid

[root@namespace-01 ~]# echo $$
1554


* terminal-2



在另一个终端中创建新的namespace并运行bash

[root@localhost ~]# unshare --net --uts bash

设置hostname

[root@localhost ~]# hostname namespace-02 && exec bash

查看inode

[root@namespace-02 ~]# readlink /proc/$$/ns/{net,uts}
net:[4026532571]
uts:[4026532569]

查看网络设备

[root@namespace-02 ~]# ip addr
1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

启动loop back

[root@namespace-02 ~]# ip link set dev lo up

测试loop back

[root@namespace-02 ~]# ping -c 5 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.047 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.060 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.060 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.068 ms

— 127.0.0.1 ping statistics —
5 packets transmitted, 5 received, 0% packet loss, time 4003ms
rtt min/avg/max/mdev = 0.032/0.053/0.068/0.014 ms

查看当前进程号

[root@namespace-02 ~]# echo $$
1624


此时,namespace-01和namespace-02是两个完全封闭的网络,彼此之间不能访问,也无法与外界连接。首先来看一下如何让两个net namespace之间可以相互访问,为此,Linux提供了veth pair,veth pair好比连接了网线的两块网卡,数据从一端流入就会从另一端流出,而我们需要做的就是将两块网卡分别安装到namespace-01和namespace-02中。


* terminal-3



查看当前系统的网络设备

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b9:ee:4a brd ff:ff:ff:ff:ff:ff
inet 172.16.7.4/24 brd 172.16.7.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb9:ee4a/64 scope link
valid_lft forever preferred_lft forever

创建一对veth,名称由系统生成

[root@localhost ~]# ip link add type veth

再次查看网络设备,veth0和veth1就是新创建的一对veth pair

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b9:ee:4a brd ff:ff:ff:ff:ff:ff
inet 172.16.7.4/24 brd 172.16.7.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb9:ee4a/64 scope link
valid_lft forever preferred_lft forever
3: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 6e:96:0f:78:bf:d6 brd ff:ff:ff:ff:ff:ff
4: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 22:a1:52:63:8e:ec brd ff:ff:ff:ff:ff:ff

将veth0安装到namespace-01,这里通过进程的pid来指定对应的net namespace

[root@localhost ~]# ip link set dev veth0 netns 1554

再次查看网络设备,设备veth0从当前列表中消失

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b9:ee:4a brd ff:ff:ff:ff:ff:ff
inet 172.16.7.4/24 brd 172.16.7.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb9:ee4a/64 scope link
valid_lft forever preferred_lft forever
4: veth1@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 22:a1:52:63:8e:ec brd ff:ff:ff:ff:ff:ff link-netnsid 0


* terminal-1



回到第一个终端,查看namespace-01的网络设备信息,veth0成功加入namespace-01,状态为down

[root@namespace-01 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: veth0@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 6e:96:0f:78:bf:d6 brd ff:ff:ff:ff:ff:ff link-netnsid 0


* terminal-3



回到第三个终端,继续将veth1加入namespace-02

[root@localhost ~]# ip link set dev veth1 netns 1624

查看网络设备,veth0和veth1均消失

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b9:ee:4a brd ff:ff:ff:ff:ff:ff
inet 172.16.7.4/24 brd 172.16.7.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb9:ee4a/64 scope link
valid_lft forever preferred_lft forever


* terminal-2



查看namespace-02的网络设备信息,veth1成功加入namespace-02

[root@namespace-02 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
4: veth1@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 22:a1:52:63:8e:ec brd ff:ff:ff:ff:ff:ff link-netnsid 0
先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

queue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
4: veth1@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 22:a1:52:63:8e:ec brd ff:ff:ff:ff:ff:ff link-netnsid 0
先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-SJMAmETm-1714521596751)]
[外链图片转存中…(img-qtzt0TjA-1714521596752)]
[外链图片转存中…(img-Y0qAuJAO-1714521596752)]
[外链图片转存中…(img-cuPcejfE-1714521596752)]
[外链图片转存中…(img-RjelupAe-1714521596753)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

  • 14
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值