docker_macvlan

目录

macvlan

macvlan的原理是在宿主机物理网卡上虚拟出多个子网卡,通过不同的MAC地址在数据链路层(Data Link Layer)进行网络数据转发的,它是比较新的网络虚拟化技术,需要较新的内核支持(Linux kernel v3.9–3.19 and 4.0+)。

准备实验环境

使用 node-1 和 host2 上单独的网卡ens38 创建 macvlan。为保证多个 MAC 地址的网络包都可以从 ens38通过,需要打开网卡的混杂模式

ip link set ens38 promisc on

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

006Gere4ly1fv3em9g8wnj30vf03z0t0.jpg

创建macvlan网络

006Gere4ly1fv3eu8jjufj30ql02v74d.jpg

在 node-2 中也要执行相同的命令

root@node-2:~# docker network create  -d macvlan --subnet=172.16.86.0/24 --gateway=172.16.86.1  -o parent=ens38 mac_net1
fc9f85149d08638194aef4722d255e0cbda8a982653ad858d9a76fa96b00f43e
root@node-2:~# 

-d macvlan 指定 driver 为 macvlan。

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

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

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

在 node-1 中运行容器 bbox1 并连接到 mac_net1。

由于 node-1 中的 mac_net1 与 node-2 中的 mac_net1 本质上是独立的,为了避免自动分配造成 IP 冲突,需要通过 --ip 指定 bbox1 地址为 172.16.86.11。

006Gere4ly1fv3f254yf3j30pv05hdg5.jpg

在 node-2 中运行容器 bbox2,指定 IP 172.16.86.10。

006Gere4ly1fv3ey4kncbj30oq02lzk8.jpg

验证 bbox1 和 bbox1 的连通性。

006Gere4ly1fv3f7w2ko2j30hr05bjrm.jpg

006Gere4ly1fv3f84pb11j30ho0543yr.jpg

macvlan 网络结构分析

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

006Gere4ly1fv3f96cqnbj30nr02qt8n.jpg

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

006Gere4ly1fv3fbds5o0j30n703sjrj.jpg

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

006Gere4ly1fv3fdfezhuj30yz028q30.jpg

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

006Gere4ly1fv3fo9eomej30w00i0jro.jpg

用 sub-interface 实现多 macvlan 网络

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

006Gere4ly1fv3fqfcxxtj30r202tjrf.jpg

macvlan 不仅可以连接到 interface(如 enp38),也可以连接到 sub-interface(如 ens38.xx)

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

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

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

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

enp38要接在交换机的 trunk 口上。如果用的是 VirtualBox 虚拟机,则不需要额外配置了。

在 ens38.10 和 ens38.20 上创建 macvlan 网络。

首先编辑 node-1和node-2 的 /etc/network/interfaces,配置 sub-auto ens38

006Gere4ly1fv3fx2acnjj30ee08omxe.jpg

然后启用 sub-interface:

ifup ens38.10

ifup ens38.20

006Gere4ly1fv3g0bxu73j30rc0k476h.jpg

创建 macvlan 网络:

docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens38.10 mac_net10

docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens38.20 mac_net20

在 node-1中运行容器:

docker run -itd --name bbox1 --ip=172.16.10.10 --network mac_net10 busybox

docker run -itd --name bbox2 --ip=172.16.20.10 --network mac_net20 busybox

006Gere4ly1fv3g4uqhcvj310s041glq.jpg
在 node-2中运行容器:

docker run -itd --name bbox3 --ip=172.16.10.11 --network mac_net10 busybox

docker run -itd --name bbox4 --ip=172.16.20.11 --network mac_net20 busybox

006Gere4ly1fv3g5aoop3j310803hq30.jpg

当前网络结构如图所示

006Gere4ly1fv3gdfet8pj30w00i03yy.jpg

macvlan的网络隔离和联通

macvlan 之间的连通性

006Gere4ly1fv4kc3jj5pj30gj09ujs3.jpg

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

006Gere4ly1fv4kd2y5y1j30ib03ot8p.jpg

bbox1 无法 ping 通 bbox2 和 bbox4。即:不同 macvlan 网络之间不能通信。但更准确的说法应该是:不同 macvlan 网络不能 在二层上 通信。

在三层上可以通过网关将 macvlan 连通,新建虚拟机(192.168.113.5 )做路由

将192.168.113.5 配置成一个虚拟路由器,设置网关并转发 VLAN10 和 VLAN20 的流:首先确保操作系统 IP Forwarding 已经启用。

root@node-2:~# ifconfig enp0s8.10 172.16.10.1 netmask 255.255.255.0 up
root@node-2:~# ifconfig enp0s8.20 172.16.20.1 netmask 255.255.255.0 up

需要开启防火墙

然后执行sysctl -w net.ipv4.ip_forward=1

添加 iptables 规则,转发不同 VLAN 的数据包。

root@node-2:~# iptables -t nat -A POSTROUTING -o enp0s8.10 -j MASQUERADE
root@node-2:~# iptables -t nat -A POSTROUTING -o enp0s8.20 -j MASQUERADE
root@node-2:~# iptables -A FORWARD -i enp0s8.10 -o enp0s8.20 -m state --state RELATED,ESTABLISHED -j ACCEPT
root@node-2:~# iptables -A FORWARD -i enp0s8.20 -o enp0s8.10 -m state --state RELATED,ESTABLISHED -j ACCEPT
root@node-2:~# iptables -A FORWARD -i enp0s8.10 -o enp0s8.20 -j ACCEPT
root@node-2:~# iptables -A FORWARD -i enp0s8.20 -o enp0s8.10 -j ACCEPT

006Gere4ly1fv4sovdqkjj30kp0ct757.jpg

upload-ueditor-image-20170820-1503219260462043301.jpg

① 因为 bbox1 与 bbox4 在不同的 IP 网段,跟据 bbox1 的路由表:

root@node-1:~# docker exec bbox1 ip route
default via 172.16.10.1 dev eth0 
172.16.10.0/24 dev eth0 scope link  src 172.16.10.10 
root@node-1:~# 

数据包将发送到网关 172.16.10.1。

② 路由器从 eth2.10 收到数据包,发现目的地址是 172.16.20.11,查看自己的路由表:

006Gere4ly1fv4t5jq04aj30pz05udg6.jpg

于是将数据包从 eth2.20 转发出去。

③ 通过 ARP 记录的信息,路由器能够得知 172.16.20.11 在 host2 上,于是将数据包发送给 host2。

④ host2 根据目的地址和 VLAN 信息将数据包发送给 bbox4。

macvlan 网络的连通和隔离完全依赖 VLAN、IP subnet 和路由,docker 本身不做任何限制,用户可以像管理传统 VLAN 网络那样管理 macvlan。

转载于:https://www.cnblogs.com/mrwuzs/p/9614558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值