ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

OpenStack多租户网络隔离实战:VXLAN选型、安全组与租户编排

2026/9/19 11:45:49 拓冰建站 浏览量
OpenStack多租户网络隔离实战:VXLAN选型、安全组与租户编排 简介一份面向云计算研究人员、系统管理员及OpenStack运维技术人员的PDF技术资料系统阐述多租户网络隔离在OpenStack环境中的设计、实现与验证方法。内容从VLAN、VXLAN、GRE等二层隔离技术到三层路由与安全组策略均有展开并给出综合方案、租户创建与网络连接配置方法以及连通性测试、性能分析和异常检测等评估思路便于在真实云平台中落地参考。内容按研究背景、相关技术、方案设计、实现配置与测试评估的完整脉络展开。PDF文档为单个文件压缩包约136KB主题集中便于离线研读。已有91人学习该文档适合作为云平台网络规划、多租户安全隔离方案选型及OpenStack Neutron运维调优的实用参考。文中结合实验环境说明了虚拟网络、子网、路由器及安全策略的配置步骤并提供了实际案例和优化建议可帮助读者快速掌握从理论到实践的完整路径。1. 多租户网络隔离不能只靠建几个网络在OpenStack里做过几个生产项目后我对“多租户网络隔离”最深的体会是它不是一个开关而是一组从控制面到数据面都要对齐的约束。经常会看到两种误判一是以为建了独立网络就天然隔离二是以为安全组能挡住所有跨租户流量。实际上Neutron负责控制面真正隔离要靠VXLAN/VLAN隧道、路由命名空间和安全组在数据面共同作用。下面内容把这些环节拆开讲从二层选型、三层安全策略到租户创建、连通性测试和批量脚本适合正在做OpenStack云平台搭建与运维的工程师也适合需要给多个租户划分网络的系统管理员。2. 从VLAN到VXLANOpenStack二层隔离技术的选型边界2.1 Neutron 在二三层网络中的角色Neutron是OpenStack的网络服务控制面负责管理network、subnet、port和安全组但数据面由计算节点上的agentOpen vSwitch或LinuxBridge承担。理解这一点是排查一切隔离问题的前提你用CLI创建的网络只是数据库里的一个对象真正让租户流量隔离的是节点上的bridge、namespace、iptables和隧道端点之间的组合。一个租户网络对应一个二层广播域Neutron会给它分配一个唯一标识VLAN ID、VNI或GRE key。ML2插件负责把这种逻辑隔离映射到底层物理网络。我通常会把Neutron里的多租户隔离拆成三个层次网络的二层隔离、路由的三层隔离、安全组的四层过滤。三个层次要分别验证缺一个都可能让“隔离”流于形式。2.2 VLAN 与 VXLAN 报文结构与隔离容量VLAN在物理交换机上打标签使用12 bit的VLAN ID理论上支持4096个二层网络实际可用的VLAN数量还要受物理交换机和trunk配置限制。VXLAN则把二层帧封装进UDP默认端口4789使用24 bit的VNI作为租户标识隔离容量远大于VLAN而且物理网络只需要IP可达不需要为每个租户网络配置VLAN trunk。维度VLANVXLANGRE隔离标识12 bit VLAN ID24 bit VNI24 bit key最大隔离段4096实际更少约1600万约1600万数据封装802.1Q直接打标MAC-in-UDP/IPMAC-over-GRE/IP对物理网络要求交换机必须放行VLAN trunk只需要IP可达建议加大MTU需要IP可达且放行GRE协议典型规模中小规模、交换机可控大规模、跨区域传统网络设备兼容场景常见排错点交换机端口VLAN是否放行UDP 4789、MTU、隧道状态GRE key、隧道状态注意VLAN模式下如果物理交换机没有放行某个VLAN即使两个虚机在同一个宿主机上也可能不通。而VXLAN只要三层可达就能工作所以很多企业从VLAN切到VXLAN就是为了摆脱交换机VLAN配置的变更瓶颈。配置VXLAN类型驱动时我一般会这样处理# /etc/neutron/plugins/ml2/ml2_conf.ini [ml2] type_drivers local,flat,vlan,vxlan tenant_network_types vxlan mechanism_drivers openvswitch [ml2_type_vxlan] vni_ranges 1001:200000这段配置里type_drivers声明Neutron支持哪几种网络类型tenant_network_types决定租户创建网络时默认使用VXLANmechanism_drivers选择Open vSwitch作为数据面机制。vni_ranges是VNI分配范围我给得比较大避免后期扩容时改配置。修改完这些配置后要重启neutron-server和openvswitch agent否则创建租户网络时会直接报“network type not supported”。2.3 GRE 类型隧道的适用场景GRE在Neutron中也可以作为租户网络类型隔离标识使用GRE头里的24 bit key。它的优势是协议成熟容易与部分存量网络设备对接缺点是GRE头没有UDP源端口跨ECMP链路的负载均衡能力比VXLAN弱MTU开销也更大。配置方式与VXLAN类似[ml2] tenant_network_types gre mechanism_drivers openvswitch [ml2_type_gre] tunnel_id_ranges 1001:10000参数说明tenant_network_types改为gretunnel_id_ranges指定GRE key分配范围。GRE需要计算节点之间IP互通同时要保证GRE协议IP protocol 47没有被网络设备丢弃。我在生产环境里很少直接用GRE作为默认租户网络通常只在特定网络设备兼容性要求下才启用。2.4 选型边界与常见误用我的选型经验是租户数量少于50、物理交换机完全可控VLAN足够租户会快速增长或需要跨三层区域调度优先选择VXLAN。GRE只在设备兼容性受限时用新环境不建议。不要把VXLAN当万能MTU没调好会导致虚机访问外部网络时“小包通、大包断”。常见做法是在物理网络上开启MTU 9000的jumbo frame并把租户网络MTU设为1450或者在虚机里把网卡MTU降到1400。VXLAN头本身比普通IP头多50字节如果物理网络MTU是1500虚机侧仍用1500一旦发送接近MTU的大包就会被丢弃。提示判断是不是MTU问题用ping -M do -s 1472 ip测试。如果小包通、大包不通优先检查MTU而不是隔离规则。3. 三层网络隔离与安全组策略的落地3.1 虚拟路由器与网络命名空间隔离三层隔离的基石是Neutron router和Linux network namespace。每个router创建后L3 agent所在的网络节点上会有一个独立命名空间比如qrouter-router-id。命名空间拥有自己的路由表、iptables和接口所以即使两个租户都使用192.168.100.0/24它们被分配在不同命名空间里也不会直接冲突。这是OpenStack多租户隔离和传统“用ACL控制互访”最本质的区别。排查三层问题时我会先进入命名空间确认router接口是否存在ip netns list ip netns exec qrouter-router-id ip addr ip netns exec qrouter-router-id ip route第一条命令列出节点上所有网络命名空间其中qrouter-开头的是路由命名空间qdhcp-开头的是DHCP命名空间。后面两条分别查看router命名空间里的IP地址和路由表。发现router命名空间中没有租户子网网关地址时说明子网没有正确连接到路由器或者DHCP端口没创建这是三层排错的第一步。也别把所有三层隔离都压给router。默认关闭DVR时同一租户内不同子网间的东西向流量可能要绕到网络节点上的集中式router高带宽下容易形成瓶颈。启用DVR后计算节点上的L3 agent可以本地处理东西向和北向流量隔离边界不改变但性能改善明显。我在性能敏感环境会直接开DVR同时把计算节点的Open vSwitch和dvr_enabled配置一起验证。3.2 安全组规则实现与参数说明安全组是Neutron提供的有状态防火墙作用于每个虚机网卡所在的tap设备。“有状态”的意思是允许出去的流量它的回程流量会被自动放行不需要额外配置入方向规则。这一点经常被误解导致安全组里出现大量无效的双向规则。默认每个project有一个default安全组通常允许所有出站、拒绝所有入站所以虚机刚创建时往往无法ping通。openstack security group create --project demo_sg_project --description demo sg demo_sg openstack security group rule create --project demo_sg_project --ingress --ethertype IPv4 --protocol icmp demo_sg openstack security group rule create --project demo_sg_project --ingress --ethertype IPv4 --protocol tcp --dst-port 22 --remote-ip 0.0.0.0/0 demo_sg openstack security group rule create --project demo_sg_project --egress --ethertype IPv4 --protocol tcp --dst-port 80 --remote-ip 0.0.0.0/0 demo_sg先建一个安全组然后往里面放行入站ICMP和SSH再放行出站HTTP。--remote-ip用来限定来源或目的地址段写成0.0.0.0/0表示不限IP。注意--dst-port只在TCP/UDP规则里生效ICMP规则不需要指定端口。如果端口同时关联了default安全组入站仍然可能被拦所以最好用openstack port set --security-group demo_sg port-id显式更换安全组。3.3 FWaaS 与 RBAC权限隔离和网络隔离的边界很多人问“多租户和权限有什么区别”。在OpenStack里权限隔离由Keystone的RBAC决定控制的是“谁能管理网络、谁能用镜像”网络隔离则由Neutron的数据面机制决定控制的是“租户间流量能不能通”。设置安全组规则属于权限隔离的使用场景但安全组本身实现的却是网络访问控制。FWaaS防火墙即服务早期版本在Neutron中提供过但驱动支持一直不理想我在生产环境更倾向于用安全组加路由命名空间内的iptables完成同样的目标。功能实现位置隔离维度管理对象安全组计算节点tap设备端口级四层过滤虚机网卡FWaaS网络节点router租户边界防火墙路由器RBACKeystoneAPI权限控制project/user三者共同构成了隔离的完整画面。实际操作中我会先验证二层和三层是否真的不通再验证安全组规则是否按预期放行而不是先查RBAC。RBAC配置错误会直接导致API调用失败而网络隔离失效通常表现为延时丢包或完全不通两种故障现象完全不同。4. 多租户网络隔离的手动实现环境部署与资源配置4.1 实验环境规划与 Neutron 配置要点要从零验证隔离手把手搭一个最小OpenStack云平台通常需要两个节点控制节点和计算节点。控制节点上运行Neutron server、MySQL、RabbitMQ、Nova API、L3 agent和DHCP agent计算节点上运行nova-compute和Open vSwitch agent。如果资源有限可以用all-in-one环境先跑通流程但无法完整验证跨主机的VXLAN隧道。安装方式用packstack或devstack都可以但尽量选择带独立Neutron的Train之后的版本避免使用已经合并进Nova网络的旧架构。服务节点作用neutron-server控制节点处理API请求维护网络数据库neutron-ovs-agent计算节点实现二层转发、隧道和安全组neutron-l3-agent控制/网络节点创建router命名空间并做三层转发neutron-dhcp-agent控制/网络节点为每个租户子网分配IP这个环境下最重要的Neutron配置项是ML2插件和OVS agent的联动# /etc/neutron/plugins/ml2/ml2_conf.ini [ml2] type_drivers local,flat,vlan,vxlan tenant_network_types vxlan mechanism_drivers openvswitch [ml2_type_vxlan] vni_ranges 1001:200000 [securitygroup] enable_security_group True firewall_driver openvswitchenable_security_group开启安全组功能firewall_driver指定OVS agent使用iptables驱动确保规则落在网卡上而不是只存在于数据库。这里没有用LinuxBridge是因为OVS的流表排错和VXLAN offload支持都更成熟。修改配置后重启服务并检查agent状态systemctl restart neutron-server neutron-ovs-agent neutron-l3-agent openstack network agent list重启顺序上先启neutron-server再启agentagent会从消息队列读取新配置。network agent list输出里alive为True且admin_state_up为True才算配置就绪。如果agent显示dead优先看日志定位不要反复重启。4.2 创建租户、网络、子网与路由器的完整流程下面的命令可以在admin账号下批量创建租户A的完整网络资源。先source管理员环境变量再按顺序执行。source /root/admin-openrc.sh # 1. 创建租户项目和用户 openstack project create --domain default --description Tenant A isolation tenant_a openstack user create --project tenant_a --password TenantAPass user_a openstack role add --project tenant_a --user user_a member # 2. 创建VXLAN网络 openstack network create --project tenant_a \ --provider-network-type vxlan \ --provider-segment 10001 \ --mtu 1450 \ tenant_a_net # 3. 创建子网 openstack subnet create --project tenant_a \ --subnet-range 192.168.100.0/24 \ --gateway 192.168.100.1 \ --dns-nameserver 223.5.5.5 \ --network tenant_a_net \ tenant_a_subnet # 4. 创建路由器并把子网接入 openstack router create --project tenant_a tenant_a_router openstack router add subnet tenant_a_router tenant_a_subnet openstack router set --external-gateway public tenant_a_router第1步创建project和user把user加入project的member角色但这个角色只决定管理权限不决定网络隔离。第2步创建VXLAN网络指定VNI为10001同时把网络MTU设为1450这是避免VXLAN封装后分片的关键。第3步创建子网--gateway必须落在子网范围内--dns-nameserver建议使用可用的公共DNS或内网DNS。第4步创建router先把租户子网接入router再给router设置外部网关这样租户才能访问外部网络。参数说明--provider-segment的语义随网络类型改变vxlan下表示VNIvlan下表示VLAN IDgre下表示GRE key。分不清时会创建出预期之外类型的网络。另外--mtu 1450并非所有版本都支持若CLI不接受可在网络创建后执行openstack network set --mtu 1450。4.3 租户网络隔离策略的实施隔离策略不是一条命令而是确保每个project的网络资源归属正确、路由器不跨租户共享、网络不设shared。可以用配额硬性限制openstack quota set --project tenant_a --networks 3 --subnets 4 --routers 1 --ports 20 tenant_a配额是控制面的硬限制防止租户无限创建网络。比如给tenant_a设了3个网络、4个子网、1个路由器和20个端口一旦超过API会拒绝创建并提示Quota exceeded。端口数要结合计算节点实际网卡数量调整太小会连虚机都起不来。配额不能替代数据面隔离因为租户之间仍然可能通过router和外部网络互通所以还要确认归属关系和数据面标识openstack network show tenant_a_net | grep -E project_id|provider:network_type|provider:segmentation_id openstack network show tenant_b_net | grep -E project_id|provider:network_type|provider:segmentation_idproject_id和segmentation_id是关键。VXLAN网络要保证不同租户的segmentation_id不同如果相同说明VNI冲突流量可能串到别的租户网络。project_id不同说明网络确实属于不同项目这是权限隔离的基础。给租户创建虚机时还需要明确安全组。很多人在创建虚机时不指定安全组导致默认规则把入站全部拒绝然后误判为网络隔离问题。我会先给租户单独建安全组openstack security group create --project tenant_a --description allow ssh and icmp tenant_a_sg openstack security group rule create --project tenant_a --ingress --protocol icmp --remote-ip 0.0.0.0/0 tenant_a_sg openstack security group rule create --project tenant_a --ingress --protocol tcp --dst-port 22 --remote-ip 0.0.0.0/0 tenant_a_sg给tenant_a单独建一个安全组而不是用默认的default是因为默认规则会随版本变化。明确放行ICMP和SSH之后后续连通性测试才不会被安全组干扰。如果测试跨租户隔离这条规则应该只加在租户A的安全组上租户B的安全组保持默认拒绝入站。4.4 在租户网络内启动虚机有了网络和安全组之后启动虚机就很简单openstack image list openstack flavor list openstack server create --flavor m1.small \ --image cirros-0.6.2-x86_64 \ --network tenant_a_net \ --security-group tenant_a_sg \ vm-a这里把--network指向了租户A的VXLAN网络--security-group指定了刚建的安全组。虚机启动后可以看openstack server show vm-a的状态如果一直ERROR通常是flavor内存不足或镜像不可用。控制台登录可以先用openstack console url show vm-a抓VNC地址再进去手动配置IP或确认DHCP分配。5. 隔离效果测试与异常排查连通性、性能与故障模拟5.1 租户间连通性测试方法验证隔离是否生效最直接的是做一组“相同租户互通、跨租户隔离”的测试矩阵。我一般会在租户A内起两个虚机vm-a1、vm-a2租户B内起vm-b1分别记录它们的IP然后用ping和nc测试。测试动作期望结果验证点vm-a1 ping vm-a2通同一租户二层网络转发正常vm-a1 ping vm-b1不通租户间VXLAN/VLAN隔离生效vm-b1 ping vm-a1不通双向均隔离vm-a1 ping 外部网关通需要router南北向路由正常外部PC ping vm-a1 Floating IP按安全组规则决定入站访问受安全组控制注意ping不通时不要急着声称“隔离生效”。第一种可能是安全组默认规则阻止了ICMP第二种可能是MTU问题导致大包不通小包通第三种才是二层隔离起效。标准做法是先看安全组规则里有没有放行ICMP再用openstack port show确认端口关联的安全组最后再确认跨租户的包是否真的走到了同一个bridge。只有排除应用层和配置层因素后才能把“不通”归因于隔离机制。5.2 网络流量监控与性能评估隔离方案不能只看通不通还要看性能损耗。VXLAN的封装开销在万兆环境下比较明显。评估时我最常用的工具是iperf3在租户内两个虚机之间跑TCP流# 在 vm-a2 上启动服务端 iperf3 -s -p 5201 # 在 vm-a1 上发起测试 iperf3 -c 192.168.100.20 -t 30 -P 4-t 30控制测试时长-P 4开4个并行流避免单流打不满。如果测出来带宽和物理网卡差异过大先看物理网卡是否有fcs或drop计数再用ovs-vsctl show看隧道端口是否UP。iperf测试本身会放大CPU消耗在低配虚机上不要开过高的P值否则结果不可信。流量监控也可以配合ovs-ofctl dump-flows br-int看流表计数n_packets/n_bytes一直没有增长说明流量没走到对应路径。5.3 异常状态检测与排查部署后常遇到的异常包括DHCP不分配IP、租户网络创建失败、跨主机VXLAN不通、安全组规则不生效。典型排错路径是先控制面后数据面# 检查agent状态 openstack network agent list # 检查DHCP端口和命名空间 openstack port list --device-owner network:dhcp ip netns exec qdhcp-network-id ip addr # 检查OVS流表 ovs-vsctl show ovs-ofctl dump-flows br-int | grep -i nw_dst192.168.100.0network agent list看agent是否alive这是控制面是否健康的第一步。port list --device-owner network:dhcp能看到DHCP端口是否存在不存在说明DHCP agent没有为该网络创建端口。OVS流表里查nw_dst可以确认虚机流量是否被正确转发流表里完全没有192.168.100.0/24相关条目说明发到网络段的数据包在隧道口就丢了。异常现象可能原因处理动作虚机无法获取IPDHCP agent未启动或端口冲突重启neutron-dhcp-agent检查qdhcp命名空间同一宿主机内同租户不通安全组默认规则未放行放行ICMP或绑定自定义安全组跨宿主机不通VXLAN隧道未建立或MTU问题检查隧道口、UDP 4789连通性和MTU跨租户竟然能通共享网络或router外部网关错配检查network的shared属性和router归属注意排错时要区分“不隔离”和“不通”。跨租户不通是正确行为跨租户能通才需要紧张通常意味着某个子网被错误地设为shared或者两个租户的路由器被连到了同一个外部网络且错配了CIDR。最后再用一条命令确认二层隔离是否真的失效在两个租户的虚机里分别执行ip neigh如果出现对方的MAC说明二层隔离已经失效。6. 把隔离配置固化为批量建租户的 CLI 脚本6.1 脚本设计与使用边界手动执行前面一长串命令能帮助理解但交付生产环境时手工操作容易漏参数、错打project。我最终会把整个流程固化成脚本一个租户跑一次输出校验结果。下面是简化版本#!/usr/bin/env bash set -euo pipefail ADMIN_RC${ADMIN_RC:-/root/admin-openrc.sh} source $ADMIN_RC PROJECT_NAME${1:?Usage: $0 project_name [cidr] [gateway]} CIDR${2:-192.168.100.0/24} GATEWAY${3:-192.168.100.1} openstack project create --domain default $PROJECT_NAME /dev/null openstack network create --project $PROJECT_NAME \ --provider-network-type vxlan \ --provider-segment $(( RANDOM % 100000 10001 )) \ --mtu 1450 \ ${PROJECT_NAME}_net /dev/null openstack subnet create --project $PROJECT_NAME \ --subnet-range $CIDR \ --gateway $GATEWAY \ --dns-nameserver 223.5.5.5 \ --network ${PROJECT_NAME}_net \ ${PROJECT_NAME}_subnet /dev/null openstack router create --project $PROJECT_NAME ${PROJECT_NAME}_router /dev/null openstack router add subnet ${PROJECT_NAME}_router ${PROJECT_NAME}_subnet echo Tenant $PROJECT_NAME ready: $CIDR脚本第一步用set -euo pipefail保证任何一条命令失败就退出避免留下半配置的项目。source导入admin凭证$(( RANDOM % 100000 10001 ))随机挑选一个VNI作为演示生产环境应改为从已有的IPAM系统获取避免VNI冲突。--mtu 1450是VXLAN环境防分片的关键参数。脚本最后会打印租户的CIDR方便录入资产信息。这个脚本只是个起点实际使用还要添加租户配额、安全组、DHCP检查、失败回滚和日志记录。一个更稳妥的做法是使用OpenStack Heat模板把项目、网络、子网、路由器和安全组定义在YAML stack里然后通过openstack stack create一次创建失败时自动回滚。如果不想引入Heat可以在脚本里写trap清理已经创建的neutron资源捕获异常后删除新建的项目和网络。把这些动作封装成函数后新租户开通时间可以从十几分钟手工操作降到一条命令。本文还有配套的精品资源点击获取