玩转Linux network namespace

使用ip netns命令操作network namespace

创建一个network namespace名为nstest。

[ ~]# ip netns add nstest

列出系统中已存在的network namespace

[ ~]# ip netns list
nstest

删除一个network namespace

[ ~]# ip netns delete nstest

在network namespace中执行一条命令

[ ~]# 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)。该设备默认不启动,用最好将其启动。

[ ~]# ip netns exec nstest ip link set dev lo up

在主机上创建两张网卡veth-a和veth-b

[ ~]# ip link add veth-a type veth peer name veth-b

将veth-b设备添加到nstest这个network namespace中, veth-a留在主机中

[ ~]# ip link set veth-b netns nstest

现在nstest这个network namespace就有了两块网卡lo和veth-b,来验证一下。

[ ~]# 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: : <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并启动

[ ~]# ip addr add 10.0.0.1/24 dev veth-a
[ ~]# ip link set dev veth-a up

为nstest中的veth-b配置IP并启动。

[ ~]# ip netns exec nstest ip addr add 10.0.0.2/24 dev veth-b
[ ~]# ip netns exec nstest ip link set dev veth-b up

给两张网卡配置了IP后,会在各自的network namespace中生成一条路由,用ip route或route -a命令查看一下。

[ ~]# 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中
[ ~]# 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网卡。

[ ~]# 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网卡

[ ~]# 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

[ ~]# ip netns add ns1
[ ~]# ip netns add ns2

创建veth pair设备veth-a,veth-b

[ ~]# ip link add veth-a type veth peer name veth-b

将网卡分别放在两个naemspace中

[ ~]# ip link set veth-a netns ns1
[ ~]# ip link set veth-b netns ns2

启动两张网卡。

[ ~]# ip netns exec ns1 ip link set dev veth-a up
[ ~]# ip netns exec ns2 ip link set dev veth-b up

分配IP

[ ~]# ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-a
[ ~]# ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth-b

验证连通

[ ~]# 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
[ ~]# 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就好像直接通过网线连接起来的两台机器

玩转Linux network namespace

如果有更多的network namespace需要连接,那就有必要引入虚拟网桥了,就如同docker的网络一样。

相关推荐