HMK's blog

保持思考|00后|等待


  • Home
  • Archive
  • Tags
  •   

© 2026 Hekang

Theme Typography by Makito

Proudly published with Hexo

Neutron

Posted at 2026-06-02 Openstack 

一、Neutron 网络

传统网络vs虚拟网络

网络虚拟化

image-20260525115844259

Neutron架构图:

  • Neutron 的架构是基于插件的,不同的插件提供不同的网络服务,主要包含一下组件

    • Neutron Server: 对外提供网络API,并调用Plugin处理请求
    • Plugin:处理Neutron server的请求,维护网络状态,并调用Agent处理请求
    • Agent: 处理Plugin的请求,调用底层虚拟或物理网络设备实现各种网络功能

虚拟交换机:

Bridge:

OVS: Open Vswitch

OVN: Open Virtual Network

tap设备:虚拟机虚拟网卡名称,在虚拟机操作系统中网卡eth0,在openstack看来就是一个tap设备

qbr: QEME Bridge 提供安全组规则,目前OpenSwitch 不支持iptables防火墙规则,引入qbr 来实现iptables规则

qvb: Bridge qbr

qvo: OVS qvo

br-int: 内部虚机交换机 集成网桥,所有instance 的虚拟网卡和其他虚拟网络设备都将连接到该网桥

br-tun: 隧道网桥,基于隧道技术的vxlan 和 GRE 网络将使用 该网桥进行通信

metadata agent cloud-init 如果没有该服务,即使安装了cloud-init也无法实现个性化信息,主机名 IP地址 root密码等

Agent: 代理,具体处理业务的存在 L2 Agent 处理真正二层交换数据

L3 Agent 处理路由数据

VM1和VM2 在同一个子网,并且在同一台计算节点上,则VM1访问VM2,直接通过br-int这个内部虚拟交换机来实现,提升访问性能

Neutron 组件-Agent

  • Neutron Agent 向虚拟机提供二层和三层的网络连接、完成虚拟网络和物理网络,之间的转换,提供扩展服务

Neutron Agent :L2 Agent 、L3 Agent、DHCP Agent、MetaData Agent

在一个网络中,L2 Agent 可以由Bridge或者OVS 来实现,但是同时只能使用其中之一,所有节点要么是Bridge ,要么是OVS,考虑到业务的多样性,其他公司和其他公司采用不同L2 Agent。

引入ML2 ,支持多种L2 Agent 让我们的环境同时支持多种L2 Agent

==========================================

ML2插件 :

通过TypeManager 和 MechainismManager 实现二层互通

抽象出Plugin中共性代码(DB等)减少厂商新增和维护Plugin的工作量、只需实现driver即可

解决原结构中只支持一个Plugin的问题,同时支持多个Driver

通过l2 polulation 减少overlay网络广播流量

实现异构部署: 每个hypervisor node可使用不同的driver

计算节点运行L2 Agent openstack-openvswitch.service

网络节点运行L3 Agent

neutron-L3-agent.service

查看各个节点运行的网络组件

neutron agent-list

普通用户创建网络时,不能指定类型,使用默认类型

LOCAL :如果Neutron 租户采用该网络,只有同一个计算节点的虚拟机才能通讯,仅主机模式一般不采用

Flat: 扁平网络 不采用VLAN隔离的网络

VLAN: 带vlan tag的网络

VXLAN,GRE 等: 隧道网络

1. FLAT网络

需求一 :改造现有的VXLAN网络为Flat 网络(无Vlan隔离的网络类型)

1.在管理员身份下,创建指定的网络

OVS flat network

flat network 是不带tag的网络,宿主机的物理网卡通过网桥与flat network连接,每个flat网络都会占用一个物理网卡。

在ML2 配置中 enable flat network

在控制节点/etc/neutron/plugins/ml2/ml2_conf.ini 中设置 flat network 相关参数:

[ml2]

tenant_network_types = flat

