macvlan是有一些局限性的,ipvlan也能够解决macvlan的一些限制。
macvlan和ipvlan虚拟网络模型提供的功能看起来差不多。macvlan存在一些先天不足:
- 无法支持大量的mac地址
- 无法工作在无线网络环境中
ipvlan也是从一个主机的接口虚拟出多个网络接口。区别在于ipvlan的所有虚拟接口都是用相同的mac地址,而ip地址却各不相同。因为共享mac地址,所以DHCP的场景一般会使用mac地址作为机器的标识。在macvlan的场景下,客户端动态获取IP的时候需要配置唯一的clientID,并且DHCP服务器也要使用作为机器的标识而不是mac地址。
- linux 3.19开始支持ipvlan,4.2+docker才能稳定的支持ipvlan。
IPvlan有L2,L3两种模式,一个父接口只能选择其中一种模式。
ipvlan l2 和macvlan 的bridge 很相似。
[root@node2 ~]# nsenter -t 29159 -n 用法: nsenter [options]2.1.2 mode l3[...] Run a program with namespaces of other processes. 选项: -t, --target 要获取名字空间的目标进程 -m, --mount[= ] enter mount namespace -u, --uts[= ] enter UTS namespace (hostname etc) -i, --ipc[= ] enter System V IPC namespace -n, --net[= ] enter network namespace -p, --pid[= ] enter pid namespace -U, --user[= ] enter user namespace -S, --setuid set uid in entered namespace -G, --setgid set gid in entered namespace --preserve-credentials do not touch uids or gids -r, --root[= ] set the root directory -w, --wd[= ] set the working directory -F, --no-fork 执行 <程序> 前不 fork -Z, --follow-context set SELinux context according to --target PID -h, --help 显示此帮助并退出 -V, --version 输出版本信息并退出
L3,类似于路由器的功能,只要父接口相同,即使虚拟机/容器不在同一个网络中,也可以互相ping通对方。ipvlan会在中间做报文转发的工作。
下图参考链接:https://cizixs.com/2017/02/17/network-virtualization-ipvlan/
L3模式下虚拟接口不会接收多播或者广播 的报文。原因是所有的网络都会发往父接口,所有的ARP过程或者其他多播报文都是在底层父接口完成的。
notice:如果不在外部路由器上配置好对应的路由规则,那么ipvlan的网络不能被外部直接访问。
2.1.3 测试环境ipvlan l3- 内核参数
[root@node2 ~]# uname -a Linux node2 5.14.7-1.el7.elrepo.x86_64 #1 SMP Tue Sep 21 11:14:57 EDT 2021 x86_64 x86_64 x86_64 GNU/Linux [root@node2 ~]#
- 创建ns
[root@node2 ~]# ip netns add test1 [root@node2 ~]# ip netns add test2 --- [root@node2 ~]# ip netns list test2 test1
- 创建link
[root@node2 ~]# ip link add ipv1 link eth0 type ipvlan mode l3 [root@node2 ~]# ip link add ipv2 link eth0 type ipvlan mode l3 [root@node2 ~]# ip link 1: lo:mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: mtu 1450 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether fa:16:3e:bc:07:c1 brd ff:ff:ff:ff:ff:ff 3: eth1: mtu 1450 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether fa:16:3e:d2:fc:fa brd ff:ff:ff:ff:ff:ff ... 360: ipv1@eth0: mtu 1450 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether fa:16:3e:bc:07:c1 brd ff:ff:ff:ff:ff:ff 361: ipv2@eth0: mtu 1450 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether fa:16:3e:bc:07:c1 brd ff:ff:ff:ff:ff:ff [root@node2 ~]#
- 网卡up
[root@node2 ~]# ip link set ipv1 netns test1 [root@node2 ~]# ip link set ipv2 netns test2 [root@node2 ~]# [root@node2 ~]# ip netns exec test1 ip link set ipv1 up [root@node2 ~]# ip netns exec test2 ip link set ipv2 up [root@node2 ~]# [root@node2 ~]# ip netns list test2 (id: 7) test1 (id: 6) [root@node2 ~]#
- 配置ip和默认路由
[root@node2 ~]# ip netns exec test1 ip addr add 11.0.1.10/24 dev ipv1 [root@node2 ~]# ip netns exec test2 ip addr add 12.0.1.10/24 dev ipv2 [root@node2 ~]# [root@node2 ~]# ip netns exec test1 ip route add default dev ipv1 [root@node2 ~]# ip netns exec test2 ip route add default dev ipv2
- 测试网络连通性
[root@node2 ~]# ip netns exec test1 ping -c 3 12.0.1.10 PING 12.0.1.10 (12.0.1.10) 56(84) bytes of data. 64 bytes from 12.0.1.10: icmp_seq=1 ttl=64 time=0.148 ms 64 bytes from 12.0.1.10: icmp_seq=2 ttl=64 time=0.094 ms2.1.4 小结
ipvlan能够基于ipvlan搭建比较复杂的网络拓扑,不在基于macvlan简单的二层网络。能够与BGP等协议扩展网络边界。
(docker 1.13 加入了ipvlan的支持)
但是有好多的地方没有明白。
比如:
- 使用了ipvlan l2mode ,calico,multus-cni实现了pod的双网卡,但是我在主机上并不能看到pod的ip。只能通过进入到pod的命名空间下查看网卡才能知道这个pod的ip是什么。有没有简单的linux命令能看到pod的ip及netns呢?
- 如何实现notice,在外部直接访问mode l3的网络呢?
- docker中的实现方式,现在还可以指定vlan id。 方法很多需要了解下,https://docs.docker.com/network/ipvlan/
可能这部分的实现原理需要在multus、ipvlan中一探究竟。



