ip netns add net1 ip netns add net2 ip link set macvlan1 netns net1 ip link set macvlan2 netns net2 ip netns exec net1 ip link set macvlan1 name eth0 ip netns exec net2 ip link set macvlan2 name eth0
ip netns exec net1 ip addr add 172.28.248.10/20 dev eth0 ip netns exec net2 ip addr add 172.28.248.9/20 dev eth0 ip netns exec net1 ip link set eth0 up ip netns exec net2 ip link set eth0 up ip netns exec net1 ip -detail link show eth0 28: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 8e:c0:cd:f7:cb:3b brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0 minmtu 68 maxmtu 65521 macvlan mode bridge bcqueuelen 1000 usedbcqueuelen 1000 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 62780 gso_max_segs 65535 $ ip netns exec net2 ip -detail link show eth0 29: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 5e:54:bb:4c:55:b6 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0 minmtu 68 maxmtu 65521 macvlan mode bridge bcqueuelen 1000 usedbcqueuelen 1000 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 62780 gso_max_segs 65535 $ ip netns exec net1 ip a s eth0 28: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 8e:c0:cd:f7:cb:3b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.28.248.10/20 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::8cc0:cdff:fef7:cb3b/64 scope link valid_lft forever preferred_lft forever $ ip netns exec net2 ip a s eth0 29: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 5e:54:bb:4c:55:b6 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.28.248.9/20 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::5c54:bbff:fe4c:55b6/64 scope link valid_lft forever preferred_lft forever
测试命名空间之间的网络连通性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ ip netns exec net2 ping -c 3 172.28.248.10 PING 172.28.248.10 (172.28.248.10) 56(84) bytes of data. 64 bytes from 172.28.248.10: icmp_seq=1 ttl=64 time=0.035 ms 64 bytes from 172.28.248.10: icmp_seq=2 ttl=64 time=0.023 ms 64 bytes from 172.28.248.10: icmp_seq=3 ttl=64 time=0.024 ms
--- 172.28.248.10 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2058ms rtt min/avg/max/mdev = 0.023/0.027/0.035/0.005 ms $ ip netns exec net1 ping -c 3 172.28.248.9 PING 172.28.248.9 (172.28.248.9) 56(84) bytes of data. 64 bytes from 172.28.248.9: icmp_seq=1 ttl=64 time=0.016 ms 64 bytes from 172.28.248.9: icmp_seq=2 ttl=64 time=0.022 ms 64 bytes from 172.28.248.9: icmp_seq=3 ttl=64 time=0.021 ms
--- 172.28.248.9 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2098ms rtt min/avg/max/mdev = 0.016/0.019/0.022/0.002 ms
但是此时从主机无法访问命名空间的网络,从命名空间也无法访问主机网络:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ ping -c 3 172.28.248.10 PING 172.28.248.10 (172.28.248.10) 56(84) bytes of data. From 172.28.252.45 icmp_seq=1 Destination Host Unreachable From 172.28.252.45 icmp_seq=2 Destination Host Unreachable From 172.28.252.45 icmp_seq=3 Destination Host Unreachable
ip link add mynet-shim link eth0 type macvlan mode bridge ip addr add 172.28.248.254/32 dev mynet-shim ip link set mynet-shim up ip route add 172.28.248.0/21 dev mynet-shim $ ping -c 3 172.28.248.9 PING 172.28.248.9 (172.28.248.9) 56(84) bytes of data. 64 bytes from 172.28.248.9: icmp_seq=1 ttl=64 time=0.075 ms 64 bytes from 172.28.248.9: icmp_seq=2 ttl=64 time=0.047 ms 64 bytes from 172.28.248.9: icmp_seq=3 ttl=64 time=0.029 ms
--- 172.28.248.9 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2082ms rtt min/avg/max/mdev = 0.029/0.050/0.075/0.018 ms $ ip netns exec net1 ping -c 3 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.057 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.037 ms 64 bytes from 172.28.252.45: icmp_seq=3 ttl=64 time=0.034 ms
--- 172.28.252.45 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2052ms rtt min/avg/max/mdev = 0.034/0.042/0.057/0.010 ms
清理测试现场使用:
ip netns delete net1 ip netns delete net2 ip link delete mynet-shim
ip link add mynet-shim link eth0 type macvlan mode bridge ip addr add 172.28.244.254/32 dev mynet-shim ip link set mynet-shim up ip route add 172.28.244.0/22 dev mynet-shim
然后进行测试网络连通正常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ ping -c 3 172.28.244.2 PING 172.28.244.2 (172.28.244.2) 56(84) bytes of data. 64 bytes from 172.28.244.2: icmp_seq=1 ttl=64 time=0.040 ms 64 bytes from 172.28.244.2: icmp_seq=2 ttl=64 time=0.034 ms 64 bytes from 172.28.244.2: icmp_seq=3 ttl=64 time=0.030 ms
--- 172.28.244.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2109ms rtt min/avg/max/mdev = 0.030/0.034/0.040/0.004 ms $ docker exec -it ubuntu2 ping -c 3 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.081 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.032 ms 64 bytes from 172.28.252.45: icmp_seq=3 ttl=64 time=0.039 ms
--- 172.28.252.45 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2058ms rtt min/avg/max/mdev = 0.032/0.050/0.081/0.021 ms
ip link add link eth0 name eth0.10 type vlan id 10 ip link add link eth0 name eth0.20 type vlan id 20 ip addr add 172.28.244.1/24 brd 172.28.244.255 dev eth0.10 ip addr add 172.19.248.1/24 brd 172.28.248.255 dev eth0.20 ip link set dev eth0.10 up ip link set dev eth0.20 up $ ip -d a s eth0.10 42: eth0.10@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:15:5d:41:e5:36 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 0 maxmtu 65535 vlan protocol 802.1Q id 10 <REORDER_HDR> numtxqueues 1 numrxqueues 1 gso_max_size 62780 gso_max_segs 65535 inet 172.28.244.1/24 brd 172.28.244.255 scope global eth0.10 valid_lft forever preferred_lft forever inet6 fe80::215:5dff:fe41:e536/64 scope link tentative valid_lft forever preferred_lft forever $ ip -d a s eth0.20 43: eth0.20@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:15:5d:41:e5:36 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 0 maxmtu 65535 vlan protocol 802.1Q id 20 <REORDER_HDR> numtxqueues 1 numrxqueues 1 gso_max_size 62780 gso_max_segs 65535 inet 172.19.248.1/24 brd 172.28.244.255 scope global eth0.20 valid_lft forever preferred_lft forever inet6 fe80::215:5dff:fe41:e536/64 scope link valid_lft forever preferred_lft forever
ip link add macvlan1-shim link eth0.10 type macvlan mode bridge ip addr add 172.28.244.254/32 dev macvlan1-shim ip link set macvlan1-shim up ip route add 172.28.244.0/24 dev macvlan1-shim ip link add macvlan2-shim link eth0.20 type macvlan mode bridge ip addr add 172.28.248.254/32 dev macvlan2-shim ip link set macvlan2-shim up ip route add 172.28.248.0/24 dev macvlan2-shim
测试主机到容器的网络连通性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
$ ping -c 2 172.28.244.2 PING 172.28.244.2 (172.28.244.2) 56(84) bytes of data. 64 bytes from 172.28.244.2: icmp_seq=1 ttl=64 time=0.050 ms 64 bytes from 172.28.244.2: icmp_seq=2 ttl=64 time=0.045 ms
--- 172.28.244.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1061ms rtt min/avg/max/mdev = 0.045/0.047/0.050/0.002 ms $ ping -c 2 172.28.248.2 PING 172.28.248.2 (172.28.248.2) 56(84) bytes of data. 64 bytes from 172.28.248.2: icmp_seq=1 ttl=64 time=0.047 ms 64 bytes from 172.28.248.2: icmp_seq=2 ttl=64 time=0.037 ms
--- 172.28.248.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1059ms rtt min/avg/max/mdev = 0.037/0.042/0.047/0.005 ms
如果还没有为 vlan 设置 IP 地址,执行如下的命令:
1 2 3 4
ip addr add 172.28.244.1/24 dev eth0.10 ip addr add 172.28.248.1/24 dev eth0.20 ip route delete 172.28.248.0/24 dev eth0.20 ip route delete 172.28.244.0/24 dev eth0.10
此时系统的路由如下:
1 2 3 4 5 6 7 8 9
$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.28.240.1 0.0.0.0 UG 0 0 0 eth0 10.42.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 172.28.240.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0 172.28.244.0 0.0.0.0 255.255.255.0 U 0 0 0 macvlan1-shim 172.28.248.0 0.0.0.0 255.255.255.0 U 0 0 0 macvlan2-shim
再测试容器到主机的网络连通情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
$ docker exec -it ubuntu1 ping -c 2 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.071 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.037 ms
--- 172.28.252.45 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1040ms rtt min/avg/max/mdev = 0.037/0.054/0.071/0.017 ms $ docker exec -it ubuntu4 ping -c 2 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.081 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.027 ms
--- 172.28.252.45 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1036ms rtt min/avg/max/mdev = 0.027/0.054/0.081/0.027 ms
ip link add link eth0 name ipvlan1 type ipvlan mode l2 ip link add link eth0 name ipvlan2 type ipvlan mode l2 ip link add link eth0 name ipvlan3 type ipvlan mode l2
创建三个命名空间,将新创建的子接口移入且重命名:
1 2 3 4 5 6 7 8 9
ip netns add net1 ip netns add net2 ip netns add net3 ip link set ipvlan1 netns net1 ip link set ipvlan2 netns net2 ip link set ipvlan3 netns net3 ip netns exec net1 ip link set ipvlan1 name eth0 ip netns exec net2 ip link set ipvlan2 name eth0 ip netns exec net3 ip link set ipvlan3 name eth0
为子接口设置IP地址,其中net1 和 net2 在同一个网络内,net3 属于其他网络:
1 2 3 4 5 6
ip netns exec net1 ip addr add 172.28.248.2/24 dev eth0 ip netns exec net2 ip addr add 172.28.248.3/24 dev eth0 ip netns exec net3 ip addr add 172.28.244.2/24 dev eth0 ip netns exec net1 ip link set eth0 up ip netns exec net2 ip link set eth0 up ip netns exec net3 ip link set eth0 up
net1 和 net2 网络连通性正常:
1 2 3 4 5 6 7 8 9 10 11 12 13
$ ip netns exec net1 route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.28.248.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 $ ip netns exec net1 ping -c 3 172.28.248.3 PING 172.28.248.3 (172.28.248.3) 56(84) bytes of data. 64 bytes from 172.28.248.3: icmp_seq=1 ttl=64 time=0.306 ms 64 bytes from 172.28.248.3: icmp_seq=2 ttl=64 time=0.029 ms 64 bytes from 172.28.248.3: icmp_seq=3 ttl=64 time=0.021 ms
--- 172.28.248.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2103ms rtt min/avg/max/mdev = 0.021/0.118/0.306/0.132 ms
net1 和 net3 由于在不同的网络内,即使手动添加路由,网络也不能连通:
1 2 3 4 5 6 7 8 9 10 11
$ ip netns exec net1 ip route add default via 172.28.248.1 $ ip netns exec net1 route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.28.248.1 0.0.0.0 UG 0 0 0 eth0 172.28.248.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 $ ip netns exec net1 ping -c 3 172.28.244.2 PING 172.28.244.2 (172.28.244.2) 56(84) bytes of data.
ip link add link eth0 name ipvlan_shim type ipvlan mode l3 ip addr add 172.28.248.222/32 dev ipvlan_shim ip link set ipvlan_shim up ip route add 172.28.248.0/24 dev ipvlan_shim ip route add 172.28.244.0/24 dev ipvlan_shim
再次测试网络连通性,正常:
1 2 3 4 5 6 7 8 9
$ ip netns exec net1 ping -c 3 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.130 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.039 ms 64 bytes from 172.28.252.45: icmp_seq=3 ttl=64 time=0.036 ms
--- 172.28.252.45 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2110ms rtt min/avg/max/mdev = 0.036/0.068/0.130/0.043 ms
清理现场使用如下方式:
1 2 3 4
ip netns delete net1 ip netns delete net2 ip netns delete net3 ip link delete ipvlan_shim
L3
创建两个 ipvlan 子接口:
1 2 3
ip link add link eth0 name ipvlan1 type ipvlan mode l3 ip link add link eth0 name ipvlan2 type ipvlan mode l3 ip link add link eth0 name ipvlan3 type ipvlan mode l3
创建两个命名空间,将新创建的子接口移入且重命名:
1 2 3 4 5 6 7 8 9
ip netns add net1 ip netns add net2 ip netns add net3 ip link set ipvlan1 netns net1 ip link set ipvlan2 netns net2 ip link set ipvlan3 netns net3 ip netns exec net1 ip link set ipvlan1 name eth0 ip netns exec net2 ip link set ipvlan2 name eth0 ip netns exec net3 ip link set ipvlan3 name eth0
为两个子接口设置IP地址,而且他们不在同一个网络内:
1 2 3 4 5 6
ip netns exec net1 ip addr add 172.28.248.2/24 dev eth0 ip netns exec net2 ip addr add 172.28.248.3/24 dev eth0 ip netns exec net3 ip addr add 172.28.244.2/24 dev eth0 ip netns exec net1 ip link set eth0 up ip netns exec net2 ip link set eth0 up ip netns exec net3 ip link set eth0 up
net1 和 net2 处于相同的网络,网络连通性正常:
1 2 3 4 5 6 7 8 9 10 11 12 13
$ ip netns exec net1 route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.28.248.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 $ ip netns exec net1 ping -c 3 172.28.248.3 PING 172.28.248.3 (172.28.248.3) 56(84) bytes of data. 64 bytes from 172.28.248.3: icmp_seq=1 ttl=64 time=0.023 ms 64 bytes from 172.28.248.3: icmp_seq=2 ttl=64 time=0.022 ms 64 bytes from 172.28.248.3: icmp_seq=3 ttl=64 time=0.024 ms
--- 172.28.248.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2107ms rtt min/avg/max/mdev = 0.022/0.023/0.024/0.000 ms
net1 和 net3 不在同一个命名空间内网络不能互通:
1 2
$ ip netns exec net1 ping -c 3 172.28.244.3 ping: connect: Network is unreachable
但是 l3 模式下,可以通过设置默认路由的方式让两个网络互通:
1 2 3
ip netns exec net2 ip route add default via 172.28.248.1 ip netns exec net1 ip route add default via 172.28.248.1 ip netns exec net3 ip route add default via 172.28.244.1
验证 net1 和 net3 之间的连通性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ ip netns exec net1 ping -c 3 172.28.244.2 PING 172.28.244.2 (172.28.244.2) 56(84) bytes of data. 64 bytes from 172.28.244.2: icmp_seq=1 ttl=64 time=0.029 ms 64 bytes from 172.28.244.2: icmp_seq=2 ttl=64 time=0.022 ms 64 bytes from 172.28.244.2: icmp_seq=3 ttl=64 time=0.029 ms
--- 172.28.244.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2112ms rtt min/avg/max/mdev = 0.022/0.026/0.029/0.003 ms $ ip netns exec net3 ping -c 3 172.28.248.3 PING 172.28.248.3 (172.28.248.3) 56(84) bytes of data. 64 bytes from 172.28.248.3: icmp_seq=1 ttl=64 time=0.022 ms 64 bytes from 172.28.248.3: icmp_seq=2 ttl=64 time=0.021 ms 64 bytes from 172.28.248.3: icmp_seq=3 ttl=64 time=0.022 ms
--- 172.28.248.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2109ms rtt min/avg/max/mdev = 0.021/0.021/0.022/0.000 ms
如果想要从命名空间内访问到主机,需要额外创建一个 ipvlan 设备用作跳板:
1 2 3 4 5
ip link add link eth0 name ipvlan_shim type ipvlan mode l3 ip addr add 172.28.248.222/32 dev ipvlan_shim ip link set ipvlan_shim up ip route add 172.28.248.0/24 dev ipvlan_shim ip route add 172.28.244.0/24 dev ipvlan_shim
测试从命名空间到达宿主机的网络连通性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ ip netns exec net3 ping -c 3 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.047 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.029 ms 64 bytes from 172.28.252.45: icmp_seq=3 ttl=64 time=0.052 ms
--- 172.28.252.45 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2050ms rtt min/avg/max/mdev = 0.029/0.042/0.052/0.009 ms $ ip netns exec net1 ping -c 3 172.28.252.45 PING 172.28.252.45 (172.28.252.45) 56(84) bytes of data. 64 bytes from 172.28.252.45: icmp_seq=1 ttl=64 time=0.057 ms 64 bytes from 172.28.252.45: icmp_seq=2 ttl=64 time=0.038 ms 64 bytes from 172.28.252.45: icmp_seq=3 ttl=64 time=0.036 ms
--- 172.28.252.45 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2068ms rtt min/avg/max/mdev = 0.036/0.043/0.057/0.009 ms
清理现场:
1 2 3 4
ip netns delete net1 ip netns delete net2 ip netns delete net3 ip link delete ipvlan_shim
docker
创建基于 ipvlan 的容器网络:
1 2 3 4 5 6 7 8
$ docker network create -d ipvlan --subnet=172.28.240.0/20 --gateway=172.28.240.1 --ip-range 172.28.244.0/22 \ > --aux-address 'host=172.28.244.254' -o parent=eth0 -o ipvlan_mode=l2 ipvlan_l2 $ docker network ls NETWORK ID NAME DRIVER SCOPE 8599456a5481 bridge bridge local 72f3e075f337 host host local b92fa8a5d1eb ipvlan_l2 ipvlan local 5daaac101de2 none null local
基于 ipvlan 网络创建两个容器:
1 2
docker run -itd --name ubuntu1 --ip=172.28.244.2 --network ipvlan_l2 ubuntu:local docker run -itd --name ubuntu2 --ip=172.28.244.3 --network ipvlan_l2 ubuntu:local