IPC namespace用来隔离System V IPC objects和POSIX message queues。其中System V IPC objects包含Message queues、Semaphore sets和Shared memory segments. html
对于其余几种IPC,下面是个人理解,有可能不对,仅供参考,欢迎指正:linux
signal不必隔离,由于它和pid密切相关,当pid隔离后,signal天然就隔离了,能不能跨pid namespace发送signal则由pid namespace决定git
pipe好像也不必隔离,对匿名pipe来讲,只能在父子进程之间通信,因此隔离的意义不大,而命名管道和文件系统有关,因此只要作好文件系统的隔离,命名管道也就隔离了github
socket和协议栈有关,而不一样的network namespace有不一样的协议栈,因此socket就被network namespace隔离了shell
下面的全部例子都在ubuntu-server-x86_64 16.04下执行经过ubuntu
从这篇文章开始,再也不像介绍UTS namespace那样本身写代码,而是用ubuntu 16.04中现成的两个工具,他们的实现和上一篇文章中介绍UTS namespace时的代码相似,只是多了一些参数处理bash
这里将以消息队列为例,演示一下隔离效果,在本例中将用到两个ipc相关的命令工具
ipcmk - 建立shared memory segments, message queues, 和semaphore arrays
ipcs - 查看shared memory segments, message queues, 和semaphore arrays的相关信息
为了使演示更直观,咱们在建立新的ipc namespace的时候,同时也建立新的uts namespace,而后为新的utsnamespace设置新hostname,这样就能经过shell提示符一眼看出这是属于新的namespace的bash,后面的文章中也采起这种方式启动新的bash。
在这个示例中,咱们将用到两个shell窗口
#--------------------------第一个shell窗口---------------------- #记下默认的uts和ipc namespace number dev@ubuntu:~$ readlink /proc/$$/ns/uts /proc/$$/ns/ipc uts:[4026531838] ipc:[4026531839] #确认hostname dev@ubuntu:~$ hostname ubuntu #查看现有的ipc Message Queues,默认状况下没有message queue dev@ubuntu:~$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages #建立一个message queue dev@ubuntu:~$ ipcmk -Q Message queue id: 0 dev@ubuntu:~$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x12aa0de5 0 dev 644 0 0 #--------------------------第二个shell窗口---------------------- #从新打开一个shell窗口,确认和上面的shell是在同一个namespace, #能看到上面建立的message queue dev@ubuntu:~$ readlink /proc/$$/ns/uts /proc/$$/ns/ipc uts:[4026531838] ipc:[4026531839] dev@ubuntu:~$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x12aa0de5 0 dev 644 0 0 #运行unshare建立新的ipc和uts namespace,而且在新的namespace中启动bash #这里-i表示启动新的ipc namespace,-u表示启动新的utsnamespace dev@ubuntu:~$ sudo unshare -iu /bin/bash root@ubuntu:~# #确认新的bash已经属于新的ipc和uts namespace了 root@ubuntu:~# readlink /proc/$$/ns/uts /proc/$$/ns/ipc uts:[4026532455] ipc:[4026532456] #设置新的hostname以便和第一个shell里面的bash作区分 root@ubuntu:~# hostname container001 root@ubuntu:~# hostname container001 #当hostname改变后,bash不会自动修改它的命令行提示符 #因此运行exec bash从新加载bash root@ubuntu:~# exec bash root@container001:~# root@container001:~# hostname container001 #如今各个bash进程间的关系以下 #bash(24429)是shell窗口打开时的bash #bash(27668)是运行sudo unshare建立的bash,和bash(24429)不在同一个namespace root@container001:~# pstree -pl ├──sshd(24351)───sshd(24428)───bash(24429)───sudo(27667)───bash(27668)───pstree(27695) #查看message queues,看不到原来namespace里面的消息,说明已经被隔离了 root@container001:~# ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages #建立一条新的message queue root@container001:~# ipcmk -Q Message queue id: 0 root@container001:~# ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x54b08fc2 0 root 644 0 0 #--------------------------第一个shell窗口---------------------- #回到第一个shell窗口,看看有没有受到新namespace的影响 dev@ubuntu:~$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x12aa0de5 0 dev 644 0 0 #彻底无影响,仍是原来的信息 #试着加入第二个shell窗口里面bash的uts和ipc namespace #-t后面跟pid用来指定加入哪一个进程所在的namespace #这里27668是第二个shell中正在运行的bash的pid #加入成功后将运行/bin/bash dev@ubuntu:~$ sudo nsenter -t 27668 -u -i /bin/bash #加入成功,bash的提示符也自动变过来了 root@container001:~# readlink /proc/$$/ns/uts /proc/$$/ns/ipc uts:[4026532455] ipc:[4026532456] #显示的是新namespace里的message queues root@container001:~# ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x54b08fc2 0 root 644 0 0
上面介绍了IPC namespace和两个经常使用的跟namespace相关的工具,从演示过程能够看出,IPC namespace差很少和UTS namespace同样简单,没有太复杂的逻辑,也没有父子namespace关系。不事后续将要介绍的其余namespace就要比这个复杂多了。