OpenStack Yoga版安装笔记(24)启动一个实例(L2Population测试)
1、测试准备
1.1 测试环境
本次练习是在完成《OpenStack Yoga版安装笔记(十九)启动一个实例(Self-service networks)》之后进行的,只需要controller,compute1两个节点,已经完成Keystone、Glance、Nova、Neutron相关OpenStack服务组件的安装。
两个节点都安装了nova-compute,可以作为计算节点开启虚机。
root@osclient ~(admin/amdin)# openstack compute service list
+--------------------------------------+----------------+------------+----------+---------+-------+----------------------------+
| ID | Binary | Host | Zone | Status | State | Updated At |
+--------------------------------------+----------------+------------+----------+---------+-------+----------------------------+
| b935d869-0102-45c0-8b24-e338c5606890 | nova-scheduler | controller | internal | enabled | up | 2025-04-22T12:43:02.000000 |
| e4929b42-af08-449f-b703-c0fc36c4220b | nova-conductor | controller | internal | enabled | up | 2025-04-22T12:43:07.000000 |
| c04e53a4-fdb8-4915-9b1a-f5d195e753c4 | nova-compute | compute1 | nova | enabled | up | 2025-04-22T12:43:01.000000 |
| b3d4e71d-088a-4249-8d8f-e6d8528c698d | nova-compute | controller | nova | enabled | up | 2025-04-22T12:43:01.000000 |
+--------------------------------------+----------------+------------+----------+---------+-------+----------------------------+
root@osclient ~(admin/amdin)# openstack server show selfservice-instance
1.2 测试虚机1(instance)
目前环境中已经创建了两个network,创建了两个虚机。
root@osclient ~(myproject/myuser)# openstack network list
+--------------------------------------+-------------+--------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+-------------+--------------------------------------+
| 28d343c8-1cbb-4d3a-b69c-7d9afe5840fa | selfservice | 2825e2f9-b894-49ba-8cdb-399285223219 |
| 48f2b88e-7740-4d94-a631-69e2abadf25b | provider | 8279842e-d7c5-4ba6-a037-831e0a72a938 |
+--------------------------------------+-------------+--------------------------------------+
root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+----------------------+---------+----------------------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+----------------------+---------+----------------------------------------+--------+---------+
| e6978f67-7b21-4a53-97a4-58bca7e0c7d5 | selfservice-instance | SHUTOFF | selfservice=172.16.1.42, 203.0.113.145 | cirros | m1.nano |
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+----------------------+---------+----------------------------------------+--------+---------+
root@osclient ~(myproject/myuser)#
selfservice network已经有一台虚机selfservice-instance,运行在controller节点,开启这台虚机:
1、admin role登录进myproject,可以显示虚机运行在哪个节点上:
root@osclient ~(myproject/myuser)# source myproject-admin-openrc
root@osclient ~(myproject/admin)# openstack server show selfservice-instance
+-------------------------------------+----------------------------------------------------------+
| Field | Value |
+-------------------------------------+----------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-SRV-ATTR:host | controller |
| OS-EXT-SRV-ATTR:hypervisor_hostname | controller |
| OS-EXT-SRV-ATTR:instance_name | instance-00000005 |
| OS-EXT-STS:power_state | Shutdown |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | stopped |
| OS-SRV-USG:launched_at | 2025-04-11T00:55:20.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | selfservice=172.16.1.42, 203.0.113.145 |
| config_drive | |
| created | 2025-04-11T00:55:13Z |
| flavor | m1.nano (0) |
| hostId | f482eac1735f9b4319d1f2bf7604decf52e3866937ad1fb219a8eeaf |
| id | e6978f67-7b21-4a53-97a4-58bca7e0c7d5 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | selfservice-instance |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='default' |
| status | SHUTOFF |
| updated | 2025-04-12T08:16:58Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-------------------------------------+----------------------------------------------------------+
root@osclient ~(myproject/admin)# 2、myuser role登录进myproject,启动虚机:
root@osclient ~(myproject/admin)# source demo-openrc
root@osclient ~(myproject/myuser)# openstack server start selfservice-instance
root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+----------------------+---------+----------------------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+----------------------+---------+----------------------------------------+--------+---------+
| e6978f67-7b21-4a53-97a4-58bca7e0c7d5 | selfservice-instance | ACTIVE | selfservice=172.16.1.42, 203.0.113.145 | cirros | m1.nano |
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+----------------------+---------+----------------------------------------+--------+---------+
root@osclient ~(myproject/myuser)#
1.3 测试虚机2(instance)
计划在selfservice network启动第二个虚机,并希望运行在compute1节点上,可以使用--availability-zone选项:
root@osclient ~(myproject/myuser)# openstack server create --flavor m1.nano --image cirros \
> --nic net-id=28d343c8-1cbb-4d3a-b69c-7d9afe5840fa --security-group default \
> --key-name mykey --availability-zone nova:compute1 selfservice-instance2
Policy doesn't allow os_compute_api:servers:create:forced_host to be performed. (HTTP 403) (Request-ID: req-13b4e388-69f9-4e79-80f9-fde7d33fe0a5)
使用“myuser” role的“myuser" user登录“myproject” project,没有权限执行--availability-zone。
不使用--availability-zone,也能正常创建虚机,并运行在compute1:
root@osclient ~(myproject/myuser)# openstack server create --flavor m1.nano --image cirros --nic net-id=28d343c8-1cbb-4d3a-b69c-7d9afe5840fa --security-group default --key-name mykey selfservice-instance2
+-----------------------------+-----------------------------------------------+
| Field | Value |
+-----------------------------+-----------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | |
| OS-EXT-STS:power_state | NOSTATE |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | None |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | |
| adminPass | xHoWzwReG3P6 |
| config_drive | |
| created | 2025-04-22T13:29:24Z |
| flavor | m1.nano (0) |
| hostId | |
| id | 7b16bf01-aa2f-4e45-a4f1-16d92a03c122 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | selfservice-instance2 |
| progress | 0 |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='15dfe688-d6fc-4231-a670-7b832e08fb9d' |
| status | BUILD |
| updated | 2025-04-22T13:29:24Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-----------------------------+-----------------------------------------------+
root@osclient ~(myproject/myuser)# root@osclient ~(myproject/myuser)# source myproject-admin-openrc
root@osclient ~(myproject/admin)# openstack server show selfservice-instance2
+-------------------------------------+----------------------------------------------------------+
| Field | Value |
+-------------------------------------+----------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-SRV-ATTR:host | compute1 |
| OS-EXT-SRV-ATTR:hypervisor_hostname | compute1 |
| OS-EXT-SRV-ATTR:instance_name | instance-00000006 |
| OS-EXT-STS:power_state | Running |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | active |
| OS-SRV-USG:launched_at | 2025-04-22T13:29:02.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | selfservice=172.16.1.30 |
| config_drive | |
| created | 2025-04-22T13:29:24Z |
| flavor | m1.nano (0) |
| hostId | 892d1a79d804f6b0fbfb68938ec0df8a0abc8e3d52660529538123e4 |
| id | 7b16bf01-aa2f-4e45-a4f1-16d92a03c122 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | selfservice-instance2 |
| progress | 0 |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='default' |
| status | ACTIVE |
| updated | 2025-04-22T13:29:30Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-------------------------------------+----------------------------------------------------------+
root@osclient ~(myproject/admin)#
1.4 OpenStack网络拓扑
一个OpenStack Network在对应主机上会对应一个linux bridge。
provider、selfservice network在controller、compute1按需产生对应的linux bridge。
controller:
root@controller:~# brctl show
bridge name bridge id STP enabled interfaces
brq28d343c8-1c 8000.fa9e6d61701c no tap9c9c42d1-7ctapdef1277e-dbtapfb68b947-33vxlan-649
brq48f2b88e-77 8000.36f43ea8e0c3 no ens34tap02f3fada-b8tapa51b2fe4-04
virbr0 8000.5254007be820 yes
root@controller:~#
root@controller:~# ip netns
qrouter-782e8b74-a13c-4e8c-83dd-066f49e55ac2 (id: 2)
qdhcp-48f2b88e-7740-4d94-a631-69e2abadf25b (id: 0)
qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa (id: 1)
root@controller:~#
brq28d343c8-1c对应selfservice network
brq48f2b88e-77对应provider network
compute1:
brq28d343c8-1c 8000.2a188c6fc74a no tap2c862cb2-03vxlan-649
brq48f2b88e-77 8000.ea99122ddd99 no
virbr0 8000.525400db7049 yes
root@compute1:~#
brq28d343c8-1c对应selfservice network
brq48f2b88e-77对应provider network
OpenStack抽象网络如下图所示:
(注意是在project "myproject"下的网络拓扑)
OpenStack实体网络如下图所示:
在selfservice network创建的两个instance彼此之间通过vxlan通信,在这里VTEP采用了管理网段的地址。
1.5 通过浮动IP登录测试虚机
由于之前配置了浮动IP:
root@osclient ~(myproject/myuser)# openstack float ip list
+--------------------------------------+---------------------+------------------+--------------------------------------+--------------------------------------+----------------------------------+
| ID | Floating IP Address | Fixed IP Address | Port | Floating Network | Project |
+--------------------------------------+---------------------+------------------+--------------------------------------+--------------------------------------+----------------------------------+
| 5bb30161-2555-4456-8b06-42e6125ce1d9 | 203.0.113.145 | 172.16.1.42 | def1277e-db96-4200-a351-1c127fc0bcee | 48f2b88e-7740-4d94-a631-69e2abadf25b | f5e75a3f7cc347ad89d20dcfe70dae01 |
+--------------------------------------+---------------------+------------------+--------------------------------------+--------------------------------------+----------------------------------+
可以通过访问203.0.113.145(对应172.16.1.42),登录selfservice-instance虚机:
$ hostname
selfservice-instance
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc pfifo_fast qlen 1000link/ether fa:16:3e:84:d2:a6 brd ff:ff:ff:ff:ff:ffinet 172.16.1.42/24 brd 172.16.1.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::f816:3eff:fe84:d2a6/64 scope link valid_lft forever preferred_lft forever
$ ip route
default via 172.16.1.1 dev eth0
169.254.169.254 via 172.16.1.1 dev eth0
172.16.1.0/24 dev eth0 src 172.16.1.42
$
1.6 同网段虚机跨VXLAN通信抓包
selfservice network的selfservice-instance 能成功ping通 selfservice-instance2:
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc pfifo_fast qlen 1000link/ether fa:16:3e:84:d2:a6 brd ff:ff:ff:ff:ff:ffinet 172.16.1.42/24 brd 172.16.1.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::f816:3eff:fe84:d2a6/64 scope link valid_lft forever preferred_lft forever
$ ping -c 4 172.16.1.30
PING 172.16.1.30 (172.16.1.30): 56 data bytes
64 bytes from 172.16.1.30: seq=0 ttl=64 time=0.753 ms
64 bytes from 172.16.1.30: seq=1 ttl=64 time=1.259 ms
64 bytes from 172.16.1.30: seq=2 ttl=64 time=1.814 ms
64 bytes from 172.16.1.30: seq=3 ttl=64 time=1.059 ms--- 172.16.1.30 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.753/1.221/1.814 ms
$ 查看arp信息:
查看 /proc/net/arp 文件
ARP 缓存存储在 /proc/net/arp 文件中,可以通过 cat /proc/net/arp 命令查看其内容:
$ cat /proc/net/arp
IP address HW type Flags HW address Mask Device
172.16.1.2 0x1 0x2 fa:16:3e:be:16:3b * eth0
172.16.1.1 0x1 0x2 fa:16:3e:33:b2:f8 * eth0
172.16.1.30 0x1 0x2 fa:16:3e:f4:9e:bd * eth0
$
在vmnet8抓包,可以看到虚机之间通过VXLAN封装进行通讯,VNI=649:
2、L2Population机制
2.1 问题提出
传统的二层网络通讯,当本地终端设备(比如虚机)需要与目的设备IP地址通信时,首先查询设备自身的ARP表格,获得目的IP地址对应的目的MAC地址。如果它不知道目的MAC地址,就会发送一个ARP广播请求,查询目的IP地址对应的目的MAC地址。
交换机一侧通过MAC Learning机制,建立MAC地址表。MAC地址表(Media Access Control Address Table)是交换机(或某些网络设备)用来存储和管理网络中设备MAC地址与相应端口映射关系的表格。交换机对于BUM报文(广播、组播、未知单播报文),通常采用Flooding(泛洪)的方式进行发送。
VXLAN(Virtual Extensible LAN)通过在IP网络(Underlay网络)上叠加二层虚拟网络(Overlay网络),实现跨三层网络的二层通信。在VXLAN网络中,对于BUM优化是一个重要的需求,尤其是在处理ARP广播请求时。
通常由两种优化处理需求:
1、源端VTEP提前获知目的端设备(比如虚机)信息(VNI/IP/MAC),在MAC地址表中提前填充远端虚机MAC处于哪个VTEP之下,减少未知单播报文的泛洪。
2、源端VTEP所在的交换机开启Proxy ARP功能,需实现两个能力:1/ 能创建ARP表,在该ARP表中提前填充远端虚机IP地址-MAC信息。2/ 能截获本地ARP广播请求,根据ARP请求报文中的目的IP地址,查询建立的ARP表项,获得目的IP对应的MAC地址,直接发送ARP Reply給本地设备,减少ARP广播请求。本地终端设备(虚机)使用目的MAC建立报文,到达VTEP设备,根据MAC地址表进行报文转发。
详细解读:
这段话讨论了在虚拟网络环境中,特别是在使用隧道(如 VXLAN、GRE)技术时,广播、未知单播(unknown unicast)和组播(multicast) 数据包的处理方式,以及与这些操作相关的一些效率问题。以下是对段落中各个关键点的解读:
1. 未知单播、组播和广播的泛洪
未知单播(Unknown Unicast):指的是网络中一个目的 MAC 地址在当前网络拓扑中不被已知(即该 MAC 地址不在学习表中)。此时,虚拟交换机会将数据包广播到所有计算节点(compute nodes)以寻找目标。
组播(Multicast)和广播(Broadcast):组播是发送给一组设备的数据包,广播则是发送给网络中所有设备的数据包。广播包括像 ARP 请求、DHCP 请求等。
在这种架构下,当虚拟机发送一个未知目的地的单播、组播或广播流量时,数据包会被 泛洪 到所有其他计算节点的隧道中。这意味着,不管目标 MAC 地址是否存在,所有的计算节点都会收到这些数据包。
2. 学习 MAC 地址表
学习表(Learning Table):当数据包到达某个计算节点时,该节点会使用数据包的源 MAC 地址来更新自己的学习表。通过记录源 MAC 地址和它所属的计算节点,下一次针对该 MAC 地址的流量将不再广播,而是直接发送到正确的计算节点。
这是一种基于 MAC 地址学习 的机制,旨在避免未来的流量泛洪。通过这种学习机制,网络效率逐步提升,因为一旦某个 MAC 地址的目标已知,后续流量将直接被送往相应的节点,而不再通过广播。
3. 潜在的效率问题
这段话指出了在上述机制下可能存在的效率问题:
MAC 地址初始未知:网络中初期的 MAC 地址 是不为代理(L2 代理)所知的,因此每次发送未知单播、组播或广播流量时,都会通过隧道泛洪到所有计算节点,这会带来大量的不必要的网络流量,影响性能。
Neutron 服务 知道整个网络拓扑(包括每个端口的 MAC 地址和其所在节点),但这些信息并没有直接传递给每个 L2 代理,导致了不必要的广播流量。
ARP 请求的泛洪:网络中可能会有大量的 ARP 请求(特别是在虚拟机启动时),这些请求也是广播流量。ARP 请求用于将 IP 地址解析为 MAC 地址,但如果每次都进行广播,这会消耗大量网络带宽,尤其是在大规模网络中。是否可以 优化 ARP 请求,减少不必要的广播。
4. 关于广播的进一步思考
另外,段落提到一个问题:如果某个节点不托管任何端口(或不在某个特定网络中),那么这个节点是否应该接收该网络的广播流量?
这是一个重要的优化问题。如果一个节点没有参与某个特定的网络,它并不需要接收该网络的广播流量(例如 ARP 请求)。如果该节点仍然接收到这些广播流量,将会浪费带宽和计算资源。
这个问题表明了 广播流量的范围优化 的必要性。广播过滤机制 可以根据节点是否参与某个网络或是否托管该网络的端口来决定是否转发广播流量(不需要就不发),从而减少不必要的网络负载。
5. 总结与优化方向
MAC 地址学习表 能够在一定程度上减少流量的泛洪,但在网络初期或网络拓扑变化时,仍然存在大量广播流量。
ARP 请求的优化:目前 ARP 请求通常是广播的,可以考虑通过优化机制(例如 ARP 响应器)减少广播,提高网络效率。
广播过滤机制:通过过滤不必要的广播流量(例如,仅将广播流量发送到需要的节点),可以进一步提高网络性能,避免节点接收到不相关的广播流量。
通过这些改进,虚拟化网络可以在减少网络负载、提高性能方面得到显著优化。
2.2 解决方案
在OpenStack Neutron网络服务中,Neutron 服务器知道环境中所有活动的 MAC 地址和 IP 地址。这些信息可以用来预先填充所有隧道桥接的转发条目。这是通过 L2 population 驱动程序实现的。
详细解读:
Neutron 服务器:
在 OpenStack 中,Neutron 是负责网络管理的组件,它提供虚拟网络服务,包括创建和管理虚拟网络、路由、IP 地址分配等。Neutron 服务器即是 Neutron 服务的核心,它负责管理和协调整个 OpenStack 环境中的网络资源。所有活动的 MAC 和 IP 地址:
这句话的意思是,Neutron 服务器能够追踪和管理环境中所有活动的虚拟机(VM)以及其他网络设备的 MAC 地址 和 IP 地址。这意味着 Neutron 会维护一个全局的 IP 和 MAC 地址映射表,包括所有在网络中活动的虚拟机和设备。预填充转发条目:
在网络中,尤其是使用隧道技术(如 VXLAN、GRE 等)时,数据包需要通过不同的网络桥接(可以理解为linux bridge)进行转发。在这种情况下,每个隧道桥接(可以理解为在linux bridge中实现)需要知道如何将数据包从源端转发到目的端。预填充转发条目指的是根据已有的 IP 和 MAC 地址信息,Neutron 可以提前在隧道桥接(linux bridge)中配置好相应的转发规则或条目(可以理解为提前填充MAC地址表),以便数据包可以快速、准确地被转发到目的地。隧道桥接(Tunnel Bridges):
隧道桥接是虚拟化网络中的一种常见结构,用于支持隧道协议,如 VXLAN 或 GRE。隧道桥接通常存在于网络节点(如 Compute 节点)之间,用于在物理网络之间封装和转发数据流量。当虚拟机或容器在不同物理主机上运行时,隧道桥接就负责将它们的通信流量传输到正确的目标。L2 population 驱动程序:
L2 population 驱动程序是 Neutron 中的一项功能,旨在通过维护和传播 Layer 2(数据链路层)信息来优化虚拟网络的性能。L2 population 驱动程序使得 Neutron 能够在网络拓扑中自动维护 MAC 地址表,特别是在使用隧道桥接的环境中。它通过自动将 MAC 地址信息分发到各个节点,确保网络中的数据包能够正确地转发。简而言之,L2 population 是用于动态分发和更新 MAC 地址和 IP 地址映射的机制,帮助快速建立网络连接。关键点总结:
Neutron 服务器 知道所有活动设备的 MAC 地址 和 IP 地址,这是通过 L2 population 驱动程序实现的。
L2 population 驱动程序 通过自动分发 MAC 和 IP 映射信息,确保隧道桥接节点能够提前填充转发规则,使数据包可以快速正确地转发。
隧道桥接 用于在不同物理主机之间传输数据流,通常用于支持 VXLAN 或 GRE 隧道等技术。
通过这一机制,Neutron 提高了网络通信的效率和可靠性,减少了在网络中查找目的 MAC 地址的时间,从而加速了虚拟机和容器之间的通信。
然而,仅仅这个还不够。前面提到,每当虚拟机不知道目标 MAC 地址时,它会发送一个广播的 ARP 请求,这个请求需要被本地主机拦截并响应,以防止它在网络中被泛洪。后者是通过一个叫做 ARP 响应器(ARP Responder) 的功能来实现的,它模拟了隧道桥接中通常称为 ARP代理(ARP Proxy) 的功能。
详细解读:
虚拟机不知道目标 MAC 地址时的 ARP 请求: 当虚拟机要和其他设备(比如另一台虚拟机)通信时,它首先需要知道对方的 MAC 地址。如果虚拟机知道目标 IP 地址,但不知道对应的 MAC 地址,它会发出 ARP 请求。这是 ARP (地址解析协议) 的标准流程,作用是通过广播请求来查找目标设备的 MAC 地址。
由于 ARP 请求是广播的,这意味着它会发送到同一子网的所有设备,并且每个设备都会检查自己是否匹配目标 IP 地址。如果匹配,设备会回应其 MAC 地址。
ARP 请求的泛洪: ARP 请求是一种广播消息,这意味着请求会被发送到网络中的所有设备,这样可能会导致不必要的网络流量,尤其是在大型网络中。如果每个虚拟机或设备都对所有 ARP 请求进行广播响应,这可能会严重影响网络的效率。
因此,为了避免这种 泛洪(flooding)现象,需要有一个机制来拦截 ARP 请求并在合适的时机进行响应。
ARP 响应器(ARP Responder): 这段话提到的 ARP 响应器 是一种用于拦截 ARP 请求并主动响应的机制。它通过模拟 ARP 代理 的功能来完成这一操作。在虚拟化网络中,特别是在使用隧道技术(如 VXLAN 或 GRE)时,隧道桥接中会使用 ARP 响应器来避免 ARP 请求的泛洪。
ARP 代理(ARP Proxy):在传统网络中,ARP 代理是一个功能,它允许网络设备代替目标设备响应 ARP 请求,从而避免不必要的广播。ARP 响应器正是模拟了这种代理功能,使得虚拟机或网络中的其他设备能够通过本地设备(如隧道桥接节点)直接获取 MAC 地址,从而提高网络效率。
隧道桥接中的 ARP 响应器:在使用隧道技术时(如 VXLAN),网络中的 ARP 请求会通过隧道转发。为了避免这些请求在每个节点之间传播,隧道桥接中的 ARP 响应器会拦截这些 ARP 请求并直接做出响应,从而避免了 ARP 请求的广播泛洪。
模拟 ARP 代理的功能: 隧道桥接中的 ARP 响应器并不让每个节点都响应 ARP 请求,而是 集中响应,通过在网络中选择一个本地的设备(如隧道桥接节点或物理主机)来直接回应 ARP 请求。这样一来,网络中的其他设备就不会被无意义的广播请求淹没,减少了网络负担。
这个过程在网络上表现为:当虚拟机发送 ARP 请求时,并不是所有虚拟机和设备都响应,而是 本地的代理设备(如隧道桥接设备)会自动响应 ARP 请求。
关键点总结:
ARP 请求的泛洪问题:当虚拟机不知道目标 MAC 地址时,它会发送广播的 ARP 请求,这种请求会在网络中泛洪,导致不必要的流量。
ARP 响应器的作用:通过引入 ARP 响应器功能,虚拟化网络能够避免 ARP 请求的泛洪。ARP 响应器类似于 ARP 代理,能够拦截 ARP 请求并主动响应,从而减少网络中的广播流量。
隧道桥接中的 ARP 响应器:在隧道技术(如 VXLAN 或 GRE)环境中,ARP 响应器会在隧道桥接节点上模拟 ARP 代理功能,防止 ARP 请求在网络中泛洪。
通过这些机制,OpenStack 和其他虚拟化平台能够提高网络性能,减少不必要的流量,确保虚拟机和设备之间的快速、高效通信。
2.3 实现机制
当使用 ML2 插件与隧道时,如果一个新的端口被启用,ML2 会发送一个 update_port_postcommit
通知,该通知会被 l2pop
机制驱动程序接收和处理。然后,l2pop
会收集端口的 IP 和 MAC 地址,以及该端口所在的宿主机信息;接着,l2pop
会向所有二层代理发送一个 RPC 通知(通过MQ进行通讯)。代理(比如linux bridge agent)使用这个通知来解决上述详细说明二层BUM泛洪效率问题。
详细解读:
ML2 插件与隧道(Tunnels):
ML2 插件:在 OpenStack 中,ML2 是一个多租户网络插件,它允许用户使用不同的网络后端(如 VXLAN、GRE、VLAN 等)来创建虚拟网络。ML2 插件本身是一个框架,它支持多种网络类型,并能与各种网络驱动程序(mechanism drivers)进行交互。ML2 插件是 OpenStack Neutron 网络的一部分,负责管理和协调虚拟机(VM)、子网、端口等网络资源。
隧道:指的是虚拟网络中通过物理网络传输封装数据包的技术(如 VXLAN 或 GRE)。这些隧道通常用于跨物理机或数据中心的网络通信。
端口启用时的
update_port_postcommit
通知:
当一个新的端口(port)被启用时(openstack port list查看port, instance启动时,相应port启用),ML2 插件会通过发送一个
update_port_postcommit
通知,表示一个新的网络端口已经成功创建并且可以开始使用。这个通知是一个 Neutron 事件,它会被发送到 l2pop 机制驱动程序,这是一个处理 Layer 2 相关功能的模块。
l2pop 机制驱动程序:
l2pop
(Layer 2 Population)机制驱动程序是一个 Neutron 组件,主要负责管理和分发 Layer 2 信息(即 MAC 地址、IP 地址映射等)。特别是在使用隧道的网络环境中,l2pop 通过将网络信息广播给各个网络节点来确保网络拓扑的正确性。
l2pop
会处理一些任务,比如将 虚拟机的 IP 和 MAC 地址 信息同步到所有参与该虚拟网络的节点上,确保网络中其他设备能快速找到目标设备。收集端口的 IP 和 MAC 地址:
当
l2pop
接收到update_port_postcommit
通知时,它会 收集端口的 IP 地址、MAC 地址 和该端口所在的 宿主机信息(也就是端口对应的物理主机或虚拟机所在的主机)。这个过程是为了确保 Neutron 服务器和网络代理(如 L2 代理)了解网络中各个设备的具体位置及其属性,确保正确的网络通信。
向所有 Layer 2 代理发送 RPC 通知:
一旦
l2pop
收集到这些信息,它会通过 RPC(远程过程调用)通知 将这些数据发送给所有的 Layer 2 代理(比如linux bridge agent)。这些代理通常是 OpenStack 中的网络代理(如 OVS 或 Linux bridge),它们负责执行虚拟网络的二层功能,如 MAC 地址学习、转发等。代理使用通知来解决三个问题:
代理会使用 RPC 通知 来解决特定的 三大问题,这些问题通常是:
MAC 地址初始未知:
在虚拟网络环境中,代理(L2 代理)初期并不知道所有的 MAC 地址。通过接收 Neutron 发送的通知,代理能够获得网络中每个端口的 MAC 地址、IP 地址以及所在的宿主主机信息。这样一来,代理就可以学习到这些新的 MAC 地址,并将其添加到自己的学习表中,从而避免未来的流量泛洪。
ARP 请求的泛洪问题:
网络中大量的 ARP 请求是广播流量,尤其是在虚拟机刚启动时。通过这些通知,代理能够知道需要为某个 IP 地址响应 ARP 请求,而不是将其广播到所有节点。这样,可以通过 ARP 响应器 的机制,减少 ARP 请求的泛洪。
广播流量的无效传输问题
代理通过接收到通知,了解到哪些节点不托管某个特定网络的端口(openstack的network/port),进而就不会将该网络的广播流量发送到这些节点,从而减少了无效的广播流量。
通过这个过程,
l2pop
确保了网络中每个节点都可以正确地获取到设备的 MAC 地址和 IP 地址的映射,从而实现高效的二层数据转发。关键点总结:
ML2 插件 通过
update_port_postcommit
通知来告知网络端口的创建,并将该信息传递给l2pop
驱动程序。l2pop 驱动程序 负责收集端口的 IP、MAC 地址 和 宿主机信息,并将这些信息发送给所有 Layer 2 代理。
RPC 通知 是用来同步和解决虚拟网络中的 MAC 地址分发、IP 地址与 MAC 映射、以及网络拓扑同步 问题。
通过这种机制,OpenStack 能够在使用隧道的网络环境中实现高效、灵活的二层网络管理。
3、L2Population测试
3.1 测试场景
归纳三种配置测试场景:
Lab | linuxbridge_agent.ini l2population设置 | linuxbridge_agent.ini arp_responder设置 | 预期结果 (主要指穿行vxlan隧道的流量) |
lab1 | l2_population = false | arp_responder = false | a、MAC Learning b、BUM flooding |
Lab2 | l2_population = true | arp_responder = false | a、MAC预填充 b、BUM会减少,因为l2population机制能提前学习到mac |
Lab3 | l2_population = true | arp_responder = true | a、MAC预填充 b、BUM会减少,因为l2population机制能提前学习到mac c、ARP请求会减少,因为linux bridge agent arp responder会代答 |
3.2 测试拓扑
(注:图中虚机信息为Lab1中重新创建的虚机信息)
3.3 Lab1
3.3.1 配置文件
1、controller:
ml2_conf.ini未作修改。
修改linuxbridge_agent.ini:
root@controller:~# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[vxlan]
enable_vxlan = true
local_ip = 10.0.20.11
l2_population = false
arp_responder = falseroot@controller:~# service neutron-linuxbridge-agent restart
compute1:
root@compute1:~# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[vxlan]
enable_vxlan = true
local_ip = 10.0.20.12
l2_population = false
arp_responder = falseroot@compute1:~# service neutron-linuxbridge-agent restart
3.3.2 重新创建instance
删除两个instance:
root@osclient ~(myproject/myuser)# openstack server delete selfservice-instance
root@osclient ~(myproject/myuser)# openstack server delete selfservice-instance2
重新创建instance:
root@osclient ~(myproject/myuser)# openstack server create --flavor m1.nano --image cirros \
> --nic net-id=28d343c8-1cbb-4d3a-b69c-7d9afe5840fa --security-group default \
> --key-name mykey selfservice-instance
+-----------------------------+-----------------------------------------------+
| Field | Value |
+-----------------------------+-----------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | |
| OS-EXT-STS:power_state | NOSTATE |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | None |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | |
| adminPass | sQe5roCnb5mT |
| config_drive | |
| created | 2025-04-26T04:58:42Z |
| flavor | m1.nano (0) |
| hostId | |
| id | 4847a65a-d45f-4adc-971e-f1d905c2c535 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | selfservice-instance |
| progress | 0 |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='15dfe688-d6fc-4231-a670-7b832e08fb9d' |
| status | BUILD |
| updated | 2025-04-26T04:58:42Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-----------------------------+-----------------------------------------------+root@osclient ~(myproject/myuser)# openstack server create --flavor m1.nano --image cirros --nic net-id=28d343c8-1cbb-4d3a-b69c-7d9afe5840fa --security-group default --key-name mykey selfservice-instance2
+-----------------------------+-----------------------------------------------+
| Field | Value |
+-----------------------------+-----------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | |
| OS-EXT-STS:power_state | NOSTATE |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | None |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | |
| adminPass | 7fivyvDe7gS9 |
| config_drive | |
| created | 2025-04-26T05:00:06Z |
| flavor | m1.nano (0) |
| hostId | |
| id | 12faa86b-252a-4400-94d8-80dd4585b9d3 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | selfservice-instance2 |
| progress | 0 |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='15dfe688-d6fc-4231-a670-7b832e08fb9d' |
| status | BUILD |
| updated | 2025-04-26T05:00:06Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-----------------------------+-----------------------------------------------+root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+-----------------------+---------+--------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-----------------------+---------+--------------------------+--------+---------+
| 12faa86b-252a-4400-94d8-80dd4585b9d3 | selfservice-instance2 | ACTIVE | selfservice=172.16.1.152 | cirros | m1.nano |
| 4847a65a-d45f-4adc-971e-f1d905c2c535 | selfservice-instance | ACTIVE | selfservice=172.16.1.202 | cirros | m1.nano |
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+-----------------------+---------+--------------------------+--------+---------+
root@osclient ~(myproject/myuser)#
root@osclient ~(myproject/myuser)# openstack port list
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------+--------+
| ID | Name | MAC Address | Fixed IP Addresses | Status |
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------+--------+
| 2d863922-bc61-4041-a13e-258f629719b2 | | fa:16:3e:60:78:cd | ip_address='203.0.113.125', subnet_id='8279842e-d7c5-4ba6-a037-831e0a72a938' | ACTIVE |
| 446c3b7e-12fd-4a89-a65b-22047579ae3b | | fa:16:3e:bd:6f:ab | ip_address='172.16.1.152', subnet_id='2825e2f9-b894-49ba-8cdb-399285223219' | ACTIVE |
| 9c9c42d1-7c00-4996-88e8-2b19f18aeef7 | | fa:16:3e:be:16:3b | ip_address='172.16.1.2', subnet_id='2825e2f9-b894-49ba-8cdb-399285223219' | ACTIVE |
| be47d634-9f19-45ad-9c8a-0aecd9cd34ce | | fa:16:3e:11:6a:bc | ip_address='172.16.1.202', subnet_id='2825e2f9-b894-49ba-8cdb-399285223219' | ACTIVE |
| fb68b947-3324-441a-a58c-6a4a87f01517 | | fa:16:3e:33:b2:f8 | ip_address='172.16.1.1', subnet_id='2825e2f9-b894-49ba-8cdb-399285223219' | ACTIVE |
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------+--------+
root@osclient ~(myproject/myuser)#
新创建两个instance,并已经分配全新的IP地址和MAC地址。
3.3.3 查看MAC地址表
在 Linux 网络配置中,Bridge FDB(Bridge Forwarding Database)是用于存储 MAC 地址与其对应的端口信息的数据库。它类似于传统交换机中的 MAC 地址表,用于管理桥接设备中的流量转发。
使用 bridge fdb
命令,可以查看、修改和管理桥接设备的转发表信息。
1、controller:
root@controller:~# bridge fdb | grep vxlan
92:33:57:7c:56:2c dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
92:33:57:7c:56:2c dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 224.0.0.1 via ens33 self permanent
2、compute1:
root@compute1:~# bridge fdb | grep vxlan
62:39:c0:ab:4b:e6 dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
62:39:c0:ab:4b:e6 dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 224.0.0.1 via ens32 self permanent
3、结论:
目前每个VTEP没有远端的任何信息。
3.3.4 查看arp表
1、controller:
root@controller:~# arp -n
Address HWtype HWaddress Flags Mask Iface
10.0.20.2 ether 00:50:56:f2:d2:0b C ens33
10.0.20.100 ether 00:0c:29:ff:20:81 C ens33
10.0.20.12 ether 00:0c:29:51:16:68 C ens33
10.0.20.1 ether 00:50:56:c0:00:08 C ens33
root@controller:~#
2、compute1:
root@compute1:~# arp -n
Address HWtype HWaddress Flags Mask Iface
10.0.20.11 ether 00:0c:29:a8:e0:3c C ens32
10.0.20.1 ether 00:50:56:c0:00:08 C ens32
10.0.20.13 (incomplete) ens32
root@compute1:~#
3、结论:
两个计算节点(controller、compute1)都没有虚机arp信息。
3.3.5 同网段跨节点ping
1、为简单起见,从controller上同网络的qdhcp ping compute1的instance,同时抓包:
1、确保本地没有172.16.1.152相关arp信息,如果有则删除:
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa arp -a
? (172.16.1.152) at fa:16:3e:bd:6f:ab [ether] on ns-9c9c42d1-7c
? (172.16.1.202) at fa:16:3e:11:6a:bc [ether] on ns-9c9c42d1-7c
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa arp -d 172.16.1.152
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa arp -a
? (172.16.1.202) at fa:16:3e:11:6a:bc [ether] on ns-9c9c42d1-7c2、ping 172.16.1.152
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa ping 172.16.1.152
PING 172.16.1.152 (172.16.1.152) 56(84) bytes of data.
64 bytes from 172.16.1.152: icmp_seq=1 ttl=64 time=3.09 ms
64 bytes from 172.16.1.152: icmp_seq=2 ttl=64 time=0.759 ms
64 bytes from 172.16.1.152: icmp_seq=3 ttl=64 time=0.753 ms
2、Wireshark抓包:
649 是一个 VXLAN VNI,在这种情况下用于隔离 VXLAN 网络中的流量。
图中的数据包包括 ARP 请求/响应 和 ICMP 请求/回复,这表明 VXLAN 隧道中正在执行 IP 地址解析 和 Ping测试。
3、查看controller和compute1的bridge fdb表格:
controller:
root@controller:~# bridge fdb | grep vxlan
fa:16:3e:bd:6f:ab dev vxlan-649 master brq28d343c8-1c
92:33:57:7c:56:2c dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
92:33:57:7c:56:2c dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 224.0.0.1 via ens33 self permanent
fa:16:3e:bd:6f:ab dev vxlan-649 dst 10.0.20.12 self
MAC 学习:在 VXLAN 网络中,当你发送流量时,VXLAN 隧道会学习到接收到的数据包的源 MAC 地址。在这个条目中,系统通过 VXLAN 接口
vxlan-649
学到了目标 MAC 地址fa:16:3e:bd:6f:ab,即selfservice-instance2的mac地址。
动态条目是通过网络交换机或桥接设备(如
vxlan-649
)学习到的 MAC 地址。通过交换机或虚拟交换机(例如 Open vSwitch 或 Linux bridge),设备会观察并学习源 MAC 地址,并将这些信息存储在 FDB 中。动态条目在 一段时间后会过期,这个超时期限是由内核中的桥接模块设置的,通常是 300秒(5分钟)。如果在过期之前没有收到该 MAC 地址的新的数据包,条目就会被删除。
compute1:
root@compute1:~# bridge fdb show dev vxlan-649
fa:16:3e:be:16:3b master brq28d343c8-1c
fa:16:3e:33:b2:f8 master brq28d343c8-1c
62:39:c0:ab:4b:e6 vlan 1 master brq28d343c8-1c permanent
62:39:c0:ab:4b:e6 master brq28d343c8-1c permanent
00:00:00:00:00:00 dst 224.0.0.1 via ens32 self permanent
fa:16:3e:be:16:3b dst 10.0.20.11 self
fa:16:3e:33:b2:f8 dst 10.0.20.11 self
root@compute1:~#
MAC 学习:类似于前一个例子,该条目指示通过某个 VXLAN 隧道接口(例如
vxlan-649
)学习到了一个 MAC 地址(fa:16:3e:33:b2:f8
),即qdhcp的mac地址。这通常发生在网络中发送数据包时,VXLAN 接口接收到该设备的流量并记录下源 MAC 地址。
3.3.6 Lab1小结
1、MAC地址表(bridge fdb)为远端虚机MAC地址为动态MAC地址学习获得,过一定时间如果没有更新该条目会被删除。
2、ARP广播请求会传过VXLAN隧道。
3.4 Lab2
3.4.1 配置文件
1、controller:
ml2_conf.ini未作修改。
修改linuxbridge_agent.ini:
root@controller:~# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[vxlan]
enable_vxlan = true
local_ip = 10.0.20.11
l2_population = true
arp_responder = falseroot@controller:~# service neutron-linuxbridge-agent restart
compute1:
root@compute1:~# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[vxlan]
enable_vxlan = true
local_ip = 10.0.20.12
l2_population = true
arp_responder = falseroot@compute1:~# service neutron-linuxbridge-agent restart
3.4.2 查看MAC地址表
1、controller:
root@controller:~# bridge fdb | grep vxlan
92:33:57:7c:56:2c dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
92:33:57:7c:56:2c dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 224.0.0.1 via ens33 self permanent
00:00:00:00:00:00 dev vxlan-649 dst 10.0.20.12 self permanent
fa:16:3e:bd:6f:ab dev vxlan-649 dst 10.0.20.12 self permanent
root@controller:~#
fa:16:3e:bd:6f:ab dev vxlan-649 dst 10.0.20.12 self permanent
该条目是通过 L2 Population 添加的,那么它是由 Neutron 的 L2 Population 驱动程序自动管理的,而不是通过手动配置。L2 Population 是 Neutron 中用于 VXLAN 网络的一个特性,旨在帮助不同计算节点之间同步 MAC 地址信息,从而避免不必要的 ARP 请求广播。
- 当启用 L2 Population 时,Neutron 会在每个计算节点上维护一份 VXLAN 网络的 MAC 地址表。当新的 MAC 地址被学习到时,Neutron 会使用 RPC 通知 将其广播到所有其他网络代理和计算节点。
- 在这种情况下,L2 Population 会将 MAC 地址
fa:16:3e:bd:6f:ab
和目标 IP 地址10.0.20.12
相关联,并将其作为静态条目添加到所有计算节点的 FDB 中,以便在未来的数据包转发中使用。
2、compute1:
root@compute1:~# bridge fdb show dev vxlan-649
62:39:c0:ab:4b:e6 vlan 1 master brq28d343c8-1c permanent
62:39:c0:ab:4b:e6 master brq28d343c8-1c permanent
00:00:00:00:00:00 dst 224.0.0.1 via ens32 self permanent
00:00:00:00:00:00 dst 10.0.20.11 self permanent
fa:16:3e:be:16:3b dst 10.0.20.11 self permanent --> 本网络的qdhcp
fa:16:3e:11:6a:bc dst 10.0.20.11 self permanent --> selfservice-instance虚机
fa:16:3e:33:b2:f8 dst 10.0.20.11 self permanent --> qrouter连接本网络的端口
root@compute1:~#
3.4.3 查看arp表
root@controller:~# arp -n
Address HWtype HWaddress Flags Mask Iface
10.0.20.2 ether 00:50:56:f2:d2:0b C ens33
10.0.20.100 ether 00:0c:29:ff:20:81 C ens33
10.0.20.1 ether 00:50:56:c0:00:08 C ens33
10.0.20.12 ether 00:0c:29:51:16:68 C ens33
root@controller:~# root@compute1:~# arp -n
Address HWtype HWaddress Flags Mask Iface
10.0.20.13 (incomplete) ens32
10.0.20.1 ether 00:50:56:c0:00:08 C ens32
10.0.20.11 ether 00:0c:29:a8:e0:3c C ens32
root@compute1:~#
结论:
两个计算节点(controller、compute1)都没有虚机arp信息。
3.4.4 L2 Population通知消息
抓包方式:启动controller上的selfservice-instance,在vmnet8上抓包(使用amqp.type == 3过滤),查看L2Population通知消息(通知compute1 linuxbridge-agent):
Frame 469: 1336 bytes on wire (10688 bits), 1336 bytes captured (10688 bits) on interface \Device\NPF_{3CF2B347-CE40-406F-B67A-13F210B29B37}, id 0
Ethernet II, Src: 00:0c:29:a8:e0:3c, Dst: 00:0c:29:51:16:68
Internet Protocol Version 4, Src: 10.0.20.11, Dst: 10.0.20.12
Transmission Control Protocol, Src Port: 5672, Dst Port: 46552, Seq: 1287, Ack: 30, Len: 1270
Advanced Message Queuing ProtocolType: Method (1)Channel: 1Length: 60Class: Basic (60)Method: Deliver (60)ArgumentsConsumer-Tag: 3Delivery-Tag: 6.... ...0 = Redelivered: FalseExchange: q-agent-notifier-l2population-update_fanoutRouting-Key:
Advanced Message Queuing ProtocolType: Content header (2)Channel: 1Length: 43Class ID: Basic (60)Weight: 0Body size: 1143Property flags: 0xf800PropertiesContent-Type: application/jsonContent-Encoding: utf-8HeadersDelivery-Mode: 2Priority: 0
Advanced Message Queuing ProtocolType: Content body (3)Channel: 1Length: 1143Payload […]: 7b226f736c6f2e76657273696f6e223a2022322e30222c20226f736c6f2e6d657373616765223a20227b5c226d6574686f645c223a205c226164645f6664625f656e74726965735c222c205c22617267735c223a207b5c226664625f656e74726965735c223a207b5c22323864333433JavaScript Object Notation: application/jsonJSON raw form:{"oslo.version": "2.0",[…]"oslo.message": "{\"method\": \"add_fdb_entries\", \"args\": {\"fdb_entries\": {\"28d343c8-1cbb-4d3a-b69c-7d9afe5840fa\": {\"segment_id\": 649, \"network_type\": \"vxlan\", \"ports\": {\"10.0.20.11\": [[\"fa:16:3e:11:6a:bc\", \"172.1}ObjectMember: oslo.version[Path with value: /oslo.version:2.0][Member with value: oslo.version:2.0]String value: 2.0Key: oslo.version[Path: /oslo.version]Member: oslo.message[Path with value […]: /oslo.message:{\"method\": \"add_fdb_entries\", \"args\": {\"fdb_entries\": {\"28d343c8-1cbb-4d3a-b69c-7d9afe5840fa\": {\"segment_id\": 649, \"network_type\": \"vxlan\", \"ports\": {\"10.0.20.11\": [[\"fa:16:3e:11:6a][Member with value […]: oslo.message:{\"method\": \"add_fdb_entries\", \"args\": {\"fdb_entries\": {\"28d343c8-1cbb-4d3a-b69c-7d9afe5840fa\": {\"segment_id\": 649, \"network_type\": \"vxlan\", \"ports\": {\"10.0.20.11\": [[\"fa:16:3e:11:6]String value […]: {\"method\": \"add_fdb_entries\", \"args\": {\"fdb_entries\": {\"28d343c8-1cbb-4d3a-b69c-7d9afe5840fa\": {\"segment_id\": 649, \"network_type\": \"vxlan\", \"ports\": {\"10.0.20.11\": [[\"fa:16:3e:11:6a:bc\", \"172.16.1Key: oslo.message[Path: /oslo.message]
根据抓包数据,这是 L2 Population 机制通过 AMQP(Advanced Message Queuing Protocol)发送的通知消息。这个消息由 ML2 插件发给 LinuxBridgeAgent,通知其添加或更新 FDB(Forwarding Database) 条目,以便正确处理 VXLAN 网络中的流量。下面是对这条消息的详细解读:
数据包解析
AMQP 消息结构:
消息通过 AMQP 协议进行传输,并且消息类型为 Method。
Channel: 1
:这表示消息发送的通道是 1,AMQP 协议中每个消息会有一个通道来处理不同的消息流。Method:
Deliver (60)
表示这个消息是一个 AMQP 方法类型,指示消息的传送。消息内容:
该消息的 payload 部分包含了一个 JSON 格式的数据,具体如下:
{ "oslo.version": "2.0", "oslo.message": "{\"method\": \"add_fdb_entries\", \"args\": {\"fdb_entries\": {\"28d343c8-1cbb-4d3a-b69c-7d9afe5840fa\": {\"segment_id\": 649, \"network_type\": \"vxlan\", \"ports\": {\"10.0.20.11\": [[\"fa:16:3e:11:6a:bc\", \"172.16.1.202\"]]}}}}" }
oslo.version
:"2.0"
表示消息使用的是 OSLO(OpenStack Libraries) 版本 2.0。
oslo.message
: 这是核心的通知内容,包含了实际的操作和参数。
"method": "add_fdb_entries"
:这个字段表明 ML2 插件要求 LinuxBridgeAgent 执行的操作是add_fdb_entries
,即向桥接设备的 FDB 中添加条目。
"args": { ... }
:参数部分包含了要添加的 FDB 条目。
"fdb_entries"
:这是一个映射,表示要添加的 FDB 条目。具体来说,条目包含了以下信息:
28d343c8-1cbb-4d3a-b69c-7d9afe5840fa
:这是某个网络的标识符(可能是某个虚拟机或网络接口的唯一标识符)。
segment_id: 649
:这表示该 FDB 条目属于 VXLAN 网络,VNI(虚拟网络标识符)为 649,即该条目属于 VXLAN 网络。
network_type: "vxlan"
:表示该条目是针对 VXLAN 网络的。**
ports
: {"10.0.20.11": [[“fa:16:3e:11:6a:bc”, “172.16.1.202”]]}**:这是一个端口映射,表示 IP 地址
10.0.20.11和 **MAC 地址**
fa:16:3e:11:6a:bc在 VXLAN 网络中,目标设备的 IP 是
172.16.1.202`。具体含义:
添加 FDB 条目:
add_fdb_entries
方法指示 LinuxBridgeAgent 向桥接设备的 FDB 表中添加条目。此条目表明,当接收到10.0.20.11
的流量时,数据包应该被转发到 MAC 地址fa:16:3e:11:6a:bc
,该条目和 VNI 649 的 VXLAN 网络相关联。
segment_id
:是 VXLAN 网络的标识符(VNI),在这个例子中是649
,表示该条目属于 VNI 为 649 的 VXLAN 网络。
network_type: "vxlan"
:说明该条目属于 VXLAN 网络类型。端口信息:
ports: {"10.0.20.11": [[“fa:16:3e:11:6a:bc”, “172.16.1.202”]]}
这个部分表示 IP 地址10.0.20.11
和 MAC 地址fa:16:3e:11:6a:bc
的映射关系,同时指出 目标 IP 为172.16.1.202
。这是通过 VXLAN 隧道传输的设备信息。L2 Population 的作用:
L2 Population 机制通过将 MAC 地址 和 IP 地址 映射(即 FDB 条目)同步到所有的计算节点,以便在 VXLAN 网络中减少 ARP 请求的泛洪。
当一个新的设备连接到网络并发送流量时,L2 Population 会将它的 MAC 地址同步到其他节点的桥接设备中,这样每个计算节点都能知道如何路由数据包,避免重复的 ARP 请求。
总结:
该数据包通过 AMQP 协议,作为 L2 Population 通知,指示 LinuxBridgeAgent 向 FDB 表中添加一个新的条目。
VNI 649 表示该条目与 VXLAN 网络相关,具体涉及 IP 地址
10.0.20.11(VTEP地址)
和 MAC 地址fa:16:3e:11:6a:bc(意思是这个mac地址在这个VTEP下面)
。该条目帮助实现 L2 Population 机制,从而在 VXLAN 网络中减少 ARP 请求,确保数据包能够正确路由。
3.4.5 同网段跨节点ping
1、从controller的qdhcp ping compute1的selfservice-instance2,
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa arp -d 172.16.1.152
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa ping -c 4 172.16.1.152
PING 172.16.1.152 (172.16.1.152) 56(84) bytes of data.
64 bytes from 172.16.1.152: icmp_seq=1 ttl=64 time=1.70 ms
64 bytes from 172.16.1.152: icmp_seq=2 ttl=64 time=1.05 ms
64 bytes from 172.16.1.152: icmp_seq=3 ttl=64 time=0.855 ms
64 bytes from 172.16.1.152: icmp_seq=4 ttl=64 time=0.711 ms--- 172.16.1.152 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 0.711/1.078/1.695/0.376 ms
root@controller:~#
2、wireshark抓包(vmnet8抓包):
和Lab1情况一样,ARP广播请求穿过vxlan隧道。
3、查看controller和compute1的bridge fdb表格:
controller:
root@controller:~# bridge fdb | grep vxlan
92:33:57:7c:56:2c dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
92:33:57:7c:56:2c dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 10.0.20.12 self permanent
fa:16:3e:bd:6f:ab dev vxlan-649 dst 10.0.20.12 self permanent
root@controller:~#
compute1:
root@compute1:~# bridge fdb show dev vxlan-649
62:39:c0:ab:4b:e6 vlan 1 master brq28d343c8-1c permanent
62:39:c0:ab:4b:e6 master brq28d343c8-1c permanent
00:00:00:00:00:00 dst 10.0.20.11 self permanent
fa:16:3e:be:16:3b dst 10.0.20.11 self permanent
fa:16:3e:11:6a:bc dst 10.0.20.11 self permanent
fa:16:3e:33:b2:f8 dst 10.0.20.11 self permanent
root@compute1:~#
bridge fdb表格ping前后一致,虚机mac地址通过l2population机制学习获得。
3.4.6 Lab2小结
1、MAC地址表(bridge fdb)通过l2population预先获得。
2、ARP广播请求会传过VXLAN隧道。
3.5 Lab3
3.5.1 配置文件
1、controller:
ml2_conf.ini未作修改。
修改linuxbridge_agent.ini:
root@controller:~# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[vxlan]
enable_vxlan = true
local_ip = 10.0.20.11
l2_population = true
arp_responder = trueroot@controller:~# service neutron-linuxbridge-agent restart
compute1:
root@compute1:~# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[vxlan]
enable_vxlan = true
local_ip = 10.0.20.12
l2_population = true
arp_responder = trueroot@compute1:~# service neutron-linuxbridge-agent restart
3.5.2 查看MAC地址表
1、controller:
root@controller:~# bridge fdb | grep vxlan
fa:16:3e:bd:6f:ab dev vxlan-649 master brq28d343c8-1c
92:33:57:7c:56:2c dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
92:33:57:7c:56:2c dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 10.0.20.12 self permanent
fa:16:3e:bd:6f:ab dev vxlan-649 dst 10.0.20.12 self permanent
root@controller:~#
2、compute1:
root@compute1:~# bridge fdb | grep vxlan
fa:16:3e:33:b2:f8 dev vxlan-649 master brq28d343c8-1c
fa:16:3e:be:16:3b dev vxlan-649 master brq28d343c8-1c
fa:16:3e:11:6a:bc dev vxlan-649 master brq28d343c8-1c
62:39:c0:ab:4b:e6 dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
62:39:c0:ab:4b:e6 dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 10.0.20.11 self permanent
fa:16:3e:be:16:3b dev vxlan-649 dst 10.0.20.11 self permanent
fa:16:3e:11:6a:bc dev vxlan-649 dst 10.0.20.11 self permanent
fa:16:3e:33:b2:f8 dev vxlan-649 dst 10.0.20.11 self permanent
可以看到,通过l2population机制,已经预填充了mac地址表。
3.5.3 查看arp表
1、controller:
root@controller:~# arp -n
Address HWtype HWaddress Flags Mask Iface
172.16.1.152 ether fa:16:3e:bd:6f:ab CM vxlan-649
10.0.20.12 ether 00:0c:29:51:16:68 C ens33
10.0.20.1 ether 00:50:56:c0:00:08 C ens33
10.0.20.2 ether 00:50:56:f2:d2:0b C ens33
10.0.20.100 ether 00:0c:29:ff:20:81 C ens33
root@controller:~#
- 172.16.1.152 ether fa:16:3e:bd:6f:ab CM vxlan-649
Flags: CM
:
C
表示 Complete(已完成),即表示该条目是一个有效的、已完成的 ARP 映射。
M
表示 Manual(手动添加),说明该 ARP 条目可能是手动添加的(也可以是由系统自动学习得到的)。
Iface: vxlan-649
:
这表示该 ARP 条目关联的接口是
vxlan-649
。
vxlan-649
是一个 VXLAN 接口,表示该 MAC 地址和 IP 地址的映射是通过 VXLAN 隧道 学到的。这意味着目标设备的 IP 地址172.16.1.152
位于通过 VXLAN 网络连接的设备上。总结:
该条目表示 IP 地址
172.16.1.152
对应的 MAC 地址 是fa:16:3e:bd:6f:ab
,并且该 MAC 地址是在 VXLAN 隧道接口 (vxlan-649
) 上学到的。Flags: CM 表示这个条目已经完全建立并且是有效的。
该 ARP 条目提供了从 IP 地址到 MAC 地址的映射,确保网络中的流量能够正确地通过 VXLAN 隧道转发。
这条 ARP 表项表示通过 VXLAN 隧道学到的 IP 地址和 MAC 地址映射,可以用于高效的网络流量转发,避免 ARP 请求泛洪。
2、compute1:
root@compute1:~# arp -n
Address HWtype HWaddress Flags Mask Iface
10.0.20.11 ether 00:0c:29:a8:e0:3c C ens32
172.16.1.2 ether fa:16:3e:be:16:3b CM vxlan-649
172.16.1.1 ether fa:16:3e:33:b2:f8 CM vxlan-649
172.16.1.202 ether fa:16:3e:11:6a:bc CM vxlan-649
10.0.20.1 ether 00:50:56:c0:00:08 C ens32
root@compute1:~#
有3个地址(分别是controller上的qrouter、qdhcp、selfservice-instance)是通过l2population机制填充的。
3.5.4 同网段跨节点ping
1、从controller的qdhcp ping compute1的selfservice-instance2,
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa arp -d 172.16.1.152
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa arp -a
? (172.16.1.202) at fa:16:3e:11:6a:bc [ether] on ns-9c9c42d1-7c
root@controller:~# ip netns exec qdhcp-28d343c8-1cbb-4d3a-b69c-7d9afe5840fa ping 172.16.1.152
PING 172.16.1.152 (172.16.1.152) 56(84) bytes of data.
64 bytes from 172.16.1.152: icmp_seq=1 ttl=64 time=2.05 ms
64 bytes from 172.16.1.152: icmp_seq=2 ttl=64 time=0.622 ms
64 bytes from 172.16.1.152: icmp_seq=3 ttl=64 time=0.690 ms
^C
--- 172.16.1.152 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2034ms
rtt min/avg/max/mdev = 0.622/1.119/2.045/0.655 ms
root@controller:~#
2、controller内部抓包:
对qdhcp连接的tap端口抓包:
具有看ARP reply格式,完全模拟真实的地址回复:
Frame 2: 42 bytes on wire (336 bits), 42 bytes captured (336 bits) on interface tap9c9c42d1-7c, id 0
Ethernet II, Src: fa:16:3e:bd:6f:ab (fa:16:3e:bd:6f:ab), Dst: fa:16:3e:be:16:3b (fa:16:3e:be:16:3b)Destination: fa:16:3e:be:16:3b (fa:16:3e:be:16:3b)Address: fa:16:3e:be:16:3b (fa:16:3e:be:16:3b).... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default).... ...0 .... .... .... .... = IG bit: Individual address (unicast)Source: fa:16:3e:bd:6f:ab (fa:16:3e:bd:6f:ab)Address: fa:16:3e:bd:6f:ab (fa:16:3e:bd:6f:ab).... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default).... ...0 .... .... .... .... = IG bit: Individual address (unicast)Type: ARP (0x0806)
Address Resolution Protocol (reply)Hardware type: Ethernet (1)Protocol type: IPv4 (0x0800)Hardware size: 6Protocol size: 4Opcode: reply (2)Sender MAC address: fa:16:3e:bd:6f:ab (fa:16:3e:bd:6f:ab)Sender IP address: 172.16.1.152Target MAC address: fa:16:3e:be:16:3b (fa:16:3e:be:16:3b)Target IP address: 172.16.1.2
3、controller和compute1之间wireshark抓包(vmnet8抓包),没有ARP信息,因为已经由controller的linuxbridge-agent的arp responder功能进行arp代答了。
4、查看controller和compute1的bridge fdb表格,和ping之前是一致的。
root@controller:~# bridge fdb | grep vxlan
92:33:57:7c:56:2c dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
92:33:57:7c:56:2c dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 10.0.20.12 self permanent
fa:16:3e:bd:6f:ab dev vxlan-649 dst 10.0.20.12 self permanent
root@controller:~# root@compute1:~# bridge fdb | grep vxlan
62:39:c0:ab:4b:e6 dev vxlan-649 vlan 1 master brq28d343c8-1c permanent
62:39:c0:ab:4b:e6 dev vxlan-649 master brq28d343c8-1c permanent
00:00:00:00:00:00 dev vxlan-649 dst 10.0.20.11 self permanent
fa:16:3e:be:16:3b dev vxlan-649 dst 10.0.20.11 self permanent
fa:16:3e:11:6a:bc dev vxlan-649 dst 10.0.20.11 self permanent
fa:16:3e:33:b2:f8 dev vxlan-649 dst 10.0.20.11 self permanent
root@compute1:~#
3.5.5 Lab3小结
1、MAC地址表(bridge fdb)通过l2population预先获得。
2、ARP表项通过l2population机制预先获得,ARP请求已经由agent的arp responder功能进行了代答,ARP广播请求不穿越vxlan隧道。