1. 项目背景与改造动机
1.1 为什么要在Ussuri集群里动网络组件
OpenStack Ussuri这个版本,很多部署工具默认走的是LinuxBridge加VXLAN的方案。这套组合稳定、简单、上手快,对于中小规模集群或者刚接触OpenStack的人来说,几乎是最省心的选择。但集群一旦跑起来,业务一多,问题就慢慢冒出来了。我这边遇到的最典型场景是:同一台计算节点上跑了几十个租户网络,每个网络都要在br-int、br-tun上挂一堆veth和tap设备,LinuxBridge的转发面在包量上来之后,内核态桥接的转发效率开始吃紧,尤其是跨节点东西向流量大的时候,延迟抖动明显。
更关键的是,LinuxBridge对VXLAN的支持是"能用但不够精细"。它没有流表,没有隧道端点的集中管理,也没有办法做基于流的负载均衡。而Open vSwitch(后面简称OVS)天生就是为虚拟化网络设计的,支持OpenFlow流表、支持隧道元数据、支持多级流表流水线,还能和Neutron的ML2插件深度配合。所以把LinuxBridge换成OVS,本质上不是"换个驱动",而是把整个数据面的转发模型从"MAC学习+泛洪"升级到"流表驱动+精确转发"。
这个改造在CentOS 8上做,又多了一层麻烦。CentOS 8的内核版本是4.18,OVS的版本选择、内核模块编译、NetworkManager的干扰、firewalld的规则冲突,每一个都是坑。我前后在测试环境里折腾了差不多两周,才把一套可复现的流程跑通。下面就把整个改造过程拆开讲,包括为什么这么选、每一步在干什么、踩过哪些坑。
1.2 改造前后的架构对比
先上一张对比表,把LinuxBridge和OVS+VXLAN在Ussuri集群里的差异说清楚。这张表是我自己整理出来的,不是抄文档,每一条都对应实际运维中能感知到的差别。
| 对比维度 | LinuxBridge + VXLAN | OVS + VXLAN |
|---|---|---|
| 转发模型 | 内核桥MAC学习,泛洪为主 | OpenFlow流表,精确匹配 |
| 隧道管理 | 每个VXLAN一个bridge端口 | 统一br-tun,流表分流 |
| 多租户隔离 | VLAN tag + 网络命名空间 | 流表+隧道ID,隔离更彻底 |
| 性能表现 | 小规模够用,大规模抖动 | 流表卸载后转发稳定 |
| 配置复杂度 | 低,几乎零配置 | 高,需要理解流表逻辑 |
| 与Neutron集成 | ML2 linuxbridge驱动 | ML2 openvswitch驱动 |
| 故障排查 | brctl show + ip link | ovs-vsctl + ovs-ofctl dump-flows |
| 对CentOS 8适配 | 原生支持好 | 需要额外处理内核模块和NM |
从表里能看出来,OVS的优势在规模和精细控制,代价是复杂度。如果你的集群节点数少于5台、租户网络少于20个,说实话LinuxBridge完全够用,没必要折腾。但一旦超过这个量级,或者你对网络性能有明确要求,OVS就是绕不过去的选择。
1.3 改造的适用范围和前置条件
这套改造方案不是万能的,我先说清楚适用边界。集群必须是Ussuri版本,部署方式不管是Kolla-Ansible还是手动装的,只要Neutron的ML2配置可控就行。CentOS 8是硬性要求,因为下面涉及的内核模块编译和NetworkManager配置都是针对这个版本的。计算节点和控制节点都要改,控制节点改ML2配置和agent,计算节点改OVS网桥和隧道。
前置条件有几个必须满足:第一,集群当前是健康的,没有正在进行的迁移或故障;第二,所有节点的root权限可操作;第三,最好有带外管理或者控制台访问,因为改网络的过程中SSH大概率会断;第四,提前备份Neutron数据库和所有节点的网络配置文件。这四条少一条都别动手,我吃过亏,后面会讲。
2. 核心组件选型与原理拆解
2.1 OVS在Ussuri里的角色定位
在Ussuri的Neutron架构里,OVS承担的是L2和部分L3的转发职责。具体来说,每个计算节点上会跑一个openvswitch-agent,它负责管理本地的br-int、br-tun、br-ex三个网桥。br-int是集成网桥,所有虚拟机的tap口、DHCP命名空间、路由命名空间都挂在这上面;br-tun是隧道网桥,负责VXLAN隧道的封装和解封装;br-ex是外部网桥,连接物理网卡和浮动IP。
这三个网桥之间的流量走向,全靠OpenFlow流表控制。比如一个虚拟机发出一个包,先到br-int,br-int根据流表判断是本地转发还是需要走隧道,如果需要走隧道就送到br-tun,br-tun再根据隧道ID封装成VXLAN包发出去。整个过程没有MAC学习,没有泛洪,全靠流表精确匹配。这就是OVS比LinuxBridge快的原因,也是它复杂的原因。
2.2 VXLAN隧道在OVS里的实现机制
VXLAN本身是一个隧道协议,把二层帧封装在UDP里,默认端口4789。在LinuxBridge方案里,每个VXLAN网络对应一个vxlan类型的网卡,内核负责封装解封装。在OVS方案里,VXLAN隧道是br-tun上的一个端口,类型是vxlan,远端IP通过流表动态添加。
这里有个关键点:OVS的VXLAN端口不是"一个网络一个端口",而是"一个远端IP一个端口"。也就是说,如果集群有10个计算节点,每个节点上br-tun只需要一个vxlan端口指向其他9个节点的隧道IP,而不是每个租户网络都建一个端口。这个设计大幅减少了端口数量,也是OVS在大规模集群里更稳的原因之一。
流表的工作方式是:br-tun收到一个VXLAN包,先根据隧道ID(VNI)查表,找到对应的本地VLAN tag,然后送到br-int;反过来,br-int送来的包,br-tun根据目的MAC查表,找到对应的远端IP,然后封装发送。这些流表都是openvswitch-agent动态下发的,不需要手动维护。
2.3 CentOS 8带来的特殊挑战
CentOS 8和CentOS 7在OVS部署上有几个明显差异,每一个都可能让你卡半天。第一个是NetworkManager,CentOS 8默认用NM管理所有网络接口,而OVS的网桥和端口如果被NM接管,会出现"配置了但不生效"或者"重启后丢失"的问题。解决办法是在NM里把OVS相关的接口设为unmanaged,或者直接用nmcli命令把网桥排除。
第二个是内核模块。CentOS 8的内核是4.18,自带的openvswitch内核模块版本可能和用户态的ovs-vswitchd不匹配。如果版本对不上,OVS会退回到用户态转发,性能直接掉一个数量级。所以必须确认内核模块加载的是正确版本,必要时用dkms重新编译。
第三个是firewalld。CentOS 8默认开firewalld,它会拦截VXLAN的UDP 4789端口和OVS的OpenFlow端口。如果不提前放行,隧道建不起来,虚拟机跨节点不通。这个坑我踩过,排查了两个小时才发现是防火墙。
3. 改造前的环境准备与备份
3.1 集群状态检查清单
动手之前,先把集群状态摸清楚。我习惯用下面这个清单逐项确认,任何一项不通过就暂停。
- 所有节点的
neutron-agent-list显示alive,没有down的agent - 所有计算节点的
openstack network agent list里LinuxBridge agent状态正常 - 随机挑两台不同节点的虚拟机,互相ping和iperf测试,确认当前网络基线正常
- 检查所有节点的
ip link,确认没有异常的网卡或网桥 - 确认所有节点的Neutron配置文件路径一致,通常是
/etc/neutron/plugins/ml2/ - 记录当前所有租户网络的VNI和VLAN映射关系,后面要用
这个清单看起来啰嗦,但每一条都有用。特别是最后一条,VNI和VLAN的映射在改造后需要核对,如果对不上,租户网络就断了。
3.2 配置文件和数据备份
备份分三块:Neutron数据库、各节点配置文件、网络状态快照。数据库备份在控制节点做,用mysqldump导出neutron库。配置文件备份包括/etc/neutron/整个目录、/etc/sysconfig/network-scripts/里的网卡配置、/etc/NetworkManager/的配置。网络状态快照用ip addr show、brctl show、ovs-vsctl show(如果已装OVS)分别导出到文件。
注意:备份一定要在改造前做,而且要在所有节点上做。我见过有人只备份了控制节点,结果计算节点改坏了回不去,只能重装。
备份命令示例:
# 控制节点备份Neutron数据库 mysqldump -u root -p neutron > /backup/neutron_$(date +%Y%m%d).sql # 所有节点备份配置 tar czf /backup/neutron_config_$(hostname)_$(date +%Y%m%d).tar.gz /etc/neutron/ tar czf /backup/network_scripts_$(hostname)_$(date +%Y%m%d).tar.gz /etc/sysconfig/network-scripts/ # 网络状态快照 ip addr show > /backup/ip_addr_$(hostname).txt brctl show > /backup/brctl_$(hostname).txt3.3 安装OVS和相关依赖
CentOS 8上装OVS,我推荐用官方仓库的版本,不要用系统自带的。系统自带的版本偏旧,和Ussuri的Neutron agent配合可能有问题。安装步骤如下:
# 添加OVS仓库 yum install -y centos-release-openstack-ussuri yum install -y openvswitch # 确认版本 ovs-vsctl --version # 输出应该是2.13或更高 # 启动OVS服务 systemctl enable openvswitch systemctl start openvswitch # 确认内核模块 lsmod | grep openvswitch # 如果没输出,手动加载 modprobe openvswitch装完之后,先别急着改Neutron配置,先确认OVS本身能正常工作。用ovs-vsctl add-br test-br建一个测试网桥,然后ovs-vsctl show看能不能看到,再删掉。这一步是确认OVS的数据库和守护进程都正常。
4. 控制节点Neutron配置改造
4.1 ML2插件配置切换
控制节点的改造核心是ML2配置。Ussuri的ML2配置在/etc/neutron/plugins/ml2/ml2_conf.ini,需要把mechanism_drivers从linuxbridge改成openvswitch,同时确认tenant_network_types里有vxlan。
[ml2] type_drivers = flat,vlan,vxlan tenant_network_types = vxlan mechanism_drivers = openvswitch,l2population extension_drivers = port_security [ml2_type_vxlan] vni_ranges = 1:1000 vxlan_group = 239.1.1.1这里有几个点要解释。mechanism_drivers里加了l2population,这是OVS方案的关键。l2population的作用是把MAC地址信息通过消息队列同步到所有节点,这样br-tun就不需要泛洪来学习MAC,直接查表就能转发。没有l2population,OVS的VXLAN就退化成和LinuxBridge一样的泛洪模式,性能优势就没了。
vni_ranges是VXLAN网络标识的范围,1到1000够大多数场景用。vxlan_group是组播组地址,如果集群不支持组播,这个可以留空,但Ussuri里一般建议填上,避免一些边界问题。
4.2 Openvswitch agent配置
控制节点上一般也跑openvswitch-agent(如果控制节点同时是网络节点)。配置文件在/etc/neutron/plugins/ml2/openvswitch_agent.ini,关键配置如下:
[ovs] local_ip = 10.0.0.1 bridge_mappings = physnet1:br-ex tunnel_bridge = br-tun integration_bridge = br-int [agent] tunnel_types = vxlan l2_population = True arp_responder = Truelocal_ip是节点的隧道IP,必须是所有计算节点都能互相访问的地址,通常是管理网IP。bridge_mappings把物理网络名映射到br-ex,这个要和之前LinuxBridge方案里的物理网络名保持一致,否则浮动IP会出问题。arp_responder打开后,OVS会代答ARP请求,减少广播,这个在Ussuri里建议开启。
4.3 重启服务与验证
配置改完后,重启Neutron相关服务:
systemctl restart neutron-server systemctl restart neutron-openvswitch-agent然后验证agent状态:
openstack network agent list应该能看到Open vSwitch agent变成alive,原来的LinuxBridge agent消失。如果agent起不来,先看日志/var/log/neutron/openvswitch-agent.log,最常见的错误是local_ip填错或者OVS服务没起来。
提示:控制节点改完后,先别急着改计算节点。先在控制节点上确认agent正常,再逐台改计算节点,这样出问题容易定位。
5. 计算节点OVS网桥与隧道配置
5.1 清理LinuxBridge残留
计算节点改造的第一步是把LinuxBridge的残留清干净。这步很关键,如果br-int、br-tun这些名字被LinuxBridge占用了,OVS就建不起来。清理步骤如下:
# 停止LinuxBridge agent systemctl stop neutron-linuxbridge-agent systemctl disable neutron-linuxbridge-agent # 删除LinuxBridge的网桥 brctl delbr br-int 2>/dev/null brctl delbr br-tun 2>/dev/null brctl delbr br-ex 2>/dev/null # 确认没有残留 brctl show ip link show type bridge清理的时候要注意,如果节点上还有虚拟机在跑,删网桥会导致虚拟机断网。所以这一步最好在维护窗口做,或者先把虚拟机迁移走。
5.2 创建OVS网桥和端口
清理完之后,用ovs-vsctl创建三个网桥:
# 创建集成网桥 ovs-vsctl add-br br-int # 创建隧道网桥 ovs-vsctl add-br br-tun # 创建外部网桥 ovs-vsctl add-br br-ex # 把物理网卡加到br-ex ovs-vsctl add-port br-ex eth0 # 确认 ovs-vsctl show这里有个细节:物理网卡加到br-ex之后,原来的IP配置会失效,因为IP现在在网桥上而不是网卡上。所以需要把物理网卡的IP配置迁移到br-ex上。在CentOS 8里,如果用NetworkManager,需要把eth0设为unmanaged,然后给br-ex配IP。
# 把eth0设为unmanaged nmcli device set eth0 managed no # 给br-ex配IP(假设原来是eth0的IP) nmcli connection add type ovs-bridge con-name br-ex ifname br-ex nmcli connection add type ovs-port con-name br-ex-port ifname br-ex master br-ex nmcli connection add type ovs-interface con-name br-ex-if ifname br-ex master br-ex-port nmcli connection modify br-ex-if ipv4.addresses 10.0.0.1/24 ipv4.gateway 10.0.0.254 ipv4.method manual nmcli connection up br-ex5.3 配置VXLAN隧道端点
隧道端点的配置其实不需要手动做,openvswitch-agent会根据Neutron的配置自动在br-tun上添加vxlan端口。但前提是agent配置正确,且l2population正常工作。手动验证隧道是否建立:
# 查看br-tun上的端口 ovs-vsctl list-ports br-tun # 应该能看到类似vxlan-10.0.0.2的端口,对应其他计算节点 # 查看流表 ovs-ofctl dump-flows br-tun如果看不到vxlan端口,说明agent没有正确下发配置。检查agent日志,常见原因是local_ip不通或者防火墙拦截了UDP 4789。
5.4 防火墙和NetworkManager收尾
CentOS 8的firewalld必须放行VXLAN和OVS相关流量:
firewall-cmd --permanent --add-port=4789/udp firewall-cmd --permanent --add-port=6633/tcp firewall-cmd --permanent --add-port=6640/tcp firewall-cmd --reloadNetworkManager那边,除了把物理网卡设为unmanaged,还要确保OVS的网桥不被NM接管。可以在/etc/NetworkManager/conf.d/下加一个配置文件:
[keyfile] unmanaged-devices=interface-name:br-int;interface-name:br-tun;interface-name:br-ex然后重启NetworkManager。这一步做完,OVS的网桥就不会被NM干扰了。
6. 常见问题与排查实录
6.1 虚拟机跨节点不通的排查思路
改造后最常见的问题就是虚拟机跨节点不通。排查顺序我总结成一张表:
| 排查步骤 | 命令 | 预期结果 | 异常处理 |
|---|---|---|---|
| 检查agent状态 | openstack network agent list | OVS agent alive | 看agent日志 |
| 检查隧道端口 | ovs-vsctl list-ports br-tun | 有vxlan-xxx端口 | 检查local_ip和防火墙 |
| 检查流表 | ovs-ofctl dump-flows br-tun | 有隧道分流流表 | 检查l2population |
| 检查VNI映射 | ovs-vsctl list interface | VNI和Neutron一致 | 核对ml2配置 |
| 检查ARP | ip netns exec qrouter-xxx arping | 能通 | 检查arp_responder |
这个表是我实际排查时用的,按顺序走一遍,基本能定位到问题。最常见的是防火墙没放行4789,其次是l2population没开导致流表不全。
6.2 OVS内核模块版本不匹配
CentOS 8上如果内核模块版本和用户态不匹配,OVS会报"datapath not supported"之类的错误。检查方法:
# 查看用户态版本 ovs-vsctl --version # 查看内核模块版本 modinfo openvswitch | grep version # 如果版本不一致,重新编译 yum install -y openvswitch-kmod modprobe -r openvswitch modprobe openvswitch如果还是不行,可能需要用dkms重新编译。这个坑在CentOS 8上比较常见,因为系统更新内核后,原来的模块可能没跟着更新。
6.3 NetworkManager导致的配置丢失
NetworkManager最烦人的地方是它会"自作主张"地管理OVS网桥,导致重启后配置丢失。除了前面说的unmanaged配置,还有一个办法是直接禁用NM对OVS的管理:
# 查看NM是否在管理OVS nmcli device status | grep ovs # 如果显示managed,改成unmanaged nmcli device set br-int managed no nmcli device set br-tun managed no nmcli device set br-ex managed no这个操作要在每台计算节点上做,做完后重启NM验证配置是否保留。
6.4 改造后性能反而下降的情况
有人改完OVS发现性能还不如LinuxBridge,这种情况通常是流表没生效,OVS退回到慢路径转发了。检查方法:
# 查看流表命中情况 ovs-ofctl dump-flows br-int | grep n_packets # 如果大部分流表的n_packets是0,说明没命中 # 检查l2population是否开启 grep l2_population /etc/neutron/plugins/ml2/openvswitch_agent.inil2population没开的话,br-tun会泛洪,性能自然差。另外,如果OVS的datapath类型是netdev而不是system,也会走用户态转发,性能掉得厉害。用ovs-vsctl get Open_vSwitch . datapath_type确认,应该是空或者system。
7. 改造后的验证与回滚方案
7.1 功能验证清单
改造完成后,按这个清单逐项验证:
- 新建一个租户网络,创建两台虚拟机,跨节点能ping通
- 虚拟机能获取DHCP地址
- 浮动IP能正常绑定和访问
- 安全组规则生效
- 东西向流量iperf测试,带宽和延迟符合预期
- 重启一台计算节点,虚拟机和网络能自动恢复
这个清单里,重启测试最重要。很多配置问题在重启后才暴露,比如NM接管、内核模块没加载、流表丢失等。
7.2 回滚步骤
如果改造失败,回滚要快。回滚步骤和改造步骤相反:
# 停止OVS agent systemctl stop neutron-openvswitch-agent # 恢复Neutron配置 tar xzf /backup/neutron_config_xxx.tar.gz -C / # 恢复LinuxBridge systemctl start neutron-linuxbridge-agent # 恢复网络配置 tar xzf /backup/network_scripts_xxx.tar.gz -C / systemctl restart network回滚的关键是备份要全,而且要在改造前确认备份可用。我一般会在测试环境先演练一遍回滚,确认没问题再动生产。
7.3 改造后的运维习惯调整
改成OVS之后,日常运维的命令和LinuxBridge完全不一样。以前用brctl show看网桥,现在用ovs-vsctl show;以前用ip link看端口,现在用ovs-vsctl list-ports;排查问题要看流表,用ovs-ofctl dump-flows。这些命令需要时间适应,建议改造后先在测试环境多练几遍。
另外,OVS的日志在/var/log/openvswitch/,agent日志在/var/log/neutron/openvswitch-agent.log,出问题先看这两个地方。流表相关的调试可以用ovs-appctl ofproto/trace,这个工具能模拟一个包在OVS里的转发路径,排查复杂问题很有用。
我个人在实际操作中的体会是,这套改造最大的难点不在技术本身,而在细节。CentOS 8的NM、firewalld、内核模块,每一个都是小坑,单独看都不难,但凑在一起就容易让人抓狂。建议动手前先在测试环境完整走一遍,把每个坑都踩一遍,再上生产。另外,改造过程中一定要保持控制台访问,因为网络一断SSH就没了,有控制台至少能救回来。最后再分享一个小技巧:改之前把所有节点的ovs-vsctl show和ovs-ofctl dump-flows输出保存下来,改造后对比,能快速发现哪些流表没下发。