简介:这份资源是《OpenStack环境下多租户网络隔离技术的应用研究》PDF文档,面向云计算研究人员、系统管理员及OpenStack开发运维人员,聚焦多租户场景下网络隔离方案的设计与落地。内容从OpenStack架构与Neutron、Nova等关键组件切入,系统梳理VLAN、VXLAN、GRE等二层隔离技术及路由隔离、安全组等三层方案,提出综合设计并给出实验环境搭建、租户创建、网络配置与安全策略实施细节。全文涵盖研究背景、国内外现状、技术选型、部署流程、连通性测试、流量分析及异常检测等章节,便于读者理解从原理到验证的完整链路。包体为单个PDF文件,大小仅136KB,已有92人学习,适合快速建立知识框架,也能为云平台网络规划、租户隔离策略优化提供直接参考。读者可从中获得从理论分析到实验配置的完整思路,以及故障检测与性能评估的实用方法,对后续扩展自动化管理颇具启发。
1. 多租户网络隔离:OpenStack部署里最容易“能用但不敢用”的一环
某次给一家企业做OpenStack云平台搭建,存储和计算节点都验收完了,结果两个租户的生产环境网络在同一个二层广播域里裸奔了三天。问题不小,任何一个租户都能嗅探到另一租户的ARP流量,监控告警直接拉响。最终定位到是Neutron的安全组策略没有跟随项目配置一起下发,默认的放行规则把隔离层直接架空了。这件事之后,我养成了一个习惯:验收OpenStack项目时,第一件事不是看控制台漂不漂亮,而是验证多租户网络隔离到底有没有切干净。这篇笔记,就把从原理选型到落地排错的完整路径写清楚,适合正在做OpenStack部署或接手多租户环境运维的工程师。
2. Neutron网络隔离的实现层级:Flat/VLAN/VXLAN到底差在哪
OpenStack里的网络隔离不是一套开关,而是由Neutron管理的二层隔离机制。租户A的虚拟机和租户B的虚拟机要互不感知,必须让它们的广播域从创建那一刻就被拆开。Neutron给出的答案分别是Flat、VLAN和VXLAN,三种模型的隔离边界和容量上限完全不同。选错一个,后面几十台物理机都要跟着返工。
2.1 三种Provider网络的隔离模型与容量边界
Flat网络直接把虚拟机接到物理交换机的同一广播域里,Neutron不参与任何隔离。它是最省事的模型,租户网络和物理网络处在同一个二层,虚拟机可以直接拿物理网络的IP。代价是没有任何租户边界,一个租户的广播流量会灌进所有Flat网络,生产环境敢用Flat就等于把隔离层全部交给上层应用的防火墙。它只适合单机测试或者临时环境。
VLAN调用了物理交换机本身的802.1Q能力。Neutron给每个租户网络分配一个VLAN ID,在物理链路上打Tag,交换机靠这个Tag区分不同租户的二层流量。VLAN ID字段只有12位,可用数上限是4094,对多租户规模是个硬约束。更重要的是它依赖物理交换机的Trunk放行,新建租户网络时如果忘了在某台交换机上放行对应VLAN,就会出现一批节点通、另一批节点不通的局面。这个话题留到第5章展开。
VXLAN是当前多租户生产环境的主流选择。它用24位的VNI字段,隔离空间上限超过1600万,远超实际租户规模。VXLAN是Overlay方案,原始以太网帧被封装进UDP包,底层只需要IP连通性,物理交换机不需要感知VNI。这意味着跨二层甚至跨三层的数据中心里,VXLAN隧道都能把租户的二层广播域拉齐。代价是每个包多出50字节左右的开销,MTU规划和UDP端口的放行必须提前处理好。
| 隔离机制 | 标识位 | 理论容量 | 物理设备依赖 | 适用规模 |
|---|---|---|---|---|
| Flat | 无 | 1 | 无要求 | 测试环境 |
| VLAN | 12位 | 4094 | 交换机Trunk配置 | 中小规模 |
| VXLAN | 24位 | 约1677万 | 仅需IP网络 | 大规模多租户 |
选型时还要考虑一个常被忽略的点:VLAN是物理隔离,VXLAN是逻辑隔离。物理隔离的数据面转发取决于交换机的硬件表项,性能好但扩展受限;逻辑隔离的转发路径多了一层封装和解封装,CPU开销更高,但灵活性和规模上限都占优。多租户系统刚起步时用VLAN感觉很踏实,租户一多,VLAN ID的分配和交换机配置变更就成了运维噩梦,那时候再迁VXLAN,代价远大于一开始就选对。
2.2 ML2插件架构:Type Driver和Mechanism Driver怎么分工
Neutron能同时支持多种隔离机制,靠的是ML2插件。ML2把能力拆成两层,Type Driver负责网络类型的状态管理,Mechanism Driver负责把状态落实到实际转发路径。Type Driver管的是段,比如VLAN的ID分配范围、VXLAN的VNI分配范围,都由它负责登记和回收。Mechanism Driver管的是具体机制,最常见的就是LinuxBridge和Open vSwitch。
一次网络创建请求的完整路径大致如下:用户指定network type为vxlan,Type Driver从配置好的VNI池里取一个空闲VNI,写入数据库,然后通知Mechanism Driver。Mechanism Driver接着把VNI和网络信息下发给各计算节点上的Agent,Agent在本地创建虚拟交换机或网桥,并把隧道端口绑定到指定的物理网卡上。这个流程大部分是黑匣子,链路上任何一个环节失败,控制台上的表象都是“网络状态active但虚拟机不通”。
部署完成后可以查看实际生效的配置,确认自己环境的能力边界:
grep -E "type_drivers|tenant_network_types|mechanism_drivers" \ /etc/kolla/neutron-server/neutron.conf逻辑说明:type_drivers列出该环境支持的provider网络类型,tenant_network_types是租户创建网络时默认可选的类型,mechanism_drivers决定走OVS还是LinuxBridge。kolla默认通常包含flat、vlan、vxlan,Mechanism为openvswitch。如果看到tenant_network_types里只有vlan,说明租户创建网络的类型被限制住了,需要改成vxlan才能用上Overlay隔离。
2.3 选型判断:多大规模用什么隔离方案
选型没有绝对标准,给一个我常用的判断框架。单机或者两三台的演示环境,Flat够用,别浪费时间调隧道。物理机在20台以内、租户数量稳定、网络团队能维护交换机配置,VLAN可以接受,它的排查链路短,物理交换机的转发性能也最好。超过这个规模,尤其是多个租户需要独立网段、频繁创建和删除网络,直接上VXLAN,把隔离计算负担从物理交换机转移到Neutron和主机CPU上。
混合场景也很常见。遇到过核心业务网络坚持用VLAN,测试区用VXLAN的环境,Neutron允许两种类型共存,只要在创建网络时显式指定provider-network-type。关键是把VNI和VLAN的分配段错开,避免冲突。对工作室这类小规模、多机器之间需要做IP隔离的场景,一张VLAN规划就能兜住,不必一上来就引VXLAN增加排错成本。选型这件事,最怕的是照搬别人的架构,物理机数量、租户并发、运维人力都不一样,隔离方案理应不同。
3. 用openstack kolla拉起隔离环境:部署命令与租户网络创建
3.1 kolla-ansible部署前要把三张网卡的角色想清楚
用openstack kolla这套容器化部署方式,最大的好处是Neutron组件以容器方式交付,避免了手动安装时版本错乱的坑。部署前需要先明确节点上三张物理网卡的角色:管理网络走API和内部通信,外部网络接物理路由器和Floating IP,隧道网络走VXLAN封装后的流量。kolla允许管理网和隧道网复用同一张网卡,生产环境我一般把隧道单独分一张,避免租户的大流量冲击管理面。
globals.yml里三个参数对应上述角色:
network_interface: "eth0" # 管理网卡 neutron_external_interface: "eth1" # 外部网卡 tunnel_interface: "eth2" # VXLAN隧道网卡参数说明:network_interface同时承载容器间的内部通信,必须所有节点可达;neutron_external_interface只在网络节点或启用DVR的节点上配置外部网关;tunnel_interface上的IP会被Neutron写进隧道端点,所有计算节点之间需要三层互通。如果计算节点通过qemu部署多架构虚拟机这类需求也放进环境里,tunnel_interface的选择逻辑不变,隧道流量仍然走物理网卡,和虚拟机的CPU架构没有关系。
确认好网卡角色后,按顺序执行部署命令:
# 安装kolla-ansible后先生成密码和配置 kolla-genpwd # 检查主机是否满足部署条件 kolla-ansible prechecks -i /etc/kolla/multinode # 正式部署 kolla-ansible deploy -i /etc/kolla/multinode # 生成admin用户的openrc环境文件 kolla-ansible post-deploy参数说明:-i指定inventory文件,multinode文件里每个节点都有role标签,比如control、compute、network,至少要保证control节点上跑了neutron-server,compute节点上跑了neutron-openvswitch-agent。prechecks会检查网卡、DNS、磁盘等基础条件,这步的报错要全部清掉再deploy,硬着头皮继续只会把问题留到开机之后。
3.2 创建第一个租户网络:用四条命令完成隔离交付
创建租户隔离网络前,先要有租户这个概念。OpenStack里project就是租户的实体,用户归属于project,网络资源的归属也挂在project下。下面这套命令把租户、用户、VXLAN网络、子网、路由器一次性串起来,是openstack搭建教程里最常见的交付组合:
source /etc/kolla/admin-openrc.sh # 创建租户和用户 openstack project create tenant-a openstack user create --project tenant-a --password 'Tenant@123' user-a # 创建VXLAN隔离网络 openstack network create --project tenant-a \ --provider-network-type vxlan \ --provider-segment 1001 net-a # 创建子网,网段避开物理网络 openstack subnet create --project tenant-a \ --network net-a --subnet-range 192.168.100.0/24 \ --gateway 192.168.100.1 subnet-a # 创建路由器并接入外部网关,再挂上子网 openstack router create --project tenant-a router-a openstack router set --project tenant-a router-a \ --external-gateway public openstack router add subnet router-a subnet-a逻辑说明:命令先后顺序有讲究。先有project和user,租户网络才有归属者;创建network时显式声明vxlan类型和segment ID,让Neutron按规划取VNI而不是随机抢;subnet挂在net-a上,IP段必须避让底层物理网络和外部网络的路由,否则路由表会打架;最后create router并挂external-gateway,是为了让租户虚拟机之后能访问外部网络,如果只是做纯内网隔离,router这一步可以省。
参数说明:--provider-segment 1001里的1001是VNI号,取值范围在neutron.conf里配置的vni_range中选择,不同租户用不同VNI,这是隔离的关键。--external-gateway public里的public,是部署时创建好的外部网络名,用openstack network list确认实际名称,有些环境叫ext-net。密码字段Tenant@123只适合测试,生产环境交给管理员单独导入。
3.3 验证隔离是否生效:从命名空间看网络的真实拓扑
租户网络创建成功后,控制台上的active状态并不代表隔离已生效。更可靠的验证方式是进入Neutron的路由命名空间,看路由器的转发视图:
# 列出所有路由器的qrouter命名空间 ip netns list # 查看路由器命名空间里的网卡和IP ip netns exec qrouter-xxxxxxxx-xxxx ip addr # 从路由器命名空间ping租户内的虚拟机 ip netns exec qrouter-xxxxxxxx-xxxx ping 192.168.100.10逻辑说明:qrouter命名空间是每个路由器对应的独立网络栈,里面有连接租户子网的接口,以qg和qr开头。能从qr接口ping通租户虚拟机,说明路由器到子网的数据路径是通的,租户内部的二层广播域在路由器视角上是完整的。如果要验证两个租户之间的隔离,就在tenant-a和tenant-b的路由器命名空间里分别ping对方网段的IP,预期是不可达,因为路由器没有连接对方子网,也没有任何路由表项指向对方网段。
4. 隔离落地后的精细控制:安全组、路由与QoS的参数调优
4.1 安全组的默认拒绝规则:先建基础放行,再收紧
Neutron给每个项目默认创建的安全组,规则是拒绝所有入站流量,同项目内出站不限。这个设计保证隔离优先,但也会让新创建的租户虚拟机一开机就无法互访。常见做法是先给租户建三个基础安全组:一个放行同子网内的ICMP用于故障排查,一个放行同子网内TCP端口范围,一个放行SSH端口供管理员登录。没有这些基础规则,虚拟机连上也只能干瞪眼。
命令:
# 创建安全组,指定归属租户 openstack security group create --project tenant-a sec-group-a # 放行所有入站ICMP openstack security group rule create --project tenant-a \ --protocol icmp --ingress sec-group-a # 放行TCP端口22 openstack security group rule create --project tenant-a \ --protocol tcp --dst-port 22 --ingress sec-group-a # 绑定到租户内的虚拟机端口 openstack server add security group vm-a sec-group-a逻辑说明:每次rule create只加一条规则,不要试图在一个命令里写多个端口。Neutron的安全组规则是白名单机制,入站没有匹配的规则就丢弃。绑定安全组到server端口时需要虚拟机已创建完成,所以这个动作通常在虚拟机创建后执行。
参数说明:--protocol icmp不受端口限制,--dst-port可以写单个端口或端口区间如5900:5905,--ingress表示入站方向,出站规则一般不需要额外配置。如果租户要求严格的东西向隔离,可以再建一条默认拒绝所有入站的规则放到最后,但要注意顺序,Neutron会按安全组规则列表顺序匹配。
4.2 租户间互访的三种放行方案:按审计要求选
多租户环境里“完全隔离”和“允许部分互访”经常同时存在。三种常见放行方案按隔离强度排列如下。
| 方案 | 配置复杂度 | 隔离强度 | 适用场景 |
|---|---|---|---|
| 本地Router互联 | 中 | 中 | 租户间少量网段互访 |
| 共享Router | 低 | 低 | 隔离要求低、网段少 |
| FWaaS策略 | 高 | 高 | 需要审计变更记录 |
第一种,两个租户各自有router,再额外建一对router之间的对等路由,适合租户间少量网段互通,路由表可审计,但配置量大。第二种,用同一个router连接多个租户子网,配置最简单,隔离完全依赖安全组,规则维护压力大。第三种,用FWaaS做租户间的策略边界,规则集中可控,适合对安全审计要求高的场景。
选择时除了看隔离强度,还要看运维能力。FWaaS在kolla环境下默认不一定开启,需要提前确认neutron-fwaas容器是否存在,否则策略没有执行点,规则成了摆设。多数中小环境我会优先推荐共享Router加安全组,规则清晰,排错也方便。
4.3 QoS参数:限制租户带宽时最容易忽视的burst值
租户的带宽隔离经常被忽略,直到某个租户的备份任务把出口打满。Neutron的QoS策略配置在端口或网络上,支持带宽限制和最小带宽保护。带宽限制格式看起来简单,但burst参数是最大的坑,burst设得太小会导致租户的正常大流量瞬间丢包,表现为“带宽上不去”的玄学问题。
配置命令:
# 创建QoS策略并归属租户 openstack network qos policy create --project tenant-a qos-a # 添加带宽限制规则:限制10Mbps,突发上限20Mbps openstack network qos rule create --type bandwidth-limit \ --max-kbps 10240 --max-burst-kbps 20480 qos-a # 把策略绑定到网络 openstack network set --qos-policy qos-a net-a逻辑说明:带宽限制起作用的层级在虚拟网卡上,对进出端口的流量做令牌桶整形。--max-kbps是长期平均速率,--max-burst-kbps是瞬时突发容忍量。如果设置成同值,等于零突发,TCP的burst行为会立刻撞上限制,丢包重传反而拉低实际吞吐。
参数说明:--max-burst-kbps建议设置为max-kbps的2到4倍,具体看租户业务类型,数据库同步类流量需要更大的突发。绑定到网络后,该网络下所有虚拟机端口都会继承策略,如果只想限制某几台机器,把--qos-policy绑定到port而不是network。修改策略后已绑定的端口可能需要重启虚拟机或重新插拔网卡才生效,这是Neutron的已知行为,别在变更后急着怀疑配置错了。
5. 多租户网络隔离避坑指南:5个真实翻车现场
5.1 VLAN隔离的机器一半通一半不通:物理交换机Trunk没放行
现象:租户网络用VLAN隔离,计算节点A上的虚拟机之间互访正常,计算节点B上的虚拟机之间也正常,但A和B上的虚拟机互相ping不通,控制台网络状态全部是active。
原因:VLAN隔离依赖物理交换机的Trunk放行。A节点和B节点上联的交换机,有一台在Trunk端口上没有放行这个VLAN ID,数据帧进了交换机就被丢弃。Neutron只负责把VLAN ID下发到主机网桥,管不到物理交换机。
解决:登录两台接入交换机,检查上联口和级联口的trunk allow vlan配置,把该VLAN ID加进去,同时确认交换机上VLAN已创建、Trunk口PVID正确。排错时不要先怀疑Neutron,拿一台虚拟机ping另一台的IP,同时从物理交换机上查该VLAN的MAC表项,能快速定位丢在哪一跳。
5.2 VXLAN隧道跨节点不通:UDP 4789端口被主机防火墙挡了
现象:VXLAN网络的虚拟机在同一个计算节点上互访正常,跨节点就不通,tcpdump在物理网卡上能看到出去的UDP包但收不到对端响应。
原因:VXLAN封装后的包走物理网络,默认目的端口是UDP 4789。很多服务器初始安装的防火墙规则只放行了HTTP、SSH等端口,4789不在其中。防火墙拦截发生在隧道两端的任何一段,都会导致这种假死状态。
解决:在全部计算节点和网络节点上放行UDP 4789,并确认防火墙重启后规则仍然存在:
firewall-cmd --permanent --add-port=4789/udp firewall-cmd --reload参数说明:如果底层网络用了自定义端口,neutron.conf里的dest_port可以改,放行时要对齐。有些环境还涉及iptables原始表,规则优先级高于firewalld,排查时两边都要看一眼。用nc或者telnet测UDP端口不可靠,UDP无连接特性测不出对端是否可达,不如直接在隧道网卡上抓包看VXLAN包能不能突破主机边界。
5.3 大包丢小包通:MTU不一致引发的诡异表现
现象:租户虚拟机之间64字节的ping包正常,ping -s 1472就不通,路由命名空间里也一样。流量一大数据库连接就超时,但控制台和日志一切看起来正常。
原因:VXLAN在原有以太网帧上叠加了外层IP、UDP和VXLAN头,总开销约50字节。物理链路MTU是1500的话,虚拟机里1500字节的帧封装后变成1550,超过了物理链路的承载能力,需要分片或者直接丢弃。DHCP默认下发的MTU如果是1500,虚拟机就踩在悬崖边上。
解决:要么把物理网卡和交换机端口的MTU统一调到1600,给隧道让出空间,要么在Neutron的DHCP配置里给租户网络下发MTU 1450。推荐前者,物理网卡调MTU一次到位,所有租户默认受益:
# 每台计算节点和网络节点的隧道网卡设置MTU 1600 ip link set eth2 mtu 1600参数说明:这个命令重启后失效,要写进网卡配置文件。同时确认交换机上对应端口的MTU也改了,改完检查所有虚拟机和路由器命名空间接口的MTU是否一致。MTU问题最恶心的地方在于它不影响连通性只影响大包,业务表现像是偶发的性能故障,但实际是链路层能力不足。
5.4 新租户虚拟机开机就断网:安全组默认规则把路堵死了
现象:刚创建的租户网络和虚拟机状态都是active,虚拟机能拿到IP,但ping不通同网络里的另一台机器,控制台VNC进去ping网关也不通。
原因:Neutron新建项目时自带的默认安全组只有出站允许,所有入站拒绝。同子网内的机器之间的流量也算入站,所以即使两台机器在同一个VXLAN里,也互相进不了包。这是安全组的默认设计,不是故障。
解决:建立基础安全组并放行需要的协议和端口,或者在对隔离要求不高的环境里直接修改默认安全组,加一条放行规则:
openstack security group rule create --project tenant-a \ --protocol any --ingress default逻辑说明:把默认安全组的入站策略从拒绝改成放行,显然不适合生产环境。生产落地我会建一个基础安全组,放行同子网内ICMP和常用端口,然后让租户在基础组上按需添加规则。这个配置动作要写进租户开通流程里,否则每次新项目上线都会遇到一次“开机就断网”的投诉。
5.5 Neutron服务重启后租户网络状态错乱:Agent与数据库的同步陷阱
现象:维护窗口里重启了neutron-server容器,之后控制台上部分租户网络显示active但port状态卡在down,虚拟机网络时通时断,重启虚拟机也不稳定。
原因:Neutron的port状态由各节点上的Agent上报,Agent周期性上报端口状态到数据库。如果重启期间Agent没有及时重新同步本地网桥的端口信息,数据库里的状态就和实际不符。kolla容器重启顺序不对也会放大这个问题。
解决:按正确顺序重启,先重启所有节点上的neutron-openvswitch-agent容器,再重启neutron-server,或者一起重启并等待resync完成:
docker restart neutron_openvswitch_agent docker restart neutron_server参数说明:重启后观察日志中是否有port status的同步记录,确认端口状态恢复up。如果数据库里的状态仍然错乱,可以用openstack port set --binding-profile强制刷新,但通常不需要走到这么深。这个坑的关键教训是,Neutron组件重启不能随意挑一个节点做,它是一个分布式系统,操作顺序就是一致性保障。
6. 在真实环境验证隔离效果:连通性矩阵与VXLAN抓包技巧
6.1 用ip netns直接进路由命名空间做连通性测试
从虚拟机内部ping测试容易受安全组、虚拟机网卡驱动影响,结果指向性不明确。更可靠的做法是绕开虚拟机,直接进路由命名空间测:
ip netns exec qrouter-xxxxxxxx-xxxx ping 192.168.100.10qrouter命名空间里做的正是路由器本体的转发工作,从网关侧ping租户虚拟机,能确认Neutron网络数据路径是否完整。如果网关侧通而虚拟机内部不通,问题出在虚拟机的网络栈或安全组;反之则是隧道或网桥的问题。
6.2 抓包看VNI:确认VXLAN隧道真的在跑
光看状态active还不够,抓一次包就能确认隧道数据面是否真实工作:
tcpdump -i eth2 udp port 4789 -XX抓包结果里VXLAN头的VNI字段应该和创建网络时指定的segment一致,外层源IP是源计算节点的隧道网卡IP,目标IP是目的节点。看到VNI字段正确,隔离机制的封装层面才算验完。同时把两个租户的VNI记下来,确认它们不同,这正是VXLAN隔离生效的直接证据。
验证矩阵可以直接作为项目交付的验收清单:
| 测试路径 | 预期结果 |
|---|---|
| 同租户同网络虚拟机互ping | 通 |
| 同租户跨网络经路由器互访 | 按策略通或拒绝 |
| 不同租户虚拟机互ping | 不通 |
| 虚拟机经外部网关访问外部网络 | 通 |
| 隧道物理网卡抓包VNI | 与配置一致 |
这套验证做完,多租户网络隔离才算真正落地。这些年OpenStack项目里的问题,九成不在架构设计,而是躺在隔离边界的缝里。网络隔离不像存储有清晰的磁盘边界,它散落在物理交换机、Neutron Agent、安全组和隧道协议之间。我现在接手新环境,第一件事永远是先把连通性矩阵跑完,把隔离预期写死再交付业务。这套流程不复杂,但能在上线前把大部分玄学问题变成可定位的配置项,希望帮到你。
本文还有配套的精品资源,点击获取