extension_drivers = port_security

type_drivers = local,flat,vlan,gre,vxlan

memchanism_drivers = openvswitch

tenant_network_types = flat

指定普通用户网络类型为flat

&& flat网络与物理网卡一一对应,一般情况下租户网络不会采用flat

label 是flat网络的标识,在创建flat时会用到,label命名是可以任意字符串,只要确保各个节点ml2_conf.ini中的label命名一致就可以了。各个节点中label与物理网卡的对应可能不一样。

每个节点可以使用不同的物理网卡将instance 连接到flat网络

与linux bridge实现的flat网络不同,ml2中并不会直接指定label与物理网卡的对应关系,而是指定label与ovs bridge的对应关系

[ovs]

bridge_mappings = default-eth1

这里的ovs bridge 是br-eth1,需要提前通过命令ovs-ovctl 命令:

1. 创建br-eth1
1. 将物理网卡eth1 桥接在br-eth1上

如果要创建多个flat网络,需要定义多个label,用逗号隔开,当然也需要用到多个ovs bridge,如下所示:

[ml2_type_flat]

flat_networks = flat1,flat2

[ovs]

bridge_mappings = flat1:br-eth1,flat2:eth2

通过以上步骤控制节点的flat网络就准备好了。计算节点也需要做相同的配置,然后重启所有节点上的neutron服务

controller :

ovs-vsctl add-br br-eth1

ovs-vsctl add-port br-eth1 ens37

compute:

ovs-vsctl add-br br-eth1

ovs-vsctl add-port br-eth1 ens37

controller:

[root@controller ~]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/ml2_conf.ini

[ml2]
type_drivers=geneve,flat,vxlan,vlan
tenant_network_types=flat
mechanism_drivers=openvswitch
extension_drivers=port_security,qos
path_mtu=0

[root@controller ~]# egrep -v “^#|^$” /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vxlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]
local_ip=192.168.132.100
bridge_mappings=default:br-eth1

[root@controller ~]# systemctl restart neutron-server.service neutron-openvswitch-agent.service

compute:

[root@compute ~]# egrep -v “^#|^$” /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vxlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]

bridge_mappings=default:br-eth1

local_ip=192.168.132.200
[securitygroup]
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

可以创建flat 网络default 创建实例,但是通不了外网

需求二:需要让vm1 可以访问internet,或者与其他网段互通

在网络节点上配置neutron

[root@controller ~]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/ml2_conf.ini
[DEFAULT]
[ml2]
type_drivers=geneve,flat,vxlan,vlan
tenant_network_types=flat
mechanism_drivers=openvswitch
extension_drivers=port_security,qos
path_mtu=0
[ml2_type_flat]
flat_networks=default,extnet
[ml2_type_geneve]
vni_ranges=10:100
max_header_size=38
[ml2_type_gre]
[ml2_type_vlan]
network_vlan_ranges=
[ml2_type_vxlan]
vni_ranges=10:100
vxlan_group=224.0.0.1
[ovs_driver]
[securitygroup]
enable_security_group=True
[sriov_driver]

[root@controller ~]# egrep -v “^#|^$” /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vxlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]
local_ip=192.168.132.100
bridge_mappings=default:br-eth1,exnet:br-ex

[root@controller ~]# systemctl restart neutron-server.service neutron-openvswitch-agent.service

admin用户 创建其他 flat网络 外部

租户创建路由器使用外部网路 关联内部网络

租户的云主机可通网关可通外网

云主机重启获得主机名 主机名和路由器有关

弹性ip在哪里

ip netns ls

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[root@controller ~]# ip netns ls
qrouter-9306759e-750f-4001-98c0-cf8cc5c69daf (id: 1)
qdhcp-2eea55e3-bc8a-4ff8-9a85-dfc52bca7e12 (id: 0)
[root@controller ~]# ip netns exec qdhcp-2eea55e3-bc8a-4ff8-9a85-dfc52bca7e12 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
13: tap9f8ac40e-1f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether fa:16:3e:c3:05:2c brd ff:ff:ff:ff:ff:ff
inet 192.168.99.2/24 brd 192.168.99.255 scope global tap9f8ac40e-1f
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fec3:52c/64 scope link
valid_lft forever preferred_lft forever

