目录
- 一、实验环境
- 二、创建macvlan网络
- 三、用macvlan网络创建容器:
- 四、网络结构分析:
- 五、不同 macvlan 网络之间的通信
macvlan 本身是 linux kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP,macvlan 本质上是一种网卡虚拟化技术。
一、实验环境
IP | 主机名 | 内核版本 |
---|---|---|
10.1.1.17 | master | kernel-5.2.11 |
10.1.1.13 | host1 | kernel-5.2.11 |
10.1.1.14 | host2 | kernel-5.2.11 |
二、创建macvlan网络
在master、node1和node2上同时执行以下命令:
1 2 3 4 5 6 7 8 | [root@master ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1 476cfc5eb16c51647c02f87ff682452d4a76568b47d770a612996d0e09420e21 [root@master ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 7fd1d76008e3 bridge bridge local af93f80d0ba6 host host local 476cfc5eb16c mac1 macvlan local 23d2bfb36bf0 none null local |
node1:
1 2 3 4 5 6 7 8 | [root@node1 ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1 33e73b4f6637ce7064b4f6198a43125f07557e7bf824ad1ea39a276e910e11eb [root@node1 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9986d9dda86f bridge bridge local 8611ebf969a6 host host local 33e73b4f6637 mac1 macvlan local 556e2a599b82 none null local |
node2:
1 2 3 4 5 6 7 8 | [root@node2 ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1 14b860ca6be2458d3f210286be2f6a867177403f41d96985a5fcac60ec93fa78 [root@node2 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 3891241149c3 bridge bridge local a63bf958be9e host host local 14b860ca6be2 mac1 macvlan local fb8797af5710 none null local |
三、用macvlan网络创建容器:
master:
1 2 | [root@master ~]# docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox 50f2d1b18bcf4301a13afa08c5eb780f1d37351e3e30617076c5a557e4eda512 |
node1:
1 2 | [root@node1 ~]# docker run -itd --name c2 --ip=172.16.10.3 --network mac1 busybox 91ce7ad4a9f628417067a93df8c547199af438a8d0b1b20d616cbdc3742b655a |
node2:
1 2 | [root@node2 ~]# docker run -itd --name c3 --ip=172.16.10.4 --network mac1 busybox 02fa6f6be82c6c680f0e798662e3555bae204dddfa5b722d00b5f71ca80a7163 |
(4)三个容器的IP分别为172.16.10.2\3\4,进入容器互相ping对方:
master:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@master ~]# docker attach c1 / # ping -c 1 172.16.10.3 PING 172.16.10.3 (172.16.10.3): 56 data bytes 64 bytes from 172.16.10.3: seq=0 ttl=64 time=2.546 ms --- 172.16.10.3 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 2.546/2.546/2.546 ms / # ping -c 1 172.16.10.4 PING 172.16.10.4 (172.16.10.4): 56 data bytes 64 bytes from 172.16.10.4: seq=0 ttl=64 time=1.240 ms --- 172.16.10.4 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 1.240/1.240/1.240 ms |
node1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@node1 ~]# docker attach c2 / # ping -c 1 172.16.10.2 PING 172.16.10.2 (172.16.10.2): 56 data bytes 64 bytes from 172.16.10.2: seq=0 ttl=64 time=0.510 ms --- 172.16.10.2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.510/0.510/0.510 ms / # ping -c 1 172.16.10.4 PING 172.16.10.4 (172.16.10.4): 56 data bytes 64 bytes from 172.16.10.4: seq=0 ttl=64 time=1.460 ms --- 172.16.10.4 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 1.460/1.460/1.460 ms |
node2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@node2 ~]# docker attach c3 / # ping -c 1 172.16.10.2 PING 172.16.10.2 (172.16.10.2): 56 data bytes 64 bytes from 172.16.10.2: seq=0 ttl=64 time=1.994 ms --- 172.16.10.2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 1.994/1.994/1.994 ms / # ping -c 1 172.16.10.3 PING 172.16.10.3 (172.16.10.3): 56 data bytes 64 bytes from 172.16.10.3: seq=0 ttl=64 time=1.213 ms --- 172.16.10.3 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 1.213/1.213/1.213 ms |
互相之间都是能够ping通的。
四、网络结构分析:
macvlan是不依赖Linux bridge的,创建好macvlan网络之后,通过brctl show可以确认没有创建新的网桥:
1 2 3 | [root@master ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.024276b03dbc no |
查看c1容器的网络:
1 2 3 4 5 | [root@master ~]# docker exec c1 ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:10:0a:02 brd ff:ff:ff:ff:ff:ff |
除了lo,容器只有一个eth0,eth0后面有个if2,这说明该接口有个对应的interface,全局编号为2,而在主机上执行 ip link可以看到,ens33的编号也是2:
1 2 3 4 5 6 7 | [root@master ~]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:c9:32:dd brd ff:ff:ff:ff:ff:ff 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:76:b0:3d:bc brd ff:ff:ff:ff:ff:ff |
所以,可以确定的是,容器抄底eth0就是ens33通过macvlan虚拟出来的interface。容器的interface直接与主机的网卡进行连接,这种方案使得容器无需通过NAT和端口映射就能与外网相通,在网络上与其他独立主机没有区别。
五、不同 macvlan 网络之间的通信
macvlan会独占主机的网卡,也就是说每个网卡只能创建一个macvlan网络,否则会报错。但主机的网卡是有限的,如何支持更多的macvlan网络呢?好在macvlan不仅可以连接到interface,如ens33,还可以连接到sub-interface,如ens33.100,ens33.200。
Linux网卡支持VLAN技术,VLAN是现代常用的网络虚拟化技术,同一个网卡(interface)可以支持多个VLAN的数据包,不过前提是要创建sub-interface。
比如希望ens33网卡支持VLAN10和VLAN20,则需要创建sub-interface ens33.10和ens33.20。在交换机上,如果某个口智能手法单个VLAN的数据,则port为access模式;若要接受多个VLAN的数据,则为trunk模式。所以ens33网卡对端要接在交换机的trunk口上。因为我们是虚拟机,就不需要这样操作了。下面开始创建基于VLAN的macvlan网络。
首先两台主机上安装vconfig工具:
1 2 | [root@master ~]# wget https://mirrors.aliyun.com/centos/6.10/os/x86_64/Packages/vconfig-1.9-8.1.el6.x86_64.rpm rpm -ivh vconfig-1.9-8.1.el6.x86_64.rpm |
加载8021q模块:
1 | [root@master ~]# modprobe 8021q |
开启ens33网卡的混杂模式:
1 | [root@master ~]# ifconfig ens33 promisc |
确认混杂模式已经开启:
1 2 3 4 5 6 7 8 | ens33: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500 inet 10.1.1.13 netmask 255.255.255.0 broadcast 10.1.1.255 inet6 fe80::55d8:65e5:d67d:8eaf prefixlen 64 scopeid 0x20<link> ether 00:0c:29:5c:02:a3 txqueuelen 1000 (Ethernet) RX packets 138 bytes 14859 (14.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 210 bytes 21630 (21.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 |
启用IPV4. forwarding:
1 2 | [root@master ~]# vim /etc/sysctl.conf net.ipv4.ip_forward=1 |
然后重启network。
1 | [root@master ~]# systemctl restart network |
现在三台主机上分别基于ens33网卡创建两个VLAN:
1 2 | [root@master ~]# vconfig add ens33 100 [root@master ~]# vconfig add ens33 200 |
启用VLAN:
1 2 | [root@master ~]# ifconfig ens33.100 up [root@master ~]# ifconfig ens33.200 up |
基于两个子接口分别创建mac10和mac20的macvlan网络:
1 2 | [root@master ~]# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33.100 mac10 [root@master ~]# docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens33.200 mac20 |
在node1上创建d1和d2两个容器,分别基于mac10和mac20:
1 2 | [root@master ~]# docker run -itd --name d1 --ip=172.16.10.10 --network mac10 busybox [root@master ~]# docker run -itd --name d2 --ip=172.16.20.10 --network mac20 busybox |
在node2上创建d3和d4两个容器,分别基于mac10和mac20:
1 2 | [root@master ~]# docker run -itd --name d3 --ip=172.16.10.11 --network mac10 busybox [root@master ~]# docker run -itd --name d4 --ip=172.16.20.11 --network mac20 busybox |
正常来讲d1和d3属于同一个网段,d2和d4属于同一个网段,应该是能ping通的,目前我的实验没通,不知道是不是虚拟机本身不支持这个网络。正在研究中。