ip netns 与 unshare -net

network namespace提供了对网络资源的隔离,每一个network namespace都拥有独立的网络栈、网络设备、IP地址和端口号、IP路由表、防火墙规则、/proc/net目录。

创建network namespace需要用到ip命令,创建命令如下:

sudo ip netns add ns1

ns1为新的network namespace的名字。通过ip命令也可以查看新建的network namespace,命令及结果如下:

ip netns showns1

network namespace已经创建了,现在应该看看其中的网络设备了,在某个network namespace里面执行命令的格式如下:

ip netns exec netns-name command

查看一下新network namespace里面的网络设备,命令及结果如下:

sudo ip netns exec ns1 ip link show1: lo:  mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

从结果可以看出,每个新的network namespace里面有一个本地回环设备,该设备默认是关闭的。

如果我们将command指定为Shell,那么我么将得到一个默认使用该network namespace的Shell,在该Shell里面执行的网络命令只作用于所属的network namespace。命令及结果如下:

sudo ip netns exec ns1 /bin/bashroot@scratchlab:~# ip link show1: lo:  mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

查看其network namespace id,结果如下:

root@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532391]

就像使用wps、word都可以创建docx文件一样,使用unshare也可以创建network namespace。通过unshare创建network namespace,命令及结果如下:

sudo unshare --net /bin/bashroot@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532478]root@scratchlab:/home/yehanlin# readlink /proc/$/ns/utsuts:[4026531838]

使用unshare可以同时启动具有多个namespace的程序。通过unshare执行具备新uts namespace、network namespace的/bin/bash,命令及结果如下:

sudo unshare --uts --net /bin/bashroot@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532566]root@scratchlab:/home/yehanlin# readlink /proc/$/ns/utsuts:[4026532565]

ip netns命令无法做到这一点,但是unshare无法灵活的操作网络设备。因此,通常的做法是使用unshare创建network namespace;使用ip netns命令操作该network namespace。

当使用ip netns命令创建ns1 network namspace时,会在/var/run/netns/创建名为ns1的文件,ip netns命令用该文件标识ns1 network namespace。

sudo ip netns add ns1ls /var/run/netns/ns1

当调用unshare --net时,也可以指定一个文件,以创建持久化的network namespace。如果指定的文件位于/var/run/netns目录,则ip netns命令就可以操作该network namespace了。使用unshare创建ns2 network namespace,命令及结果如下:

sudo mkdir -p /var/run/netnssudo touch /var/run/netns/ns2sudo unshare --net=/var/run/netns/ns2 /bin/bashroot@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532478]

此时,使用ip netns操作的就是该network namespace。使用ip netns命令进行验证,命令与结果如下:

sudo ip netns exec ns2 /bin/bashroot@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532478]

ip netns命令使用/var/run/netns/下的文件唯一标识network namespace,创建同名network namespace会失败。

而使用相同的--net参数执行unshare命令,会创建新的network namespace。重新打开一个终端,使用相同参数执行unshare命令,命令与结果如下:

sudo unshare --net=/var/run/netns/ns2 /bin/bashroot@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532566]unshare --net=/var/run/netns/dreamland /bin/bash

而ip netns指令交互的是最新的network namespace。重新打开一个终端,执行ip netns,命令及结果如下:

sudo ip netns exec ns2 /bin/bashroot@scratchlab:/home/yehanlin# readlink /proc/$/ns/netnet:[4026532566]

为了简化,docker.sh在创建xxx network namespace之前,须确保该network namespace及/var/run/netns/xxx文件不存在。

docker.sh在检测到/var/run/netns xxx文件存在时,会退出,用户需手动删除该network namespace及文件。

ip netns del xxxrm /var/run/netns/xxx

删除network namespace之前须确保network namespace不被使用。若已确认network namespace没有使用,但仍旧删除失败,可以等待一段时间再删除。

我写了一个称作docker.sh 的小项目,该项目旨在通过一系列的实验使用户对docker的底层技术,如Namespace、CGroups、rootfs、联合加载等有一个感性的认识。在此过程中,我们还将通过Shell脚本一步一步地实现一个简易的docker,以期使读者在使用docker的过程中知其然知其所以然。该项目的仓库地址如下:

https://github.com/pandengyang/docker.sh.githttps://gitee.com/pandengyang/docker.sh.git

该项目配套了一个保姆级的教程,可用于学习 Docker 原理,里面有Namespace、CGroups的原理及示例的介绍。

ip   netns   unshare
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章