[root@controller ~]# ip netns exec qdhcp-2eea55e3-bc8a-4ff8-9a85-dfc52bca7e12 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
13: tap9f8ac40e-1f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether fa:16:3e:c3:05:2c brd ff:ff:ff:ff:ff:ff
inet 192.168.99.2/24 brd 192.168.99.255 scope global tap9f8ac40e-1f
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fec3:52c/64 scope link
valid_lft forever preferred_lft forever
[root@controller ~]# ip netns exec qrouter-9306759e-750f-4001-98c0-cf8cc5c69daf ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
14: qr-6ac1b76d-95: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether fa:16:3e:10:ce:5b brd ff:ff:ff:ff:ff:ff
inet 192.168.99.1/24 brd 192.168.99.255 scope global qr-6ac1b76d-95
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe10:ce5b/64 scope link
valid_lft forever preferred_lft forever
15: qg-53819985-30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether fa:16:3e:2a:da:4b brd ff:ff:ff:ff:ff:ff
inet 192.168.11.28/24 brd 192.168.11.255 scope global qg-53819985-30
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe2a:da4b/64 scope link
valid_lft forever preferred_lft forever

[root@controller ~(keystone_admin)]# ip netns exec qrouter-9306759e-750f-4001-98c0-cf8cc5c69daf ping www.baidu.com
PING www.wshifen.com (103.235.46.115) 56(84) 比特的数据。
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=1 ttl=128 时间=113 毫秒
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=2 ttl=128 时间=104 毫秒
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=3 ttl=128 时间=118 毫秒
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=4 ttl=128 时间=118 毫秒
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=5 ttl=128 时间=117 毫秒
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=7 ttl=128 时间=113 毫秒
64 比特,来自 103.235.46.115 (103.235.46.115): icmp_seq=8 ttl=128 时间=118 毫秒

image-20260531112422800

# iptables -t nat -A PREROUTING -d 192.168.11.13 -j DNAT –to-dest 192.168.99.195

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[root@controller ~(keystone_admin)]# ip netns exec qrouter-9306759e-750f-4001-98c0-cf8cc5c69daf iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
neutron-l3-agent-PREROUTING all -- 0.0.0.0/0 0.0.0.0/0

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
neutron-l3-agent-OUTPUT all -- 0.0.0.0/0 0.0.0.0/0

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
neutron-l3-agent-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0
neutron-postrouting-bottom all -- 0.0.0.0/0 0.0.0.0/0

Chain neutron-l3-agent-OUTPUT (1 references)
target prot opt source destination
DNAT all -- 0.0.0.0/0 192.168.11.13 to:192.168.99.195

Chain neutron-l3-agent-POSTROUTING (1 references)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ! ctstate DNAT

Chain neutron-l3-agent-PREROUTING (1 references)
target prot opt source destination
REDIRECT tcp -- 0.0.0.0/0 169.254.169.254 tcp dpt:80 redir ports 9697
DNAT all -- 0.0.0.0/0 192.168.11.13 to:192.168.99.195

Chain neutron-l3-agent-float-snat (1 references)
target prot opt source destination
SNAT all -- 192.168.99.195 0.0.0.0/0 to:192.168.11.13 random-fully

Chain neutron-l3-agent-snat (1 references)
target prot opt source destination
neutron-l3-agent-float-snat all -- 0.0.0.0/0 0.0.0.0/0
SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.11.28 random-fully
SNAT all -- 0.0.0.0/0 0.0.0.0/0 mark match ! 0x2/0xffff ctstate DNAT to:192.168.11.28 random-fully

