本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫。
上一篇文章我们详细介绍了 macvlan 这种技术,,由于它高效易配置的特性,被用在了 Docker 的网络方案设计中,这篇文章就来说说这个。
01 macvlan 用于 Docker 网络在 Docker 中,macvlan 是众多 Docker 网络模型中的一种,并且是一种跨主机的网络模型,作为一种驱动(driver)启用(-d 参数指定),Docker macvlan 只支持 bridge 模式。
下面我们做两个实验,分别验证相同 macvlan 网络和不同 macvlan 网络的连通性。
1.1 相同 macvlan 网络之间的通信首先准备两个主机节点的 Docker 环境,搭建如下拓扑图示:
1 首先使用 docker network create 分别在两台主机上创建两个 macvlan 网络:
root@ubuntu:~# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=enp0s8 mac1这条命令中,
-d 指定 Docker 网络 driver
--subnet 指定 macvlan 网络所在的网络
--gateway 指定网关
-o parent 指定用来分配 macvlan 网络的物理网卡
之后可以看到当前主机的网络环境,其中出现了 macvlan 网络:
root@ubuntu:~# docker network ls NETWORK ID NAME DRIVER SCOPE 128956db798a bridge bridge local 19fb1af129e6 host host local 2509b3717813 mac1 macvlan local d5b0798e725e none null local2 在 host1 运行容器 c1,并指定使用 macvlan 网络:
root@ubuntu:~# docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox这条命令中,
--ip 指定容器 c1 使用的 IP,这样做的目的是防止自动分配,造成 IP 冲突
--network 指定 macvlan 网络
同样在 host2 中运行容器 c2:
root@ubuntu:~# docker run -itd --name c2 --ip=172.16.10.3 --network mac1 busybox3 在 host1 c1 中 ping host2 c2:
root@ubuntu:~# docker exec c1 ping -c 2 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=0.641 ms 64 bytes from 172.16.10.3: seq=1 ttl=64 time=0.393 ms --- 172.16.10.3 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.393/0.517/0.641 ms注意:以上的实验都需要物理网卡 enp0s8 开启混杂模式,不然会 ping 不通。
1.2 不同 macvlan 网络之间的通信接下来,我们来看看不同 macvlan 网络之间的连通性,搭建以下的拓扑环境:
由于 macvlan 网络会独占物理网卡,也就是说一张物理网卡只能创建一个 macvlan 网络,如果我们想创建多个 macvlan 网络就得用多张网卡,但主机的物理网卡是有限的,怎么办呢?
好在 macvlan 网络也是支持 VLAN 子接口的,所以,我们可以通过 VLAN 技术将一个网口划分出多个子网口,这样就可以基于子网口来创建 macvlan 网络了,下面是具体的创建过程。
1 首先分别在两台主机上将物理网口 enp0s8 创建出两个 VLAN 子接口。
# 使用 vconfig 命令在 eth0 配置两个 VLAN root@ubuntu:~# vconfig add enp0s8 100 root@ubuntu:~# vconfig add enp0s8 200 # 设置 VLAN 的 REORDER_HDR 参数,默认就行了 root@ubuntu:~# vconfig set_flag enp0s8.100 1 1 root@ubuntu:~# vconfig set_flag enp0s8.200 1 1 # 启用接口 root@ubuntu:~# ifconfig enp0s8.100 up root@ubuntu:~# ifconfig enp0s8.200 up2 分别在 host1 和 host2 上基于两个 VLAN 子接口创建 2 个 macvlan 网络,mac10 和 mac20。
root@ubuntu:~# docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=enp0s8.100 mac10 root@ubuntu:~# docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=enp0s8.200 mac203 分别在 host1 和 host2 上运行容器,并指定不同的 macvlan 网络。
# host1 root@ubuntu:~# docker run -itd --name d1 --ip=172.16.10.10 --network mac10 busybox root@ubuntu:~# docker run -itd --name d2 --ip=172.16.20.10 --network mac20 busybox # host2 root@ubuntu:~# docker run -itd --name d3 --ip=172.16.10.11 --network mac10 busybox root@ubuntu:~# docker run -itd --name d4 --ip=172.16.20.11 --network mac20 busybox通过验证,d1 和 d3,d2 和 d4 在同一 macvlan 网络下,互相可以 ping 通,d1 和 d2,d1 和 d4 在不同的 macvlan 网络下,互相 ping 不通。
这个原因也很明确,不同 macvlan 网络处于不同的网络,而且通过 VLAN 隔离,自然 ping 不了。
但这也只是在二层上通不了,通过三层的路由是可以通的,我们这就来验证下。