写在前面


  • 博文内容涉及 IPvlan 的简单认知,以及一个 Demo
  • 博文内容根据《 Kubernetes 网络权威指南:基础、原理与实践》 整理
  • 理解不足小伙伴帮忙指正

不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树


IPvlan简介

Macvlan类似,IPvlan也是从一个主机接口虚拟出多个虚拟网络接口。区别在于IPvlan所有的虚拟接口都有相同的MAC地址,而IP地址却各不相同

因为所有的 IPvlan 虚拟接口共享MAC地址,所以特别需要注意DHCP使用的场景。DHCP分配IP地址的时候一般会用MAC地址作为
机器的标识。

因此,在使用 IPvlan 的情况下,客户端动态获取IP的时候需要配置唯一的 Client ID,并且DHCP服务器也要使用该字段作为机器标识,而不是使用MAC地址。

Linux内核3.19版本才开始支持IPvlan,Docker从4.2版本起能够稳定支持IPvlan

在Docker 中,当我们创建一个IPvlan 网络并将容器连接到该网络时,每个容器都被分配一个独立的IP地址,并且可以与主网络中的其他设备进行直接通信。这使得容器可以在网络层级上与其他设备进行交互,而无需经过网络地址转换(NAT)的额外处理。

IPvlan有两种不同的模式,分别是L2L3。一个父接口只能选择其中一种模式,依附于它的所有子虚拟接口都运行在该模式下。

  • L2模式: IPvlan L2模式和Macvlan bridge模式的工作原理很相似,父接口作为交换机转发子接口的数据。同一个网络的子接口可以通过父接口转发数据,如果想发送到其他网络,则报文会通过父接口的路由转发出去。
  • L3模式: L3模式下,IPvlan 有点像路由器的功能。IPvlan在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同,即使虚拟机/容器不在同一个网络,也可以互相ping通对方,因为 IPvlan 会在中间做报文的转发工作

IPvlan Demo

这里我们在两个命名空间实现 IPvlan 通信

创建两个命名空间,然后创建两个 IPvlan 设备,分别放到两个命名空间,激活网卡

liruilonger@cloudshell:~$sudo ip netns add net1
liruilonger@cloudshell:~$sudo ip netns add net2
liruilonger@cloudshell:~$sudo ip link add ipv1 link eth0 type ipvlan mode l3
liruilonger@cloudshell:~$sudo ip link add ipv2 link eth0 type ipvlan mode l3
liruilonger@cloudshell:~$ip a
liruilonger@cloudshell:~$ sudo ip link set ipv1 netns net1
liruilonger@cloudshell:~$ sudo ip link set ipv2 netns net2
liruilonger@cloudshell:~$ sudo ip netns exec net1 ip link set ipv1 up
liruilonger@cloudshell:~$ sudo ip netns exec net2 ip link set ipv2 up

给两个命名空间的 IPvlan 设备配置不同子网的IP地址

liruilonger@cloudshell:~$ sudo ip netns exec net1 ip addr  add  10.0.1.10/24 dev ipv1
liruilonger@cloudshell:~$ sudo ip netns exec net2 ip addr  add  192.168.26.10/24 dev ipv2

同时需要在两个命名空间添加默认路由信息

liruilonger@cloudshell:~$ sudo ip netns exec net1 route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.1.0        0.0.0.0         255.255.255.0   U     0      0        0 ipv1
liruilonger@cloudshell:~$ sudo ip netns exec net1 ip route add default dev ipv1
liruilonger@cloudshell:~$ sudo ip netns exec net2 ip route add default dev ipv2

添加完路由信息之后,在其中一个命名空间做 Ping 测试

liruilonger@cloudshell:~$ sudo ip netns exec net1 ping -c 3 192.168.26.10
PING 192.168.26.10 (192.168.26.10) 56(84) bytes of data.
64 bytes from 192.168.26.10: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 192.168.26.10: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 192.168.26.10: icmp_seq=3 ttl=64 time=0.030 ms

--- 192.168.26.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2082ms
rtt min/avg/max/mdev = 0.030/0.035/0.043/0.005 ms
liruilonger@cloudshell:~$
liruilonger@cloudshell:~$ sudo ip netns exec net1 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: ipv1@if2: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:fd:87:31:4d:e0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.1.10/24 scope global ipv1
       valid_lft forever preferred_lft forever
    inet6 fe80::fafd:8700:131:4de0/64 scope link 
       valid_lft forever preferred_lft forever
liruilonger@cloudshell:~$ sudo ip netns exec net2 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: ipv2@if2: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:fd:87:31:4d:e0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.26.10/24 scope global ipv2
       valid_lft forever preferred_lft forever
    inet6 fe80::fafd:8700:231:4de0/64 scope link 
       valid_lft forever preferred_lft forever
liruilonger@cloudshell:~$

IPvlan除了能够完美解决以上问题,还允许用户基于IPvlan搭建比较复杂的网络拓扑,不再基于Macvlan的简单的二层网络,而是能够与BGP(Boader GatewayProtocol,边界网关协议)等协议扩展我们的网络边界

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃


《 Kubernetes 网络权威指南:基础、原理与实践》