Chain neutron-postrouting-bottom (1 references)
target prot opt source destination
neutron-l3-agent-snat all -- 0.0.0.0/0 0.0.0.0/0 /* Perform source NAT on outgoing traffic. */

如果云主机绑定了弹性ip,路由器又开启的了SNAT 云主机出去访问是通过SNAT出去,还是弹性ip地址出去?

有弹性ip的优先走弹性ip 没有弹性ip的走路由器SNAT

1
2
3
4
5
6
7
8
Chain neutron-l3-agent-float-snat (1 references)
target prot opt source destination
SNAT all -- 192.168.99.195 0.0.0.0/0 to:192.168.11.13 random-fully

Chain neutron-l3-agent-snat (1 references)
target prot opt source destination
neutron-l3-agent-float-snat all -- 0.0.0.0/0 0.0.0.0/0
SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.11.28 random-fully

2. VLAN网络设计与实现

1
2
3
# 所有节点
ovs-vsctl add-br br-eth1
ovs-vsctl add-port br-eth1 ens37

[root@controller ml2(keystone_admin)]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/ml2_conf.ini
[DEFAULT]
[ml2]
type_drivers=geneve,flat,vxlan,vlan
tenant_network_types=vlan
mechanism_drivers=openvswitch
extension_drivers=port_security,qos
path_mtu=0
[ml2_type_flat]
flat_networks=*
[ml2_type_geneve]
vni_ranges=10:100
max_header_size=38
[ml2_type_gre]
[ml2_type_vlan]
network_vlan_ranges=vlannet​:100:1000
[ml2_type_vxlan]
vni_ranges=10:100
vxlan_group=224.0.0.1
[ovs_driver]
[securitygroup]
enable_security_group=True
[sriov_driver]

[root@controller ml2(keystone_admin)]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]
local_ip=192.168.132.100
bridge_mappings=vlannet:br-eth1,extnet:br-ex
[securitygroup]
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

[root@compute network-scripts]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vxlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]
tunnel_bridge = br-tun
local_ip=192.168.132.200
bridge_mappings = vlannet:br-eth1
[securitygroup]
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

在Openstack web界面上使用admin身份创建网络

租户网络指定不了vlanid

没有地址 br-eth1带vlan100的tag

image-20260531130612893

vmnet2 加了vlan100 相当于access vlan 100 但是机器拿不到dhcp的地址

使用user的租户创建两个云主机

查看 oepnstack neutron 的流表

第一条目: 目标vlan 内部br-int tag 2修改成vlan 100

1
2
3
4
5
[root@compute ~]# ovs-ofctl dump-flows br-eth1
cookie=0xd7a85a0091644f6e, duration=1147.937s, table=0, n_packets=83, n_bytes=18454, priority=4,in_port="phy-br-eth1",dl_vlan=2 actions=mod_vlan_vid:100,NORMAL
cookie=0xd7a85a0091644f6e, duration=2849.241s, table=0, n_packets=7, n_bytes=598, priority=2,in_port="phy-br-eth1" actions=drop
cookie=0xd7a85a0091644f6e, duration=2849.244s, table=0, n_packets=345, n_bytes=46081, priority=0 actions=NORMAL

