玩转Linux network namespace
使用ip netns命令操作network namespace
创建一个network namespace名为nstest。
[root@localhost ~]# ip netns add nstest
列出系统中已存在的network namespace
[root@localhost ~]# ip netns list
nstest
删除一个network namespace
[root@localhost ~]# ip netns delete nstest
在network namespace中执行一条命令
[root@localhost ~]# ip netns exec nstest ip addr 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 命令格式: ip netns exec [network namespace name] [command]
使用ip命令为network namespace配置网卡。
当使用ip netns add命令创建一个network namespace后,就拥有了一个独立的网空间,可以根据需求来配置网络空间,如添加网卡,配置IP,设置路由规则等,当使用ip命令创建一个network namespace时,会默认创建一个回环设备(loopback interface:lo)。该设备默认不启动,用最好将其启动。
[root@localhost ~]# ip netns exec nstest ip link set dev lo up
在主机上创建两张网卡veth-a和veth-b
[root@localhost ~]# ip link add veth-a type veth peer name veth-b
将veth-b设备添加到nstest这个network namespace中, veth-a留在主机中
[root@localhost ~]# ip link set veth-b netns nstest
现在nstest这个network namespace就有了两块网卡lo和veth-b,来验证一下。
[root@localhost ~]# ip netns exec nstest ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: veth-b@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 4e:3c:eb:70:76:76 brd ff:ff:ff:ff:ff:ff link-netnsid 0
现在可以为网卡分配IP并启动网卡了。
在主机上为veth-a配置IP并启动
[root@localhost ~]# ip addr add 10.0.0.1/24 dev veth-a [root@localhost ~]# ip link set dev veth-a up
为nstest中的veth-b配置IP并启动。
[root@localhost ~]# ip netns exec nstest ip addr add 10.0.0.2/24 dev veth-b [root@localhost ~]# ip netns exec nstest ip link set dev veth-b up
给两张网卡配置了IP后,会在各自的network namespace中生成一条路由,用ip route或route -a命令查看一下。
[root@localhost ~]# ip route default via 192.168.1.1 dev ens33 proto static metric 100 10.0.0.0/24 dev veth-a proto kernel scope link src 10.0.0.1 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.220 metric 100 在nstest network namespce中 [root@localhost ~]# ip netns exec nstest ip route 10.0.0.0/24 dev veth-b proto kernel scope link src 10.0.0.2
这两条路由表明的意义是目的地址为10.0.0.0/24网络的IP包分别从veth-a和veth-b发出。现在nstest这个network namespace有了自己的网卡,IP地址,路由表等信息,俨然成了一台小型的虚拟机,测试一下它的连通性,以检查配置是否正确。
从主机的veth-a网卡ping nstest network namespace的veth-b网卡。
[root@localhost ~]# ping 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.429 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.116 ms ^C --- 10.0.0.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.116/0.272/0.429/0.157 ms
从nstest network namespace的veth-b网卡ping主机的veth-a网卡
[root@localhost ~]# ip netns exec nstest ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.108 ms 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.053 ms 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.070 ms 64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.051 ms ^C --- 10.0.0.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3001ms rtt min/avg/max/mdev = 0.051/0.070/0.108/0.024 ms
将两个network namespace连接起来
创建两个network namespace ns1 ns2
[root@localhost ~]# ip netns add ns1
[root@localhost ~]# ip netns add ns2
创建veth pair设备veth-a,veth-b
[root@localhost ~]# ip link add veth-a type veth peer name veth-b
将网卡分别放在两个naemspace中
[root@localhost ~]# ip link set veth-a netns ns1
[root@localhost ~]# ip link set veth-b netns ns2
启动两张网卡。
[root@localhost ~]# ip netns exec ns1 ip link set dev veth-a up
[root@localhost ~]# ip netns exec ns2 ip link set dev veth-b up
分配IP
[root@localhost ~]# ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-a [root@localhost ~]# ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth-b
验证连通
[root@localhost ~]# ip netns exec ns1 ping 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.480 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.048 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.135 ms 64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.115 ms ^C --- 10.0.0.2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3002ms rtt min/avg/max/mdev = 0.048/0.194/0.480/0.168 ms [root@localhost ~]# ip netns exec ns2 ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.097 ms 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.108 ms 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.112 ms ^C --- 10.0.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.097/0.105/0.112/0.013 ms
通过veth pair设备连接起来的两个network namespace就好像直接通过网线连接起来的两台机器
如果有更多的network namespace需要连接,那就有必要引入虚拟网桥了,就如同docker的网络一样。