前面文章我们详细介绍了 macvlan 这种技术,图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN,macvlan 详解由于它高效易配置的特性,被用在了 Docker 的网络方案设计中,这篇文章就来说说这个。

01 macvlan 用于 Docker 网络#

在 Docker 中,macvlan 是众多 Docker 网络模型中的一种,并且是一种跨主机的网络模型,作为一种驱动(driver)启用(-d 参数指定),Docker macvlan 只支持 bridge 模式。

下面我们做两个实验,分别验证相同 macvlan 网络和不同 macvlan 网络的连通性。

1.1 相同 macvlan 网络之间的通信#

首先准备两个主机节点的 Docker 环境,搭建如下拓扑图示:

1 首先使用 docker network create 分别在两台主机上创建两个 macvlan 网络:

Copy
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 网络:

Copy
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                local

2 在 host1 运行容器 c1,并指定使用 macvlan 网络:

Copy
root@ubuntu:~# docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox

这条命令中,

  • --ip 指定容器 c1 使用的 IP,这样做的目的是防止自动分配,造成 IP 冲突
  • --network 指定 macvlan 网络

同样在 host2 中运行容器 c2:

Copy
root@ubuntu:~# docker run -itd --name c2 --ip=172.16.10.3 --network mac1 busybox

3 在 host1 c1 中 ping host2 c2:

Copy
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 子接口。

Copy
# 使用 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 up

2 分别在 host1 和 host2 上基于两个 VLAN 子接口创建 2 个 macvlan 网络,mac10 和 mac20。

Copy
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 mac20

3 分别在 host1 和 host2 上运行容器,并指定不同的 macvlan 网络。

Copy
# 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 不了。

但这也只是在二层上通不了,通过三层的路由是可以通的,我们这就来验证下。

重新找一台主机 host3,通过打开 ip_forward 把它改造成一台路由器(至于为什么可以这样,可以参考我之前的一篇文章),用来打通两个 macvlan 网络,大概的图示如下所示:

1 首先对 host3 执行 sysctl -w net.ipv4.ip_forward=1 打开路由开关。

2 然后创建两个 VLAN 子接口,一个作为 macvlan 网络 mac10 的网关,一个作为 mac20 的网关。

Copy
[root@localhost ~]# vconfig add enp0s8 100
[root@localhost ~]# vconfig add enp0s8 200
[root@localhost ~]# vconfig set_flag enp0s8.100 1 1
[root@localhost ~]# vconfig set_flag enp0s8.200 1 1

# 对 vlan 子接口配置网关 IP 并启用
[root@localhost ~]# ifconfig enp0s8.100 172.16.10.1 netmask 255.255.255.0 up
[root@localhost ~]# ifconfig enp0s8.200 172.16.20.1 netmask 255.255.255.0 up

3 这样之后再从 d1 ping d2 和 d4,就可以 ping 通了。

Copy
root@ubuntu:~# docker exec d1 ping -c 2 172.16.20.10
PING 172.16.20.10 (172.16.20.10): 56 data bytes
64 bytes from 172.16.20.10: seq=0 ttl=63 time=0.661 ms
64 bytes from 172.16.20.10: seq=1 ttl=63 time=0.717 ms

— 172.16.20.10 ping statistics —
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.661/0.689/0.717 ms

Copy
root@ubuntu:~# docker exec d1 ping -c 2 172.16.20.11
PING 172.16.20.11 (172.16.20.11): 56 data bytes
64 bytes from 172.16.20.11: seq=0 ttl=63 time=0.548 ms
64 bytes from 172.16.20.11: seq=1 ttl=63 time=0.529 ms--- 172.16.20.11 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.529/0.538/0.548 ms

PS:可能有些系统做了安全限制,可能 ping 不通,这时候可以添加以下 iptables 规则,目的是让系统能够转发不通 VLAN 的数据包。

Copy
iptables -t nat -A POSTROUTING -o enp0s8.100 -j MASQUERADE

iptables -t nat -A POSTROUTING -oenp0s8.200 -j MASQUERADE

iptables -A FORWARD -i enp0s8.100 -o enp0s8.200 -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -i enp0s8.200 -o enp0s8.100 -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -i enp0s8.100 -o enp0s8.200 -j ACCEPT

iptables -A FORWARD -i enp0s8.200 -o enp0s8.100 -j ACCEPT

为什么配置 VLAN 子接口,配上 IP 就可以通了,我们可以看下路由表就知道了。

首先看容器 d1 的路由:

Copy
root@ubuntu:~# docker exec d1 ip route
default via 172.16.10.1 dev eth0
172.16.10.0/24 dev eth0 scope link  src 172.16.10.10

我们在创建容器的时候指定了网关 172.16.10.1,所以数据包自然会被路由到 host3 的接口。再来看下 host3 的路由:

Copy
[root@localhost ~]# ip route
default via 192.168.108.1 dev enp0s3 proto dhcp metric 100
172.16.10.0/24 dev enp0s8.100 proto kernel scope link src 172.16.10.1
172.16.20.0/24 dev enp0s8.200 proto kernel scope link src 172.16.20.1
192.168.56.0/24 dev enp0s8 proto kernel scope link src 192.168.56.122 metric 101
192.168.108.0/24 dev enp0s3 proto kernel scope link src 192.168.108.2 metric 100

可以看到,去往 172.16.10.0/24 网段的数据包会从 enp0s8.100 出去,同理 172.16.20.0/24 网段也是,再加上 host3 的 ip_forward 打开,这就打通了两个 macvlan 网络之间的通路。

