------------------------------------重要说明------------------------------------

本文内容都是参考Cloudman系列进行学习,是个人学习过程记录,与原版不同!

原版请参考cloudman《每天5分钟玩转Docker容器技术》Cloudman博客如下:

https://blog.51cto.com/cloudman

------------------------------------重要说明------------------------------------

macvlan 本身是 linxu kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。macvlan 本质上是一种网卡虚拟化技术,Docker 用 macvlan 实现容器网络就不奇怪了。

macvlan 的最大优点是性能极好,相比其他实现,macvlan 不需要创建 Linux bridge,而是直接通过以太 interface 连接到物理网络。下面我们就来创建一个 macvlan 网络。

a) 实验环境描述

Docker host(Ubuntu02) 192.168.56.130

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第1张图片

Docker host(Ubuntu03) 192.168.56.128

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第2张图片 

b) 环境准备

使用 docker02 和 docker03 上单独的网卡 ens33 创建 macvlan。为保证多个 MAC 地址的网络包都可以从 ens33 通过,我们需要打开网卡的混杂模式。

ip link set ens33 promisc on

确保 ens33 状态 UP 并且 promisc 模式已经生效

图片.png

图片.png

图片.png 

1) Workstation promisc

如果使用的是workstation for linux做实验,开启workstation网卡的混杂模式promisc;

1.将当前的虚拟机都关闭,退出workstation;

2.查看host中的vmnet;

ls -l /dev/vmnet*

3.更改vmnet权限;

chmod a+rw /dev/vmnet*

4.启动workstation;

2) Virtualbox promisc

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第3张图片

c) 创建macvlan

在 docker02 和 docker03 中创建 macvlan 网络 mac_net1:

图片.png

这里使用的网关是ens33网卡的IP地址;

图片.png 

这里使用的网关是ens33网卡的IP地址;

注意:在 host2 中也要执行相同的命令。

① -d macvlan 指定 driver 为 macvlan。

② macvlan 网络是 local 网络,为了保证跨主机能够通信,用户需要自己管理 IP subnet。

③ 与其他网络不同,docker 不会为 macvlan 创建网关,这里的网关应该是真实存在的,否则容器无法路由。

④ -o parent 指定使用的网络 interface。

在 docker02 中运行容器 bbox1 并连接到 mac_net1

图片.png 

由于 docker02 中的 mac_net1 与 docker03 中的 mac_net1 本质上是独立的,为了避免自动分配造成 IP 冲突,我们最好通过 --ip 指定 bbox1 地址为 172.16.56.151

在 docker03 中运行容器 bbox2,指定 IP 172.16.56.152

图片.png 

d) 连通测试

1) 验证 bbox1 和 bbox1 的连通性

图片.png 

看到bbox1可以ping同bbox2的IP地址,那测试ping主机名,验证是否能够解析:

图片.png

可见 docker 没有为 macvlan 提供 DNS 服务,这点与 overlay 网络是不同的。

2) 验证 bbox 和 docker02 docker03主机 的连通性

bbox1在docker02主机(192.168.56.130)

图片.png

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第4张图片
 

Bbox2在docker03主机(192.168.56.128)

图片.png 

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第5张图片 

3) 验证与互联网的连通性

图片.png 

图片.png 

重新创建macvlan网络,使用host的网关地址,测试是否可以与互联网通信

将创建的之前创建的container和network删除

创建网络

图片.png 

这里使用的网关是host(docker02、docker03)的网关地址;

图片.png

这里使用的网关是host(docker02、docker03)的网关地址;

运行容器在macvlan网络

图片.png 

图片.png 

bbox1的IP:192.168.56.151  bbox2的IP:192.168.56.152

测试连通性

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第6张图片 

图片.png 

容器之间可以ping通;

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第7张图片 

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第8张图片 

对方主机可以ping通;

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第9张图片
 

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第10张图片 

可以ping通www.baidu.com

图片.png 

图片.png 

容器所在host的ip,无法ping通

图片.png
 

图片.png
 

不具备DNS解析功能,ping hostname无法解析;

e) macvlan网络结构分析

macvlan 不依赖 Linux bridge,brctl show 可以确认没有创建新的 bridge。

图片.png

图片.png
 

查看一下容器的网络设备:

docker02

图片.png 

docker03

图片.png
 