[root@compute ~]# ovs-ofctl dump-flows br-int
cookie=0xb9c421b8d8288c45, duration=3250.291s, table=0, n_packets=0, n_bytes=0, priority=65535,dl_vlan=4095 actions=drop
cookie=0xb9c421b8d8288c45, duration=1264.686s, table=0, n_packets=0, n_bytes=0, priority=10,icmp6,in_port=”qvo61d1e3f4-64”,icmp_type=136 actions=resubmit(,24)
cookie=0xb9c421b8d8288c45, duration=1206.640s, table=0, n_packets=0, n_bytes=0, priority=10,icmp6,in_port=”qvob6c595eb-1e”,icmp_type=136 actions=resubmit(,24)
cookie=0xb9c421b8d8288c45, duration=1264.685s, table=0, n_packets=0, n_bytes=0, priority=10,arp,in_port=”qvo61d1e3f4-64” actions=resubmit(,24)
cookie=0xb9c421b8d8288c45, duration=1206.637s, table=0, n_packets=0, n_bytes=0, priority=10,arp,in_port=”qvob6c595eb-1e” actions=resubmit(,24)
cookie=0xb9c421b8d8288c45, duration=3250.278s, table=0, n_packets=137, n_bytes=20085, priority=2,in_port=”int-br-eth1” actions=drop
cookie=0xb9c421b8d8288c45, duration=1264.689s, table=0, n_packets=45, n_bytes=9578, priority=9,in_port=”qvo61d1e3f4-64” actions=resubmit(,25)
cookie=0xb9c421b8d8288c45, duration=1206.642s, table=0, n_packets=40, n_bytes=8900, priority=9,in_port=”qvob6c595eb-1e” actions=resubmit(,25)
cookie=0xb9c421b8d8288c45, duration=1548.971s, table=0, n_packets=99, n_bytes=15746, priority=3,in_port=”int-br-eth1”,dl_vlan=100 actions=mod_vlan_vid:2,resubmit(,59)
cookie=0xb9c421b8d8288c45, duration=3250.293s, table=0, n_packets=77, n_bytes=7988, priority=0 actions=resubmit(,59)
cookie=0xb9c421b8d8288c45, duration=3250.294s, table=23, n_packets=0, n_bytes=0, priority=0 actions=drop
cookie=0xb9c421b8d8288c45, duration=1264.687s, table=24, n_packets=0, n_bytes=0, priority=2,icmp6,in_port=”qvo61d1e3f4-64”,icmp_type=136,nd_target=fe80::f816:3eff:fe0d:c784 actions=resubmit(,59)
cookie=0xb9c421b8d8288c45, duration=1206.641s, table=24, n_packets=0, n_bytes=0, priority=2,icmp6,in_port=”qvob6c595eb-1e”,icmp_type=136,nd_target=fe80::f816:3eff:fe17:6da0 actions=resubmit(,59)
cookie=0xb9c421b8d8288c45, duration=1264.686s, table=24, n_packets=0, n_bytes=0, priority=2,arp,in_port=”qvo61d1e3f4-64”,arp_spa=192.168.110.8 actions=resubmit(,25)
cookie=0xb9c421b8d8288c45, duration=1206.638s, table=24, n_packets=0, n_bytes=0, priority=2,arp,in_port=”qvob6c595eb-1e”,arp_spa=192.168.110.7 actions=resubmit(,25)
cookie=0xb9c421b8d8288c45, duration=3250.291s, table=24, n_packets=3, n_bytes=126, priority=0 actions=drop
cookie=0xb9c421b8d8288c45, duration=1264.692s, table=25, n_packets=32, n_bytes=8592, priority=2,in_port=”qvo61d1e3f4-64”,dl_src=fa:16:3e:0d:c7:84 actions=resubmit(,30)
cookie=0xb9c421b8d8288c45, duration=1206.644s, table=25, n_packets=31, n_bytes=8250, priority=2,in_port=”qvob6c595eb-1e”,dl_src=fa:16:3e:17:6d:a0 actions=resubmit(,30)
cookie=0xb9c421b8d8288c45, duration=3250.289s, table=30, n_packets=241, n_bytes=42457, priority=0 actions=resubmit(,59)
cookie=0xb9c421b8d8288c45, duration=3250.288s, table=31, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,59)
cookie=0xb9c421b8d8288c45, duration=3250.293s, table=59, n_packets=531, n_bytes=78790, priority=0 actions=resubmit(,60)
cookie=0xb9c421b8d8288c45, duration=3250.292s, table=60, n_packets=531, n_bytes=78790, priority=3 actions=NORMAL
cookie=0xb9c421b8d8288c45, duration=3250.290s, table=62, n_packets=0, n_bytes=0, priority=3 actions=NORMAL

