有了前面有关namespace的隔离的例子,对于namespace的认识应该会更深一层,对于网络的namespace同样可以虚拟化出多个网络环境,相互之间的网络环境都是独立的
在Linux里,创建网络命名空间通过netns来完成,具体可以查看netns的man page,有的linux版本是man net-ns,我这个debian更奇怪,还需要如下apt安装
sudo apt-get install core-network-daemon
下面就是创建命名空间,以及相互通信的小例子
这里最好开两个终端窗口,因为到时候其中一个直接进入新的namespace进行操作,比较简洁
终端1:
创建命名空间ns0
root@2015-vm2:~# ip netns add ns0
这样就创建了一个名为ns0的namespace,但是除了网络是相互隔离的以外,其他的比如文件系统等都还是共享的
root@2015-vm2:~# ip netns list ns0
假如想查看下ns0里面网络状况,这里需要注意的是,必须指定要查看的namespace
root@2015-vm2:~# ip netns exec ns0 ifconfig root@2015-vm2:~# ip netns exec ns0 ifconfig -a lo Link encap:Local Loopback LOOPBACK MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@2015-vm2:~# ip netns exec ns0 ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
可见新的namespace里除了一个状态为DOWN的lo之外,别无其他
在这里执行ifconfig命令就指明了ip netns exec ns0,就是为了指定查看ns0
假如想更贴切一点,进入到ns0中来执行bash命令,省掉前面几个词汇,可以入下操作
root@2015-vm2:~# ip netns exec ns0 bash root@2015-vm2:~# ifconfig -a lo Link encap:Local Loopback LOOPBACK MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@2015-vm2:~# ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
如此一来,就好像进入了一个新的环境中,目前还是终端1,那么接下来终端1就持续在ns0中操作,而另一个终端2,就在外层本来的网络环境中操作
此时新的namespace已经创建完毕,下面就先添加一对相通的veth设备
root@2015-vm2:/home/lihui# ip link add name veth0 type veth peer name veth1 root@2015-vm2:/home/lihui# ip link set veth0 netns ns0 root@2015-vm2:/home/lihui# ifconfig veth0 veth0: error fetching interface information: Device not found
创建的时候要注意type,veth0和veth1就是一对veth pair,啥叫相通呢,就像pipe一样,发给这边的数据,另一边也能收到,就像网线直连
接着将veth0分配给了ns0,果然外面ifconfig就无法找到veth0了
终端1 root@2015-vm2:~# ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether d6:a9:bf:ed:04:9a brd ff:ff:ff:ff:ff:ff root@2015-vm2:~# ip link set veth0 name eth0 root@2015-vm2:~# ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether d6:a9:bf:ed:04:9a brd ff:ff:ff:ff:ff:ff root@2015-vm2:~# ip addr add 192.168.10.100/24 dev eth0 root@2015-vm2:~# ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether d6:a9:bf:ed:04:9a brd ff:ff:ff:ff:ff:ff inet 192.168.10.100/24 scope global eth0 valid_lft forever preferred_lft forever root@2015-vm2:~# ip link set lo up root@2015-vm2:~# ip link set eth0 up root@2015-vm2:~# ping 192.168.10.100 PING 192.168.10.100 (192.168.10.100) 56(84) bytes of data. 64 bytes from 192.168.10.100: icmp_seq=1 ttl=64 time=0.016 ms 64 bytes from 192.168.10.100: icmp_seq=2 ttl=64 time=0.127 ms 64 bytes from 192.168.10.100: icmp_seq=3 ttl=64 time=0.036 ms ^C
这里进入namespace里面,果然veth0已经进来了,将网卡名换一下,然后分配一个私有IP,然后ping一下自己
假如eth0一直还是DOWN的状态,多ip link set eth0 up几次
下面想让namespace里的eth0能和外面通信,当然首先得能和终端2外面的网络环境想通,在刚创建veth pair的时候,还有一个veth1呆着呢
创建虚拟网络环境
终端2
root@2015-vm2:/home/lihui# brctl addbr newbr root@2015-vm2:/home/lihui# brctl addif newbr veth1 root@2015-vm2:/home/lihui# ip link set veth1 up root@2015-vm2:/home/lihui# ip addr add 192.168.10.101/24 dev newbr root@2015-vm2:/home/lihui# ip link set newbr up root@2015-vm2:/home/lihui# ifconfig newbr newbr Link encap:Ethernet HWaddr da:bc:b9:de:71:21 inet addr:192.168.10.101 Bcast:0.0.0.0 Mask:255.255.255.0 inet6 addr: fe80::d8bc:b9ff:fede:7121/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:508 (508.0 B)
创建虚拟网络,将veth1绑定到这个口上,并且配置一个和ns0里eth0同一个网段的IP,最终达到通信,大概方向就是:
eth0(ns0) ---- veth1(bridge) ---- eth0
试着ping一下
root@2015-vm2:/home/lihui# ping 192.168.10.100 PING 192.168.10.100 (192.168.10.100) 56(84) bytes of data. 64 bytes from 192.168.10.100: icmp_seq=1 ttl=64 time=0.040 ms 64 bytes from 192.168.10.100: icmp_seq=2 ttl=64 time=0.051 ms 64 bytes from 192.168.10.100: icmp_seq=3 ttl=64 time=0.039 ms 64 bytes from 192.168.10.100: icmp_seq=4 ttl=64 time=0.051 ms 64 bytes from 192.168.10.100: icmp_seq=5 ttl=64 time=0.052 ms
假如创建多个namespace,需要相互通信,就多创建几个veth pair,分别这样和bridge来一次