
简介这份PDF文档面向云计算研究人员、系统管理员及OpenStack开发运维人员聚焦多租户环境下云平台网络隔离的规划部署与安全稳定性问题。内容从OpenStack架构与Neutron、Nova等关键组件切入系统梳理VLAN、VXLAN、GRE等二层隔离技术及路由隔离、安全组策略等三层方案并提出多租户网络隔离的综合设计。文档进一步展开网络资源配置管理、租户创建与网络连接、访问控制与数据加密等安全策略实现并通过租户间连通性测试、安全策略验证、流量性能分析与异常排查评估方案有效性。资源包为1个PDF文件约136KB结构完整、章节清晰涵盖绪论、技术基础、隔离设计、实现配置、测试评估与总结展望便于按模块检索学习。目前已有92人学习适合需要掌握多租户网络隔离原理与落地实践的读者参考。1. OpenStack 多租户网络隔离从“能通”到“该不该通”的那道墙很多团队第一次把 OpenStack 跑起来虚拟机互相 ping 得通就觉得网络这块已经过关了。真正出事往往是在第二个租户进来之后——A 项目的机器能摸到 B 项目的数据库或者两个部门共用一条物理链路广播风暴互相拖垮。这时候你才会意识到OpenStack 多租户网络隔离不是“配个 IP 能上网”那么简单它要回答的是一个更硬的问题同一套物理资源上怎么让不同租户的流量在逻辑上彻底分家同时还能各自灵活地定义自己的网段、网关和访问策略。这篇笔记面向的是正在用 OpenStack 做私有云或行业云的工程师尤其是那些已经用 Packstack 或类似方式搭起环境、准备把业务真正迁进去的人。我会把多租户隔离拆成“底层靠什么分家、控制面怎么下发、数据面怎么落地、出问题怎么查”这几段来讲中间给到能直接抄的命令和配置也会把我在 VLAN 划分和 ACL 配置上翻过的车一并写出来。读完你应该能判断自己的环境该选哪种隔离方案以及怎么把它调通、调稳。2. 多租户隔离的底层逻辑从 VLAN 到 VXLAN 的选型账2.1 隔离的本质是给流量打上“身份标签”OpenStack 里的租户对应 Keystone 里的 project网络对应 Neutron 里的 network。所谓隔离就是让属于 project-A 的包永远不会被 project-B 的虚拟机收到哪怕它们跑在同一台计算节点、同一块网卡上。实现这件事的核心手段是给每个租户网络分配一个全局唯一的“分段标识”数据包进出虚拟机时被打上这个标识转发设备只把带相同标识的包送到同一个逻辑网络里。在 Linux 网桥和 Open vSwitch 的世界里这个标识就是 VLAN ID 或者 VXLAN 的 VNI。VLAN 走的是 802.1Q 标签最多 4094 个可用值适合租户数量可控、物理网络设备支持 VLAN 转发的场景。VXLAN 把二层帧封装进 UDP 里VNI 有 1600 万个适合租户多、跨三层物理网络的环境。选哪个不是拍脑袋得看你的物理交换机支不支持 VXLAN 终结以及运维团队对 overlay 网络的接受程度。我一般会先问三个问题租户数量会不会超过 200物理网络是不是已经做了 spine-leaf 且支持 EVPN运维能不能接受在 underlay 之上再叠一层 overlay如果租户少、物理网络可控VLAN 方案排错直观抓包就能看到标签如果租户多、跨机房VXLAN 几乎是唯一选择。混合场景也常见——核心用 VXLAN边缘某些老设备只认 VLAN那就得在边界做映射。2.2 用 Packstack 搭一套能验证隔离的最小环境要验证隔离先得有个能跑的环境。基于 Packstack 安装 OpenStack 是最快的路径适合做隔离实验。下面这套命令我在一台 16 核 32G、双网卡的 CentOS Stream 9 上跑通过网卡分别是 ens33管理/外部和 ens34租户隧道。# 关闭 NetworkManagerOpenStack 网络需要自己管网桥 systemctl disable --now NetworkManager systemctl enable --now network # 安装 Packstack 仓库 dnf install -y centos-release-openstack-yoga dnf update -y dnf install -y openstack-packstack # 生成应答文件只启用必要组件减少干扰 packstack --gen-answer-fileanswer.txt # 关键参数启用 Neutron、ML2、OVS、VXLAN禁用不需要的服务 sed -i s/^CONFIG_NEUTRON_ML2_TYPE_DRIVERS.*/CONFIG_NEUTRON_ML2_TYPE_DRIVERSvxlan,vlan,flat/ answer.txt sed -i s/^CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES.*/CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPESvxlan/ answer.txt sed -i s/^CONFIG_NEUTRON_OVS_TENANT_NETWORK_TYPES.*/CONFIG_NEUTRON_OVS_TENANT_NETWORK_TYPESvxlan/ answer.txt sed -i s/^CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS.*/CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGSextnet:br-ex/ answer.txt sed -i s/^CONFIG_NEUTRON_OVS_BRIDGE_IFACES.*/CONFIG_NEUTRON_OVS_BRIDGE_IFACESbr-ex:ens33/ answer.txt sed -i s/^CONFIG_NEUTRON_OVS_TUNNEL_IF.*/CONFIG_NEUTRON_OVS_TUNNEL_IFens34/ answer.txt # 开始安装时间取决于网络 packstack --answer-fileanswer.txt这段脚本做了几件事先把网络管理权从 NetworkManager 手里拿回来避免它和 OVS 抢网卡然后指定 ML2 驱动支持 vxlan、vlan、flat 三种类型但租户网络默认只用 vxlan最后把 br-ex 绑到 ens33 做外部网络ens34 专门跑 VXLAN 隧道。参数里CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES决定了普通租户创建网络时能选什么类型设成 vxlan 就意味着租户网络默认走 overlay不会去抢物理 VLAN。安装完成后用source keystonerc_admin加载管理员凭证然后openstack network agent list确认 Neutron 的 OVS agent、DHCP agent、Metadata agent 都是 up。如果 OVS agent 是 down多半是隧道网卡没配通或者 OVS 服务没起来先看/var/log/neutron/openvswitch-agent.log。2.3 创建两个租户网络验证默认隔离环境好了直接建两个租户、两个网络各起一台虚拟机看它们能不能通。这是最直接的隔离验证。# 创建两个项目 openstack project create --domain default tenant_a openstack project create --domain default tenant_b # 创建两个用户并绑定项目略去密码设置细节 openstack user create --domain default --project tenant_a --password A_Pass123 user_a openstack user create --domain default --project tenant_b --password B_Pass123 user_b # 管理员分别以两个项目身份创建网络和子网 # 租户 A 的网络 openstack --os-project-name tenant_a network create net_a openstack --os-project-name tenant_a subnet create --network net_a \ --subnet-range 10.10.1.0/24 --gateway 10.10.1.1 --dhcp sub_a # 租户 B 的网络 openstack --os-project-name tenant_b network create net_b openstack --os-project-name tenant_b subnet create --network net_b \ --subnet-range 10.10.2.0/24 --gateway 10.10.2.1 --dhcp sub_b创建完用openstack network list能看到两个网络但注意看它们的 ID 和 Segmentation ID。VXLAN 网络会分配不同的 VNI这个 VNI 就是隔离的根。租户 A 的虚拟机拿到 10.10.1.x租户 B 拿到 10.10.2.x即使两台虚拟机在同一台计算节点上它们的流量也会被 OVS 流表根据 VNI 分开。默认情况下不同租户网络之间没有任何路由ping 不通是预期结果。如果你发现能通先查是不是有人手动加了路由或者安全组放得太宽。3. 把隔离落到配置VLAN 划分与 ACL 的具体写法3.1 VLAN 模式下怎么划段和绑物理网卡有些场景必须用 VLAN比如租户要求网络流量直接走物理交换机做策略或者对接的硬件防火墙只认 VLAN 标签。这时候要在 Neutron 里配置 VLAN 类型的租户网络并把物理网卡桥接到 OVS 上。先确认 ML2 配置里允许 vlan 类型并且network_vlan_ranges定义了可用的 VLAN 区间。编辑/etc/neutron/plugins/ml2/ml2_conf.ini[ml2] type_drivers vlan,vxlan,flat tenant_network_types vlan mechanism_drivers openvswitch [ml2_type_vlan] network_vlan_ranges physnet1:100:200这里physnet1:100:200表示物理网络 physnet1 上可用的 VLAN ID 是 100 到 200。然后配置 OVS agent 的桥接映射把 physnet1 绑到一块物理网卡或网桥[ovs] bridge_mappings physnet1:br-eth1重启 neutron-openvswitch-agent 后创建网络时指定--provider:physical_network physnet1 --provider:network_type vlanNeutron 会自动从 100-200 里分配一个 VLAN ID。不同租户拿到不同 VLAN ID物理交换机上只要保证这些 VLAN 不互通隔离就成立。注意VLAN ID 是全局资源分配出去后不会自动回收删网络时要确认 VLAN 是否释放否则区间会被慢慢耗尽。3.2 用安全组做租户内的微隔离租户之间隔离靠 VNI 或 VLAN租户内部不同虚拟机之间要不要隔离靠安全组。安全组是带状态的防火墙规则默认拒绝所有入站、允许所有出站。很多人的翻车点在于为了让服务通直接加一条0.0.0.0/0放行所有端口结果租户内一台机器被攻破横向就能摸到同租户所有机器。更细的做法是按角色建安全组。比如 Web 层只开 80/443DB 层只允许来自 Web 安全组的 3306。# 创建 web 和 db 两个安全组 openstack security group create web_sg openstack security group create db_sg # web 组放行 80/443 入站 openstack security group rule create --proto tcp --dst-port 80 web_sg openstack security group rule create --proto tcp --dst-port 443 web_sg # db 组只允许来自 web_sg 的 3306 openstack security group rule create --proto tcp --dst-port 3306 \ --remote-group web_sg db_sg--remote-group是关键它让规则基于安全组 ID 而不是 IP 段虚拟机迁移或重建后 IP 变了也不用改规则。安全组规则最终会被 Neutron 转成 OVS 流表或 iptables 规则落在计算节点的 br-int 上。如果你发现规则不生效先openstack security group rule list确认规则存在再去计算节点ovs-ofctl dump-flows br-int看流表里有没有对应的 drop 或 allow。3.3 用 ACL 做跨租户的受控互通完全隔离有时太死业务需要租户 A 的某台机器访问租户 B 的一个 API。这时候不能把两个网络打通而是用路由器加 ACL 做受控路径。OpenStack 里可以用 Neutron 的 router 把两个租户网络连起来然后在 router 上做策略或者用第三方防火墙。常见做法是创建一个共享网络或使用“外部网络 浮动 IP”的方式让需要互通的机器各挂一个浮动 IP再在物理防火墙或安全组上限制源和目的。更干净的方式是用 Neutron 的rbac功能把某个网络共享给另一个租户但共享的是整个网络粒度太粗。细粒度控制还是得靠安全组引用或者防火墙即服务FWaaS。# 创建一个路由器连接两个租户的子网 openstack router create shared_router openstack router add subnet shared_router sub_a openstack router add subnet shared_router sub_b # 此时两个子网路由可达但默认安全组仍然拒绝入站 # 在 tenant_b 的 db_sg 里放行来自 tenant_a 特定网段的 3306 openstack security group rule create --proto tcp --dst-port 3306 \ --remote-ip 10.10.1.0/24 db_sg这样流量路径是tenant_a 的虚拟机 - 路由器 - tenant_b 的虚拟机安全组在目的端做最后一道过滤。路由器的存在打破了网络层的完全隔离所以必须配合安全组或 FWaaS 把该拦的拦掉。我一般会在路由器上再加一条策略只允许特定源 IP 访问特定端口其他一律 drop。4. 隔离失效的排查从流表到日志的定位路径4.1 先确认隔离到底有没有生效怀疑隔离失效时不要急着改配置先做三个检查。第一openstack network list --long看两个网络的 Segmentation ID 是否不同如果相同说明创建时指定了同一个 VLAN 或 VNI隔离从根上就不成立。第二在计算节点上ovs-vsctl show看 br-int 和 br-tun 的端口配置确认隧道端口和 patch 端口都在。第三ovs-ofctl dump-flows br-tun看 VXLAN 的 tun_id 匹配规则不同 VNI 的流表应该是分开的。如果两个虚拟机在不同计算节点还要确认隧道网卡互通。ping隧道 IPtcpdump -i ens34 vxlan抓包看有没有封装流量。隧道不通跨节点隔离就变成“都不通”业务会报故障但这不是隔离问题是底层网络问题。4.2 安全组规则不生效的常见原因安全组规则写了但没起作用我遇到过几种。一种是规则加了但虚拟机没重启或没重新获取端口Neutron 的端口安全组绑定有延迟openstack port show看security_group_ids是否包含预期安全组。另一种是计算节点上neutron-openvswitch-agent没 reload流表还是旧的重启 agent 后规则才下发。还有一种是虚拟机内部自己开了 iptables 或 firewalld把 Neutron 下发的规则覆盖了这时候要进虚拟机iptables -L看。提示排查安全组时先在计算节点ovs-ofctl dump-flows br-int | grep 虚拟机 IP看有没有对应的 drop 流。如果有 drop 但规则应该是 allow检查规则优先级和方向。4.3 用 tcpdump 和 ovs-tcpdump 抓隔离流量抓包是终极手段。在计算节点上tcpdump -i br-int -n能看到虚拟机进出的原始包但 br-int 上流量已经打了 tag直接看可能分不清租户。用ovs-tcpdump -i qvoport-id可以抓某个具体端口的流量这个端口对应一台虚拟机的 vif。先openstack port list找到虚拟机的 port id再在计算节点ovs-vsctl get Interface qvoport-id ofport确认端口存在然后ovs-tcpdump -i qvoport-id -w /tmp/vm.pcap抓包。抓到包后看源和目的 MAC、IP以及有没有 VLAN tag 或 VXLAN 外层。如果本该隔离的两个虚拟机之间抓到了对方的包顺着包的方向查流表看是哪条规则放行了。常见的是有人手动加了ovs-ofctl add-flow的静态流或者安全组里有一条过宽的remote_ip。5. 避坑与常见问题隔离方案落地时的五个血泪教训现象两个租户虚拟机默认就能 ping 通。原因创建网络时用了同一个 VLAN ID或者管理员把两个子网挂到了同一个路由器且安全组默认放行。更隐蔽的是ML2 配置里tenant_network_types设成了 flat所有租户网络都走同一个物理网络根本没有隔离。 解决检查openstack network show的provider:segmentation_id确保不同租户网络不同。检查 ML2 的tenant_network_types租户网络不要用 flat。路由器连接子网后安全组必须显式放行默认拒绝入站。现象VXLAN 网络跨计算节点不通同节点通。原因隧道网卡没配通或者 MTU 没调。VXLAN 封装会增加 50 字节开销物理网卡 MTU 如果是 1500虚拟机里 MTU 还是 1500大包就会被丢。 解决确认隧道 IP 互通ping -M do -s 1450 对端隧道IP测试 MTU。把 Neutron 的global_physnet_mtu和物理网卡 MTU 设成一致虚拟机内 DHCP 下发的 MTU 也要相应调小通常设 1450。现象安全组规则加了但虚拟机还是能访问不该访问的端口。原因虚拟机内部 firewalld 没关或者 Neutron 的端口安全被禁用port_security_enabledFalse导致安全组不生效。也可能是规则方向搞反了入站规则写成了出站。 解决openstack port show看port_security_enabled是否为 True。进虚拟机systemctl stop firewalld临时验证。规则创建时确认--ingress还是--egress默认是 ingress。现象VLAN 区间耗尽新网络创建失败。原因删除网络时 VLAN ID 没有正确释放或者network_vlan_ranges设得太小。Neutron 的 VLAN 分配是持久化在数据库里的异常删除可能留下残留记录。 解决openstack network list --long找出已用的 VLAN和数据库neutron.ml2_vlan_allocations表对照。清理残留记录前先确认没有活跃网络在用。扩大network_vlan_ranges需要重启 Neutron 服务。现象修改 ML2 配置后重启服务网络全断。原因改了type_drivers或tenant_network_types后已有网络的类型可能不再被支持Neutron 启动时加载失败或者 OVS agent 无法同步流表。 解决改配置前先备份/etc/neutron改完后systemctl restart neutron-server neutron-openvswitch-agent然后openstack network agent list确认 agent 恢复 up。如果已有网络类型和新配置冲突需要先迁移或删除旧网络。生产环境改这些参数一定要在维护窗口做。6. 进阶用地址范围和 RBAC 把隔离做得更细默认的租户隔离是“项目级”的同一个项目内所有网络默认互通。但有些场景需要项目内再分环境比如生产、测试、开发在同一个 project 下但网络必须隔离。这时候可以用 Neutron 的 address scope 和 subnet pool 来做更细的划分。Address scope 允许你定义一组不重叠的地址范围不同 scope 之间的子网默认不能互通即使它们在同一个项目里。创建两个 address scope分别给生产和测试用# 创建两个 address scope openstack address scope create --ip-version 4 prod_scope openstack address scope create --ip-version 4 test_scope # 创建 subnet pool 并绑定 scope openstack subnet pool create --pool-prefix 10.20.0.0/16 \ --address-scope prod_scope prod_pool openstack subnet pool create --pool-prefix 10.30.0.0/16 \ --address-scope test_scope test_pool # 创建网络时指定 subnet pool子网自动从对应 scope 分配 openstack network create prod_net openstack subnet create --network prod_net --subnet-pool prod_pool \ --prefix-length 24 prod_sub这样 prod_sub 和 test_sub 即使都在同一个 project 下默认也不互通因为 address scope 不同。要互通必须显式创建路由器并配置路由这就给了你一个受控的入口。另一个进阶手段是 Neutron RBAC。默认网络只对所属项目可见但你可以把某个网络共享给另一个项目同时只给access_as_shared权限。这适合跨租户提供公共服务比如一个共享的镜像仓库网络。RBAC 的粒度是网络级不能精确到端口所以共享后还是要靠安全组控制访问。# 把 tenant_a 的网络共享给 tenant_b openstack network rbac create --target-project tenant_b \ --action access_as_shared net_a共享后 tenant_b 能看到 net_a 并直接在上面起虚拟机但能不能访问 net_a 里的其他机器仍然由安全组决定。我一般会配合端口安全一起用共享网络里的端口默认开启 port security防止 MAC 和 IP 欺骗。最后说一个验证隔离是否真的生效的习惯每次改完网络配置不要只看openstack network list一定要起两台最小虚拟机一台在租户 A一台在租户 B互相 ping 和 telnet 目标端口确认该通的通、不该通的不通。这个动作花不了十分钟但能挡住后面百分之八十的“以为隔离了其实没有”的事故。希望帮到你。本文还有配套的精品资源点击获取