3. VXLAN 的网络设计和实现

解决: 大二层问题,跨数据中心云主机热迁移问题,热迁移只能在二层网络中

VXLAN 实现将二层网络封装在 三层中进行传输,到了对方解封装,实现二层通讯

image-20260601004315759

[root@controller ml2]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/ml2_conf.ini
[DEFAULT]
[ml2]
type_drivers=geneve,flat,vxlan,vlan
tenant_network_types=vxlan
mechanism_drivers=openvswitch
extension_drivers=port_security,qos
path_mtu=0
[ml2_type_flat]
flat_networks=*
[ml2_type_geneve]
vni_ranges=10:100
max_header_size=38
[ml2_type_gre]
[ml2_type_vlan]
network_vlan_ranges=vlannet​:100:1000
[ml2_type_vxlan]
vni_ranges=10:100
vxlan_group=224.0.0.1
[ovs_driver]
[securitygroup]
enable_security_group=True
[sriov_driver]

[root@controller ml2]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vxlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]
integration_bridge = br-int
tunnel_bridge = br-tun
local_ip=192.168.132.100
bridge_mappings=vlannet:br-eth1,extnet:br-ex
[securitygroup]
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

[root@controller ml2]# systemctl restart neutron-server

[root@compute ml2]# egrep -v ‘^#|^$’ /etc/neutron/plugins/ml2/openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types=vxlan
vxlan_udp_port=4789
l2_population=False
[dhcp]
[network_log]
[ovs]
integration_bridge = br-int
tunnel_bridge = br-tun
local_ip=192.168.132.200
bridge_mappings = vlannet:br-eth1
[securitygroup]
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

创建一个空的路由器 关联VPC11

重启实例、或者新建实例

可以获取主机名 ping通网关

Neutron - Metadata(元数据)

Metadata: 用于获取客户自己定义、我们又无法直接传送给虚拟机的数据,目前定义在DHCP上,每个网络有一个metadata,数据只走二层,一个网络有一个metadata_proxy,一个主机有一个metadata_agent,meta_proxy由dhcp_agent拉起。

cloud-init工具

  • cloud-init是Linux的一个工具,当系统启动时,cloud-init可从nova metadata服务或者config drive 中获取metadata,完成包括但不限于下面的定制化工作
  • 设置default locale
  • 设置hostname
  • 添加ssh keys 到.ssh、authorized_keys
  • 设置用户密码
  • 配置网络
  • 安装软件包

metadata: nova-metadata neutron-metadata

获取metadata流程

  • instance 通过预定义的169.254.169.254请求metadata

  • 请求被转发到neutron router

  • router 将请求转发给neutron-ns-metadata-proxy

  • 再后面就简单了: neutron-ns-metadata-proxy将请求通过unix domain socket 发给neutron-metadata-agent,后者再通过管理网络发送给nova-api-metadata

    image-20260602000339263image-20260602001739001

二、跨主机数据流

1️⃣ 跨主机 + 同子网(VM1 $\rightarrow$ VM2)—— 纯二层走线

  • VM1 发出报文 $\rightarrow$ tap $\rightarrow$ qbr(安全组) $\rightarrow$ br-int(打上内部 VLAN 标签,比如 1) $\rightarrow$ br-tun(将内部 VLAN 转为 VXLAN ID,比如 100)。
  • 关键一步: br-tun 查 MAC 地址表,发现 VM2 在 Compute 2 上,直接封装隧道外层 IP(源:Compute1 IP,目的:Compute2 IP)。
  • 网络传输: 数据包通过物理交换机,直接送到 Compute Node 2。
  • 解包入库: Compute 2 的 br-tun 剥离 VXLAN 头 $\rightarrow$ br-int $\rightarrow$ qbr $\rightarrow$ VM2。

