2. ipvlan
macvlan是有一些局限性的,ipvlan也能够解决macvlan的一些限制。
macvlan和ipvlan虚拟网络模型提供的功能看起来差不多。macvlan存在一些先天不足:
2.1 ipvlan介绍
ipvlan也是从一个主机的接口虚拟出多个网络接口。区别在于ipvlan的所有虚拟接口都是用相同的mac地址,而ip地址却各不相同。因为共享mac地址,所以DHCP的场景一般会使用mac地址作为机器的标识。在macvlan的场景下,客户端动态获取IP的时候需要配置唯一的clientID,并且DHCP服务器也要使用作为机器的标识而不是mac地址。
- linux 3.19开始支持ipvlan,4.2+docker才能稳定的支持ipvlan。
2.1.1 mode L2
IPvlan有L2,L3两种模式,一个父接口只能选择其中一种模式。
ipvlan l2 和macvlan 的bridge 很相似。
[root@node2 ~]# nsenter -t 29159 -n
用法:
nsenter [options] <program> [<argument>...]
Run a program with namespaces of other processes.
选项:
-t, --target <pid> 要获取名字空间的目标进程
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork 执行 <程序> 前不 fork
-Z, --follow-context set SELinux context according to --target PID
-h, --help 显示此帮助并退出
-V, --version 输出版本信息并退出
2.1.2 mode l3
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: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST> 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: <BROADCAST,MULTICAST> 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 ms
2.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中一探究竟。
|