Linux network namespace

有了前面有关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来一次

发表回复