💡 总结: 同子网跨主机,数据流呈 一字型(直线) 在两个计算节点间互通,不拐弯,不进网络节点。

🗺️ 正确的数据流向步骤拆解(对应上图):

  1. VM1 ➔ qbr-XXX (安全组): VM1 发现目标 VM2 的 IP 和自己在同一个网段(比如 192.168.10.0/24),于是直接通过 tap 设备发出二层以太网帧。经过 qbr 虚拟网桥时,Neutron 安全组规则(iptables/ovs-firewall)对流量进行安全检查。
  2. qvo-XXX ➔ br-int (集成网桥): 流量通过 qvb/qvo 接口进入 br-int。此时 br-int 会给这个数据包打上一个内部 VLAN Tag(本地有效,用于隔离计算节点上的不同网络)。
  3. patch-tun ➔ br-tun (隧道网桥): 数据包通过 patch-tun 补丁接口到达 br-tun。
  4. 二层核心转换 (VLAN ➔ VXLAN): br-tun 根据内部 VLAN Tag 查表,将其转换为全局唯一的 VXLAN ID (Tunnel ID)。同时,br-tun 查找 MAC 地址表,发现 VM2 的 MAC 地址在 Compute Node 2 上。
  5. 物理网络(直接飞过去): br-tun 为数据包封装外层 IP 头(源 IP: Compute 1 的 VTEP IP,目的 IP: Compute 2 的 VTEP IP)。数据包通过物理网卡 ethX 出去,直接走物理交换机送达 Compute Node 2。

三、跨主机、跨网络数据流

跨主机 + 跨子网(VM1 VM2)—— 三层大拐弯

  • VM1 发出报文,目的地是 VM2(不同网段),VM1 发现无法直接二层送达,于是将目的 MAC 填为网关(Router 的 qr 接口)的 MAC。

  • 前半程(去网络节点): Compute 1 正常走 br-int $\rightarrow$ br-tun(封 VXLAN)。但此时查表发现网关在网络节点上,于是隧道外层目的 IP 填的是 Network Node 的 IP。

  • 中转站(网络节点内部剥离与路由):

    数据包到达网络节点的 br-tun $\rightarrow$ br-int $\rightarrow$ 顺着 qr-### 接口进入 Router Namespace(虚拟路由器)。

  • 三层路由:

    路由器摘掉子网 A 的外套,查看路由表,换上子网 B 的外套,从另一个 qr-### 接口送回 br-int。

  • 后半程(去 Compute 2):

    网络节点的 br-int $\rightarrow$ br-tun(重新封装子网 B 的 VXLAN ID) $\rightarrow$ 此时隧道外层目的 IP 填 Compute Node 2 的 IP。

  • 到达终点: 经过物理网络 $\rightarrow$ Compute 2 的 br-tun $\rightarrow$ br-int $\rightarrow$ VM2。

💡 总结: 跨子网跨主机,数据流呈 V字型(或三角形)。必须先从 Compute 1 垂直下行到 Network Node 的 Router 换乘,再折返回来到 Compute 2。

四、访问Internet数据流

🛠️ 额外补充:如果是 DVR(分布式路由)呢?

如果你在 OpenStack 里开启了 DVR(Distributed Virtual Router),那么逻辑确实会变得像刚才那张错图一样“差不多”:

  • 在 DVR 模式下,每个计算节点上都有路由器的副本。
  • VM1 跨子网访问 VM2 时,在 Compute 1 本地就直接由本地路由器完成路由和 VXLAN 转换,然后直接通过隧道发送到 Compute 2。
  • 只有当 VM2 需要访问外网(Public Network)或者进行 Floating IP 转换时,才会去和网络节点/网关打交道。

Share 

 Previous post: ceph_install Next post: Rocky9.7install-openstack 

© 2026 Hekang

Theme Typography by Makito

Proudly published with Hexo