IPVLAN 和 MACVLAN 类似,都是从一个主机接口虚拟出多个虚拟网络接口。一个重要的区别就是所有的虚拟接口都有相同的 mac 地址,而拥有不同的 ip 地址。
因为所有的虚拟接口要共享 mac 地址,所以有些需要注意的地方:
- DHCP 协议分配 ip 的时候一般会用 mac 地址作为机器的标识。这个情况下,客户端动态获取 ip 的时候需要配置唯一的 ClientID 字段,并且 DHCP server 也要正确配置使用该字段作为机器标识,而不是使用 mac 地址
Ipvlan 是 linux kernel 比较新的特性,linux kernel 3.19 开始支持 ipvlan,但是比较稳定推荐的版本是 >=4.2(因为 docker 对之前版本的支持有 bug),具体代码见内核目录:
/drivers/net/ipvlan/
工作模式
创建ipvlan的简单方法为
1 | $ ip link add link <master-dev> <slave-dev> type ipvlan mode { l2 | L3 } |
L2 模式
ipvlan L2 模式和 macvlan bridge 模式工作原理很相似,父接口作为交换机来转发子接口的数据。同一个网络的子接口可以通过父接口来转发数据,而如果想发送到其他网络,报文则会通过父接口的路由转发出去。
L3 模式
ipvlan 有点像路由器的功能,它在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同,即使虚拟机/容器不在同一个网络,也可以互相 ping 通对方,因为 ipvlan 会在中间做报文的转发工作。
注意 L3 模式下的虚拟接口 不会接收到多播或者广播的报文(这个模式下,所有的网络都会发送给父接口,所有的 ARP 过程或者其他多播报文都是在底层的父接口完成的)。另外外部网络默认情况下是不知道 ipvlan 虚拟出来的网络的,如果不在外部路由器上配置好对应的路由规则,ipvlan 的网络是不能被外部直接访问的。
实战体验
创建IPVlan L3模式
1 | [root@localhost ~]#ip link add link ens224 ipvlan1 type ipvlan mode l3 |
注意看ipvlan1 和ipvlan2 的MAC地址跟ens224的一样
1 | [root@localhost ~]# ip link |
创建ns绑定接口
1 | [root@localhost ~]#ip netns add net1 |
配置IP
1 | [root@localhost ~]#ip netns exec net1 ip addr add 10.0.2.18/24 dev ipvlan1 |
增加路由
1 | [root@localhost ~]#ip netns exec net1 route add default dev ipvlan1 |
ping测试,2个ns可以正常互相ping通,无法ping通宿主机IP
抓取ARP报文,结果无法在L3模式中抓到ARP,说明二层广播和组播都不处理,工作在L3。(这就是和L2模式的区别)
1 | [root@localhost ~]#ip netns exec net1 tcpdump -ni ipvlan1 -p arp |
创建L2模式,其余操作跟L3一样
1 | # ip link add link enp0s3 ipvlan1 type ipvlan mode l2 |
区别在于L2可以在2个ns中抓取到ARP报文
总结
ipvlan L3 模式中外部网络默认情况下是不知道 ipvlan 虚拟出来的网络的,如果不在外部路由器上配置好对应的路由规则,ipvlan 的网络是不能被外部直接访问的。
CNI 配置
cni配置格式为
1 | { |
需要注意的是
- ipvlan插件下,容器不能跟Host网络通信
- 主机接口(也就是master interface)不能同时作为ipvlan和macvlan的master接口