02 总结#

macvlan 是一种网卡虚拟化技术,能够将一张网卡虚拟出多张网卡。

macvlan 的四种通信模式,常用模式是 bridge。

在 Docker 中,macvlan 只支持 bridge 模式。

相同 macvlan 可以通信,不同 macvlan 二层无法通信,可以借助三层路由完成通信。

思考一下:

  1. macvlan bridge 和 bridge 的异同点
  2. 还有一种类似的技术,多张虚拟网卡共享相同 MAC 地址,但有独立的 IP 地址,这是什么技术?

Docker 网络模型之 macvlan 详解,图解,实验完整相关推荐

  1. Docker(十四):Docker:网络模式详解

    Docker作为目前最火的轻量级容器技术,牛逼的功能,如Docker的镜像管理,不足的地方网络方面. Docker自身的4种网络工作方式,和一些自定义网络模式 安装Docker时,它会自动创建三个网络 ...

  2. Docker:网络模式详解

    http://www.cnblogs.com/zuxing/articles/8780661.html Docker:网络模式详解 袖珍指南 Docker作为目前最火的轻量级容器技术,牛逼的功能,如D ...

  3. Docker系列07—Dockerfile 详解

    Docker系列07-Dockerfile 详解 1.认识Dockerfile 1.1 镜像的生成途径 基于容器制作  dockerfile,docker build 基于容器制作镜像,已经在上篇Do ...

  4. Docker常用命令使用详解(docker help、version、info、images)(一)

    Docker常用命令 命令 描述 docker .docker help.docker --help 列出可用命令 docker version 显示Docker版本信息 docker info 显示 ...

  5. 深度学习网络模型——RepVGG网络详解、RepVGG网络训练花分类数据集整体项目实现

    深度学习网络模型--RepVGG网络详解.RepVGG网络训练花分类数据集整体项目实现 0 前言 1 RepVGG Block详解 2 结构重参数化 2.1 融合Conv2d和BN 2.2 Conv2 ...

  6. Docker持续部署图文详解

    2019独角兽企业重金招聘Python工程师标准>>> Docker持续部署图文详解 博客分类: docker 架构 JAVA项目如何通过Docker实现持续部署(只需简单四步),即 ...

  7. 基于Kubernetes构建Docker集群管理详解

    from: 基于Kubernetes构建Docker集群管理详解 Kubernetes是Google开源的容器集群管理系统,基于Docker构建一个容器的调度服务,提供资源调度.均衡容灾.服务注册.动 ...

  8. Windows 下OpenSSL 安装详解 +图解

    Windows 下OpenSSL 安装详解 +图解 转载于:https://www.cnblogs.com/zhujiabin/p/5088646.html

  9. docker entrypoint入口文件详解

    docker entrypoint入口文件详解 pasting Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较 [k8s]args指令案例-彻底理解docke ...

  10. 第20节 核心交换机配置热备份详解及实验演示—基于Cisco Packet Tracer

    核心交换机配置热备份详解及实验演示 1 网络规划 1.1 核心交换机的重要性及作用 1.2 对核心交换机做热备份 2 拓扑图分析 2.1 网络环路问题及解决方案 2.1.1 网络环路问题 2.1.2 ...

最新文章

  1. ES6, Angular,React和ABAP中的String Template(字符串模板)
  2. Linux日志收集logrotate原理介绍
  3. 搭建tidb集群linux_无服务器计算,学习Go,Linux系统恢复,TiDB,Udev等
  4. 帝国cms 留言板html,帝国CMS留言板加字段和验证码
  5. 华为scp快充协议详解_1A1C多协议快充,倍思30W PD PPS双口充电器(BS-CH905)评测...
  6. 高可用Redis(四):列表,集合与有序集合
  7. Vmware Workstation虚拟机繁忙导致虚拟机系统死机
  8. JAVA开发的人力资源管理系统
  9. 医院子母钟时钟系统方案
  10. Matlab之format 设置命令行窗口输出显示格式
  11. sea新浪云计算机平台,新浪云计算SAE免费申请使用及域名绑定
  12. Alan Walker MV 合辑01 by defender 歌词
  13. UPDATE STATISTICS
  14. jmeter中控制器的使用
  15. JPEG2000图象压缩标准及其关键算法(转)
  16. JAVA简单的控制台模拟斗地主
  17. x86架构手机_为什么苹果放弃的是x86,而不是ARM?
  18. odoo13 订单模板设置_Odoo + Anodoo功能介绍13-SaaS公司如何定义在线销售的订阅产品...
  19. 安卓盒子刷rec linux启动,常见电视或盒子进入Recovery模式的方法汇总
  20. 猿辅导获国际科研大奖:深度解析它为何在科研界“混得”风生水起

热门文章

  1. 雅礼集训 Day6 T2 Equation 解题报告
  2. 自动化框架应该具备的要点
  3. javascript 笔记--变量
  4. webstorm注释写出的提示
  5. Objective-C学习—UIScrollView控件使用
  6. DOS及BIOS中断调用实验
  7. 程序员有多少读过《人性的弱点》?项目经理呢?
  8. python如何处理文本文件_python如何选择合适的异常处理方式?
  9. cartographer安装_【ROS-SLAM】Cartographer ROS官方文档翻译学习(1)——下载与安装...
  10. Redis常见的5种不同的数据类型详解