js06金沙官网登录-js06.com-欢迎您

来自 计算机 2020-01-04 23:48 的文章
当前位置: js06金沙官网登录-js06.com-欢迎您 > 计算机 > 正文

介绍 Linux 的命名空间

介绍 Linux 的命名空间

背景

从Linux 2.6.24版的木本早先,Linux 就帮衬6种不一致种类的命名空间。它们的现身,使顾客创立的历程能够与系统一分配离得特别绝望,进而没有必要运用越来越多的底层虚拟化技术。

  • CLONE_NEWIPC: 进度间通讯(IPC卡塔尔的命名空间,能够将 SystemV 的 IPC 和 POSIX 的新闻队列独立出来。
  • CLONE_NEWPID: 进度命名空间。空间内的PID 是单身分配的,意思正是命名空间内的假造 PID 恐怕会与命名空间外的 PID 相矛盾,于是命名空间内的 PID 映射到命名空间外时会采纳别的一个PID。举例说,命名空间内先是个 PID 为1,而在命名空间外正是该 PID 已被 init 进度所采用。
  • CLONE_NEWNET: 网络命名空间,用于隔绝网络财富(/proc/net、IP 地址、网卡、路由等)。后台进度能够运维在分裂命名空间内的相符端口上,顾客还足以虚构出一块网卡。
  • CLONE_NEWNS: 挂载命名空间,进度运维时方可将挂载点与系统剥离,使用那么些效果时,我们得以完毕chroot 的法力,而在安全性方面比 chroot 越来越高。
  • CLONE_NEWUTS: UTS 命名空间,主要目标是单身出主机名和互联网音信服务(NIS)。
  • CLONE_NEWUSEEnclave: 客户命名空间,同进程 ID 一样,客商 ID 和组 ID 在命名空间内外是不适合的,并且在分化命名空间内得以存在同样的 ID。

上边大家介绍一下历程命名空间和网络命名空间。

金沙官网登录 1

(题图来自:fotothing.com)

经过命名空间

正文用 C 语言介绍上述概念,因为演示进程命名空间的时候必要用到 C 语言。上边包车型地铁测量检验进程在 Debian 6 和 Debian 7 上实践。首先,在栈内分配后生可畏页内部存款和储蓄器空间,并将指针指向内部存款和储蓄器页的最终。这里大家接收alloca(卡塔尔(قطر‎ 函数来分配内部存款和储蓄器,不要用 malloc(卡塔尔 函数,它会把内部存款和储蓄器分配在堆上。

  1. void*mem = alloca(sysconf(_SC_PAGESIZE))+ sysconf(_SC_PAGESIZE);

下一场使用 clone(卡塔尔 函数创设子进程,传入大家的子栈空间地址 "mem",并钦命命名空间的号子。同一时间大家还点名“callee”作为子进度运营的函数。

  1. mypid = clone(callee, mem, SIGCHLD | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_FILES, NULL);

clone 之后大家要在父进度在那之中待子进程先退出,否则的话,父进度会继续运转下去,并立时进程甘休,留下子进程产生孤儿进度:

  1. while(waitpid(mypid,&r,0)<0&& errno == EINTR)
  2. {
  3. continue;
  4. }

末尾当子进度退出后,我们会回去 shell 分界面,并再次来到子进度的退出码。

  1. if(WIFEXITED(r))
  2. {
  3. return WEXITSTATUS(r);
  4. }
  5. return EXIT_FAILURE;

上文介绍的 callee 函数成效如下:

  1. staticint callee()
  2. {
  3. int ret;
  4. mount("proc","/proc","proc",0,"");
  5. setgid(u);
  6. setgroups(0, NULL);
  7. setuid(u);
  8. ret = execl("/bin/bash","/bin/bash", NULL);
  9. return ret;
  10. }

程序挂载了 /proc 文件系统,设置顾客 ID 和组 ID,值都为“u”,然后运转/bin/bash 程序,LXC 是一个操作系统级的设想化学工业具,使用 cgroups 和命名空间来成功能源的分别。今后大家把装有代码放在一齐,变量“u”的值设为65534,在 Debian 系统中,这是“nobody”和“nogroup”:

  1. #define _GNU_SOURCE
  2. #include<unistd.h>
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<sys/types.h>
  6. #include<sys/wait.h>
  7. #include<sys/mount.h>
  8. #include<grp.h>
  9. #include<alloca.h>
  10. #include<errno.h>
  11. #include<sched.h>
  12. staticint callee();
  13. constint u =65534;
  14. int main(int argc,char*argv[])
  15. {
  16. int r;
  17. pid_t mypid;
  18. void*mem = alloca(sysconf(_SC_PAGESIZE))+ sysconf(_SC_PAGESIZE);
  19. 金沙官网登录,mypid = clone(callee, mem, SIGCHLD | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_FILES, NULL);
  20. while(waitpid(mypid,&r,0)<0&& errno == EINTR)
  21. {
  22. continue;
  23. }
  24. if(WIFEXITED(r))
  25. {
  26. return WEXITSTATUS(r);
  27. }
  28. return EXIT_FAILURE;
  29. }
  30. staticint callee()
  31. {
  32. int ret;
  33. mount("proc","/proc","proc",0,"");
  34. setgid(u);
  35. setgroups(0, NULL);
  36. setuid(u);
  37. ret = execl("/bin/bash","/bin/bash", NULL);
  38. return ret;
  39. }

进行以下命令来运作方面包车型大巴代码:

  1. [email protected]:~/pen/tmp# gcc -O -o ns.c -Wall -Werror -ansi -c89 ns.c
  2. [email protected]:~/pen/tmp# ./ns
  3. [email protected]:~/pen/tmp$ id
  4. uid=65534(nobody) gid=65534(nogroup)
  5. [email protected]:~/pen/tmp$ ps auxw
  6. USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
  7. nobody 10.00.046201816 pts/1 S 21:210:00/bin/bash
  8. nobody 50.00.027841064 pts/1 R+21:210:00 ps auxw
  9. [email protected]:~/pen/tmp$

注意下边包车型地铁结果,UID 和 GID 棉被服装置成 nobody 和 nogroup 了,非常是 ps 工具只输出七个进程,它们的 ID 分别是1和5(LCTT注:那正是上文介绍 CLONE_NEWPID 时提到的效能,在线程所在的命名空间内,进度 ID 可感觉1,映射到命名空间外是别的三个 PID;而命名空间外的 ID 为1的经过一向是 init)。

互连网命名空间

接下去轮到使用 ip netns 来设置网络的命名空间。第一步先鲜明当前系统并未有命名空间:

  1. [email protected]:~# ip netns list
  2. Object"netns"is unknown,try"ip help".

风流倜傥经报了上述荒谬,你必要立异您的系统基本,以至 ip 工具程序。这里借让你的内核版高于2.6.24,ip 工具版本也基本上,高于2.6.24(LCTT注:ip 工具由 iproute 安装包提供,此安装包版本与底子版本周边)。更新好后,ip netns list 在未曾命名空间存在的境况下不会输出职务消息。加个名字为“ns1”的命名空间看看:

  1. [email protected]:~# ip netns add ns1
  2. [email protected]:~# ip netns list
  3. ns1

列出网卡:

  1. [email protected]:~# ip link list
  2. 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
  3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4. 2: eth0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 1000
  5. link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff

始建新的伪造网卡,并加到命名空间。虚构网卡必要成对创立,相互关联——如同交叉电缆同样:

  1. [email protected]:~# ip link add veth0 type veth peer name veth1
  2. [email protected]:~# ip link list
  3. 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. 2: eth0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 1000
  6. link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff
  7. 3: veth1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
  8. link/ether d2:e9:52:18:19:ab brd ff:ff:ff:ff:ff:ff
  9. 4: veth0: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
  10. link/ether f2:f7:5e:e2:22:ac brd ff:ff:ff:ff:ff:ff

此时 ifconfig -a 命令也能显得新加上的 veth0 和 veth1 两块网卡。

很好,以往将这两份块网卡加到命名空间中去。注意一下,上边包车型地铁 ip netns exec 命令用于将前面包车型大巴一声令下在命名空间中实行(LCTT注:下边包车型大巴结果突显了在 ns1 这一个网络命名空间中,只设有 lo 和 veth1 两块网卡):

  1. [email protected]:~# ip link set veth1 netns ns1
  2. [email protected]:~# ip netns exec ns1 ip link list
  3. 1: lo: mtu 65536 qdisc noop state DOWN mode DEFAULT
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. 3: veth1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
  6. link/ether d2:e9:52:18:19:ab brd ff:ff:ff:ff:ff:ff

此时 ifconfig -a 命令只好显示 veth0,无法显得 veth1,因为后面一个曾经在ns1 命名空间中。

设若想删除 veth0/veth1,能够实践下边包车型大巴授命:

  1. ip netns exec ns1 ip link del veth1

大家可认为 veth0 分配 IP 地址:

  1. ifconfig veth0 192.168.5.5/24

在命名空间内为 veth1 分配 IP 地址:

  1. ip netns exec ns1 ifconfig veth1 192.168.5.10/24 up

在命名空间内外实践 ip addr list 命令:

  1. [email protected]:~# ip addr list
  2. 1: lo: mtu 65536 qdisc noqueue state UNKNOWN
  3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4. inet 127.0.0.1/8 scope host lo
  5. inet6 ::1/128 scope host
  6. valid_lft forever preferred_lft forever
  7. 2: eth0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
  8. link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff
  9. inet 192.168.3.122/24 brd 192.168.3.255 scope global eth0
  10. inet6 fe80::20c:29ff:fe65:259e/64 scope link
  11. valid_lft forever preferred_lft forever
  12. 6: veth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
  13. link/ether 86:b2:c7:bd:c9:11 brd ff:ff:ff:ff:ff:ff
  14. inet 192.168.5.5/24 brd 192.168.5.255 scope global veth0
  15. inet6 fe80::84b2:c7ff:febd:c911/64 scope link
  16. valid_lft forever preferred_lft forever
  17. [email protected]:~# ip netns exec ns1 ip addr list
  18. 1: lo: mtu 65536 qdisc noop state DOWN
  19. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  20. 5: veth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
  21. link/ether 12:bd:b6:76:a6:eb brd ff:ff:ff:ff:ff:ff
  22. inet 192.168.5.10/24 brd 192.168.5.255 scope global veth1
  23. inet6 fe80::10bd:b6ff:fe76:a6eb/64 scope link
  24. valid_lft forever preferred_lft forever

在命名空间内外查看路由表:

  1. [email protected]:~# ip route list
  2. default via 192.168.3.1 dev eth0 proto static
  3. 192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.3.122
  4. 192.168.5.0/24 dev veth0 proto kernel scope link src 192.168.5.5
  5. [email protected]:~# ip netns exec ns1 ip route list
  6. 192.168.5.0/24 dev veth1 proto kernel scope link src 192.168.5.10

谈起底,将虚构网卡连到物理网卡上,大家须要用到桥接。这里做的是将 veth0 桥接到 eth0,而 ns1 命名空间内则应用 DHCP 自动获取 IP 地址:

  1. [email protected]:~# brctl addbr br0
  2. [email protected]:~# brctl addif br0 eth0
  3. [email protected]:~# brctl addif br0 veth0
  4. [email protected]:~# ifconfig eth0 0.0.0.0
  5. [email protected]:~# ifconfig veth0 0.0.0.0
  6. [email protected]:~# dhclient br0
  7. [email protected]:~# ip addr list br0
  8. 7: br0: mtu 1500 qdisc noqueue state UP
  9. link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff
  10. inet 192.168.3.122/24 brd 192.168.3.255 scope global br0
  11. inet6 fe80::20c:29ff:fe65:259e/64 scope link
  12. valid_lft forever preferred_lft forever

为网桥 br0 分配的 IP 地址为192.168.3.122/24。接下来为命名空间分配地址:

  1. [email protected]:~# ip netns exec ns1 dhclient veth1
  2. [email protected]:~# ip netns exec ns1 ip addr list
  3. 1: lo: mtu 65536 qdisc noop state DOWN
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. 5: veth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
  6. link/ether 12:bd:b6:76:a6:eb brd ff:ff:ff:ff:ff:ff
  7. inet 192.168.3.248/24 brd 192.168.3.255 scope global veth1
  8. inet6 fe80::10bd:b6ff:fe76:a6eb/64 scope link
  9. valid_lft forever preferred_lft forever

今日, veth1 的 IP 棉被服装置成 192.168.3.248/24 了。

本文永远更新链接地址:

Linux 的命名空间 背景 从Linux 2.6.24版的基业最早,Linux 就支持6种差异门类的命名空间。它们的产出,使顾客创制的经过能够与系统抽离...

本文由js06金沙官网登录-js06.com-欢迎您发布于计算机,转载请注明出处:介绍 Linux 的命名空间

关键词: