macvlan
可以将一块物理网卡虚拟成多块虚拟网卡,并可以配置不同的 mac
地址(之前单网卡配置多IP使用的是同一个mac
地址)。Linux kernel v3.9–3.19
和 4.0+
之后开始支持 macvlans
技术。使用 macvlan
技术虚拟出来的虚拟网卡,在逻辑上和物理网卡功能相同。macvlan
可以看成一个简单的 Bridge,但也有很大的不同。
特点
- 一张物理网卡绑定多个
MAC
地址
macvlan
虚拟的网卡称为子接口(sub interface)
,物理网卡则称为父接口(parent interface)
父接口(parent interface)
可以是一个物理接口
、子接口(eth0.10)
或 bonding 接口
父接口(parent interface)
和 子接口(sub interface)
均可以配置 MAC
地址和 IP
地址
子接口(sub interface)
无法直接与 父接口(parent interface)
联通,需要通过三层通信
加载
# 加载
$ modprobe macvlan
# 查看是否加载
$ lsmod | grep macvlan
macvlan 24576 0
四种模式
根据 macvlan
子接口之间的通信模式可以分为四种网络模式:
- VEPA(Virtual Ethernet Port Aggregator)模式(默认):
子接口(sub interface)
之间的流量需要经过外部支持 802.1Qbg/VPEA
功能的交换机(物理的或虚拟)上转发(需要支持Hairpin
功能),才能通信。创建 Harpin
模式的 Bridge
命令如下:
brctl hairpin br0 ens33 on
# or
bridge link set dev ens33 hairpin on
- Private 模式:同一
父接口(parent interface)
下的子接口(sub interface)
之间彼此隔离,不能通信。即使从外部的物理交换机导流,也会被丢掉
- Bridge 模式:模拟
Linux bridge
的功能,但比 bridge
要好的一点是每个接口的 MAC
地址是已知的,不用学习。所以,该模式下子接口(sub interface)
之间就是直接可以通信的
- Passthru 模式:只允许单个子接口连接主接口,且必须设置成混杂模式,一般用于子接口桥接和创建 VLAN 子接口的场景
创建
ip link add link DEVICE name NAME type { macvlan | macvtap } mode { private | vepa | bridge | passthru [ nopromisc ] }
使用场景
结合 VM
和容器
来构建网络。
示例
使用 bridge 模式
为网卡 ens33
创建两个 macvlan
子接口,配置 IP
并挂到两个 netns 中,测试连通性。
# 创建两个 macvlan 子接口 mac1@ens33、mac2@ens33
ip link add link ens33 dev mac1 type macvlan mode bridge
ip link add link ens33 dev mac2 type macvlan mode bridge
# 创建两个 netns
ip netns add ns1
ip netns add ns2
# 将两个子接口分别挂到两个 netns 中
ip link set mac1 netns ns1
ip link set mac2 netns ns2
# 配置 IP 并启用,ens33 的 IP 是 172.20.0.20/24,配置的子接口 IP 也必须是同一网段的
ip netns exec ns1 ip addr add 172.20.0.101/24 dev mac1
ip netns exec ns1 ip link set mac1 up
ip netns exec ns2 ip addr add 172.20.0.102/24 dev mac2
ip netns exec ns2 ip link set mac2 up
# 查看
$ ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: mac1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 32:c2:12:bc:4d:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.0.101/24 scope global mac1
valid_lft forever preferred_lft forever
inet6 fd15:4ba5:5a2b:1003:30c2:12ff:febc:4d99/64 scope global mngtmpaddr dynamic
valid_lft 2591990sec preferred_lft 604790sec
inet6 fe80::30c2:12ff:febc:4d99/64 scope link
valid_lft forever preferred_lft forever
$ ip netns exec ns2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: mac2@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 4e:60:d4:4b:95:52 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.0.102/24 scope global mac2
valid_lft forever preferred_lft forever
inet6 fd15:4ba5:5a2b:1003:4c60:d4ff:fe4b:9552/64 scope global mngtmpaddr dynamic
valid_lft 2591981sec preferred_lft 604781sec
inet6 fe80::4c60:d4ff:fe4b:9552/64 scope link
valid_lft forever preferred_lft forever
$ ip netns exec ns1 ping -c 1 172.20.0.102
PING 172.20.0.102 (172.20.0.102) 56(84) bytes of data.
64 bytes from 172.20.0.102: icmp_seq=1 ttl=64 time=0.044 ms
--- 172.20.0.102 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.044/0.044/0.044/0.000 ms
扩展
mactap
也能实现类似的功能。