除了 lo,容器只有一个 eth0,请注意 eth0 后面的 @if4,这表明该 interface 有一个对应的 interface,其全局的编号为 4。根据 macvlan 的原理,我们有理由猜测这个 interface 就是主机的 ens33,确认如下:

图片.png 

 

可见,容器的 eth0 就是 ens33 通过 macvlan 虚拟出来的 interface。容器的 interface 直接与主机的网卡连接,这种方案使得容器无需通过 NAT 和端口映射就能与外网直接通信(只要有网关),在网络上与其他独立主机没有区别。当前网络结构如图所示(引用cloudman博客中图)

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第11张图片

f) 用 sub-interface 实现多 macvlan 网络

macvlan 会独占主机的网卡,也就是说一个网卡只能创建一个 macvlan 网络,否则会报错:

图片.png

但主机的网卡数量是有限的,如何支持更多的 macvlan 网络呢?

好在 macvlan 不仅可以连接到 interface(如 ens33),也可以连接到 sub-interface(如 ens33.xxx)。

VLAN 是现代网络常用的网络虚拟化技术,它可以将物理的二层网络划分成多达 4094 个逻辑网络,这些逻辑网络在二层上是隔离的,每个逻辑网络(即 VLAN)由 VLAN ID 区分,VLAN ID 的取值为 1-4094。

1) 安装VLAN

Linux 的网卡也能支持 VLAN(apt-get install vlan),同一个 interface 可以收发多个 VLAN 的数据包,不过前提是要创建 VLAN 的 sub-interface。

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第12张图片

2) 配置VLAN接口

比如希望 ens33 同时支持 VLAN10 和 VLAN20,则需创建 sub-interface ens33.10 和 ens33.20。

在交换机上,如果某个 port 只能收发单个 VLAN 的数据,该 port 为 Access 模式,如果支持多 VLAN,则为 Trunk 模式,所以接下来实验的前提是:

ens33 要接在交换机的 trunk 口上。不过我们用的是 workstation/VirtualBox 虚拟机,则不需要额外配置了。

下面演示如何在 ens33.10 和 ens33.20 上创建 macvlan 网络。

首先编辑 docker02 和 docker03 的 /etc/network/interfaces,配置 sub-interface

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第13张图片

然后启用 sub-interface

systemctl restart networking.service

图片.png
 

配置docker02主机vlan10接口(ens33.10)的macvlan网络

图片.png
 

配置docker02主机vlan20接口(ens33.20)的macvlan网络

图片.png
 

配置docker03主机vlan10接口(ens33.10)的macvlan网络

图片.png
 

配置docker03主机vlan20接口(ens33.20)的macvlan网络

图片.png
 

配置docker02主机vlan10的容器(172.16.10.11)

图片.png
 

配置docker02主机vlan20的容器(172.16.20.11)

图片.png
 

配置docker03主机vlan10的容器(172.16.10.12)

图片.png 

配置docker03主机vlan20的容器(172.16.20.12)

图片.png 

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第14张图片 

3) sub-interface连通性测试

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第15张图片
 

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第16张图片 

bbox1 能 ping 通 bbox2,bbox3 能 ping 通 bbox4。即:同一 macvlan 网络能通信。

bbox1 无法 ping 通 bbox3 和 bbox4。即:不同 macvlan 网络之间不能通信。但更准确的说法应该是:不同 macvlan 网络不能 在二层上 通信。在三层上可以通过网关将 macvlan 连通,下面我们就启用网关。

将 Host 192.168.56.130 配置成一个虚拟路由器,设置网关并转发 VLAN10 和 VLAN20 的流量。当然也可以使用物理路由器达到同样的效果。首先确保操作系统 IP Forwarding 已经启用。

图片.png

输出为 1 则表示启用,如果为 0 可通过如下命令启用:

sysctl -w net.ipv4.ip_forward=1

------------------------------------重要说明------------------------------------

本文内容都是参考Cloudman系列进行学习,是个人学习过程记录,与原版不同!

原版请参考cloudman《每天5分钟玩转Docker容器技术》Cloudman博客如下:

https://blog.51cto.com/cloudman

------------------------------------重要说明------------------------------------

书籍:

1.《每天5分钟玩转Kubernetes》
https://item.jd.com/26225745440.html

2.《每天5分钟玩转Docker容器技术》
https://item.jd.com/16936307278.html

3.《每天5分钟玩转OpenStack》
https://item.jd.com/12086376.html

20、《每天5分钟玩转Docker容器技术》学习--macvlan Network_第17张图片