本文首发于我的公众号码农之屋(id: Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。
导读:macvlan是linux kernel提供的网络虚拟化技术之一,它将物理网卡虚拟出多块虚拟网卡,每块虚拟网卡都有自己的mac地址和IP地址,相当于物理网卡施展了多重影分身之术,由一块变成多块。
一、macvlan简介
有时我们可能需要一块物理网卡绑定多个IP以及多个MAC地址,虽然绑定多个IP很容易,但是这些IP会共享物理网卡的MAC地址,无法满足我们的设计需求,所以才有了macvlan虚拟网络技术。macvlan是linux kernel v3.9才开始支持的新特性,它一般是以内核模块的形式存在,当前比较稳定的版本是4.0+。
macvlan听起来有点像vlan,但它们的实现机制是完全不一样的。macvlan子接口和主接口是完全独立的,可以单独配置MAC地址和IP地址,而VLAN子接口和主接口是共用相同的MAC地址。从功能上看,vlan是用来划分广播域,而macvlan则共享同一个广播域。
macvlan会根据收到包的目的MAC地址判断这个包需要交给哪个虚拟网卡,然后再由虚拟网卡交予上层协议栈进行处理,具体的原理图可以参考图1所示。
二、四种工作模式
根据macvlan子接口之间的通信模式,macvlan共有四种网络模式:bridge模式、vepa模式、private模式和passthru模式,默认是使用vepa模式,但是常用的是bridge模式。
1、bridge模式
bridge模式只是针对同属于一块宿主物理网卡的macvlan网卡以及宿主网卡之间的通信行为的,与外部通信无关。所谓的bridge指的是在这些网卡之间,数据流可以实现直接转发,不需要外部的协助,这有点像在Linux内建了一个bridge,但比bridge要好的一点是每块网卡的MAC地址都是已知的,不需要重新学习。
2、vepa模式
vepa模式下,子接口间不能直接通信,必须要通过与物理网卡相连的外部交换机(物理或虚拟的都可以,需支持802.1Qbg/VPEA功能,直白点就是数据包从接口收到上之后还能传回去)的协助,经由外部交换机转发,再绕回来。
3、private模式
private模式的隔离性比vepa模式更强。在private模式下,即使是macvlan eth1和macvlan eth2同时配在在eth0上,eth0连接了外部交换机S,S支持“发夹弯”转发模式,macvlan eth1的广播/多播流量也无法到达macvlan eth2,反之亦然。也就是说,private模式下,子接口间是无法通信的。
4、passthrough模式
passthrough模式只允许单个子接口连接主接口,且主接口必须设置成混杂模式,一般用于子接口桥接和创建vlan子接口的场景。
三、macvlan收发包报文流程
对于macvlan的收发包流程,这里不再一一介绍,具体的流程可参考图6所示,建议能够结合内核代码,加深macvlan收发包流程的理解。
四、示例
单独使用macvlan技术是毫无意义的,一般都是结合VM或容器来构建网络。下面我们就简单使用namespace来看看怎么使用macvlan的。以接口eth0为例创建两个macvlan子接口(使用bridge模式),配置IP并将其挂到两个namespace中,测试两macvlan子接口是否能通,具体的实验拓展图请参考图7所示。
1、创建2 macvlan子接口
[root@node]# ip link add link eth0 dev macvlaneth00 type macvlan mode bridge
[root@node]# ip link add link eth0 dev macvlaneth01 type macvlan mode bridge
2、创建2 net namespace,并把2 macvlan子接口分别挂到2 namespace中
[root@node]# ip netns add ns2
[root@node]# ip netns add ns3
[root@node]# ip link set macvlaneth00 netns ns2
[root@node]# ip link set macvlaneth01 netns ns3
3、配置macvlan子接口IP(需与eth0同网段),并启动
[root@node]# ip netns exec ns2 ip a a 200.10.10.112/24 dev macvlaneth00
[root@node]# ip netns exec ns3 ip a a 200.10.10.116/24 dev macvlaneth01
[root@node]# ip netns exec ns2 ip l s macvlaneth00 up
[root@node]# ip netns exec ns3 ip l s macvlaneth01 up
4、验证2 macvlan子接口之间是否能通(从实验结果看,bridge模式下,2子接口是可以直接互通的)
[root@node]# ip netns exec ns3 ping 200.10.10.112
PING200.10.10.112 (200.10.10.112) 56(84) bytes of data.
64bytes from 200.10.10.112: icmp_seq=1 ttl=64 time=0.097 ms
64bytes from 200.10.10.112: icmp_seq=2 ttl=64 time=0.065 ms
64bytes from 200.10.10.112: icmp_seq=3 ttl=64 time=0.073 ms
^C
---200.10.10.112 ping statistics ---
3packets transmitted, 3 received, 0% packet loss, time 1999ms
rttmin/avg/max/mdev = 0.065/0.078/0.097/0.015 ms
[root@node]# ip netns exec ns2 ping 200.10.10.116
PING200.10.10.116 (200.10.10.116) 56(84) bytes of data.
64bytes from 200.10.10.116: icmp_seq=1 ttl=64 time=0.056 ms
64bytes from 200.10.10.116: icmp_seq=2 ttl=64 time=0.075 ms
64bytes from 200.10.10.116: icmp_seq=3 ttl=64 time=0.077 ms
64bytes from 200.10.10.116: icmp_seq=4 ttl=64 time=0.056 ms
^C
---200.10.10.116 ping statistics ---
4packets transmitted, 4 received, 0% packet loss, time 2999ms
rttmin/avg/max/mdev = 0.056/0.066/0.077/0.010 ms
我的公众号「码农之屋」(id: Spider1818) ,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。