云多租户网络隔离全景:从 Hypervisor 到 VNI,一层层看懂租户是怎么被隔开的

多租户是云计算的立身之本——成千上万个互不信任的租户共享同一批物理机、同一批交换机、同一批存储盘,却要求彼此"看不见、摸不着"。这篇文章从计算、网络、数据、管理面四个维度拆解隔离体系,然后聚焦最核心也最容易被误解的一环:VPC 逻辑隔离为什么真的能隔离。我们会用一个"故意撞 IP、故意共宿主机"的例子逐跳追踪报文,再回答两个高频疑问:subnet 能不能做租户隔离?subnet 在路由表和交换机里的真实拓扑长什么样?


一、多租户隔离体系总览

隔离的本质命题是:在共享物理资源的前提下,为每个租户构建一个"逻辑上独立、必要时可物理隔离"的运行环境,同时兼顾安全性与资源利用率。

不同云服务模型的隔离锚点不同:IaaS 靠 Hypervisor 和网络虚拟化,PaaS 靠容器沙箱与命名空间,SaaS 靠应用层的 Tenant-ID 与数据权限策略。

隔离维度 共享程度 核心实现机制 典型技术/产品
计算隔离 共享硬件,独立内核 Hypervisor 虚拟机、安全容器、机密计算 KVM/Xen、Kata Containers、Firecracker、gVisor、AMD SEV/Intel TDX/SGX
网络隔离 共享物理网络,独立逻辑网络 VPC + VXLAN Overlay、安全组、网络 ACL VPC、VNI(24 位标识,约 1600 万租户)
存储隔离 共享存储池,独立卷/桶 计算存储分离、QoS 限速、数据擦除、透明加密 云硬盘、对象存储 Bucket、KMS
数据隔离 共享实例/表,逻辑分片 独立实例 / 独立 Schema / 共享表+RLS PostgreSQL RLS、tenant_id 过滤
管理面隔离 共享控制平面 IAM 多账户、最小权限、审计日志 RBAC/ABAC、CloudTrail、操作审计

1.1 计算隔离:从 Hypervisor 到机密计算

计算隔离的核心是让租户的工作负载无法访问彼此的内存与 CPU 资源,实现强度由弱到强分三档:

Hypervisor 虚拟机隔离(IaaS 主流):每个租户运行在独立 VM 中,由 KVM/Xen 等虚拟化管理程序在硬件层面做地址空间隔离。云厂商还会配合虚拟机布局算法防止恶意租户"探测"自身所在物理机,并对虚拟化层做热补丁修复和逃逸检测。

容器/沙箱隔离(PaaS 主流):通过 Linux namespaces + cgroups 做轻量隔离,多个租户共享宿主机内核,隔离强度依赖内核安全性。为弥补共享内核的风险,业界引入了三类增强方案:

  • gVisor:用户态拦截 syscall,开销约 45MB 内存、启动约 85ms;
  • Kata Containers:每个 Pod 运行在独立轻量 VM 中,具备完整内核隔离,适合多租户不可信代码与金融/政务场景;
  • Firecracker microVM:AWS Lambda/Fargate 采用的极致轻量 VMM,启动 <125ms、内存约 28MB,禁用多余设备模拟,攻击面最小。

机密计算隔离(高合规场景):基于 CPU TEE(AMD SEV-ES、Intel SGX/TDX)对租户内存做硬件加密,连云厂商的 Hypervisor 和管理员都无法窥视运行中的数据。

1.2 网络隔离:VPC + VXLAN Overlay

网络隔离的核心思想是:在共享的物理网络上,通过 Overlay 封装为每个租户构建专属的虚拟网络,让租户之间的流量在二/三层都无法互通。

  • VPC 逻辑隔离:每个租户分配独立 VPC,拥有自定义 CIDR 网段、子网、路由表,不同 VPC 之间默认完全隔离,互访必须通过显式的对等连接、专线或 VPN;
  • VXLAN 封装实现多租户标识:传统 VLAN 只有 12 位标签(4094 个),无法满足大规模多租户;VXLAN 在原始以太网帧外新增 8 字节头部(含 24 位 VNI),理论支持 2²⁴ ≈ 1600 万个租户网络;
  • 安全组与网络 ACL:作为 VPC 内的 L4 状态防火墙,安全组以 ENI 为对象控制实例级出入流量,网络 ACL 以子网为对象做无状态访问控制,两者组合实现细粒度"微分段";
  • 网络加密(可选):高合规租户可开启 VPC 内加密,计算节点与网关之间的流量全程加密,对云厂商也保持不透明。

1.3 存储与数据隔离

存储层隔离有两个目标:性能上防"吵闹邻居",安全上防数据越权访问。

  • 存储卷隔离:计算与存储分离架构下,虚拟机只能访问分配给它的磁盘空间;实例释放时对原存储介质做可靠的数据擦除,防止跨租户数据残留;
  • QoS 性能隔离:对云硬盘、对象存储 Bucket、消息队列等设置每租户的 IOPS/吞吐/QPS 上限;
  • 数据加密隔离:通过 KMS 为每个租户分配独立密钥(BYOK),对静态数据做服务端透明加密;部分高安全方案甚至实现"加密隔离"——即使集群管理员也无法解密租户数据;

SaaS 数据隔离的三种模式(应用层最关键的选型问题):

模式 隔离性 成本 适用规模
独立实例(一租户一 DB 实例) 最高(物理/进程级) 最高 <50 租户,金融/政务
独立 Schema(一租户一库) 高(逻辑库级) 中等 50–500 租户
共享库 + tenant_id + RLS 依赖应用层 + 行级策略 最低 500+ 租户

共享表方案最大的风险是应用层 SQL 漏写 WHERE 条件导致串数据,因此推荐把访问控制下沉到数据库引擎层的行级安全(PostgreSQL RLS):在查询执行器阶段自动为每条 SQL 注入租户过滤条件,即使绕过应用直连数据库也不会泄露跨租户数据。

1.4 管理面隔离

共享的控制平面是横向渗透的高危路径:

  • 身份与权限隔离:每个租户对应独立 IAM 账户体系,通过 RBAC/ABAC 实现最小权限;所有 API 请求必须携带合法 TenantID,在接口权限、数据权限、操作权限三层做分层校验;
  • 物理运维通道隔离:云厂商内部运维通过堡垒机 + 多因素认证进入生产网,与租户网络完全隔离;
  • 审计与溯源:全量记录租户操作日志与控制面调用日志,通过 eBPF tracepoint 等手段做零侵入式审计;
  • 元数据隔离(SaaS 层):Salesforce 等多租户 SaaS 通过租户专属 metadata 实现功能差异化,避免代码分叉。

1.5 选型原则

隔离方案的选择本质是合规强度、性能隔离需求与成本三者之间的权衡:

  • 金融、政务、医疗等强合规行业倾向于"物理/加密隔离"路线:裸金属、独立 VPC、独立 DB 实例、机密计算、专属 KMS——用较高成本换取清晰的责任边界与审计路径;
  • 互联网 SaaS、AI 推理平台等规模型业务倾向于"逻辑隔离"路线:共享硬件 + Kata 安全容器 + 共享表 + RLS + 严格的配额与审计——通过把隔离机制从"人肉纪律"升级为"平台强制"来取得平衡。

二、VPC 逻辑隔离为什么就能隔离租户网络?

"逻辑隔离"听起来很虚:明明所有租户的报文都在同一批交换机、同一批光纤上跑,为什么 A 租户的虚拟机就"够不着"B 租户的虚拟机?

关键在于:物理网络搬运的从来不是租户的原始报文,而是被封装后打了租户标签的"包裹",而解封、转发、隔离的决策全部发生在宿主机的虚拟交换机上。

2.1 物理网络上跑的到底是什么

假设租户 A 的 VM1(10.0.0.5)要 ping 租户 B 的 VM2(192.168.1.5),报文离开 VM 后的第一站不是物理交换机,而是宿主机上的 vSwitch(虚拟交换机,如 OVS)。vSwitch 会做一件事:

1
2
3
4
5
6
7
8
原始报文(租户 A 的 VM 发出,源 10.0.0.5 → 目的 B 的 IP)
↓ vSwitch 判断:目的 MAC 不在本机,需要跨宿主机转发
↓ 查表:VM1 属于 VNI=100(租户 A 的网络标识)
↓ VXLAN 封装:
外层以太网头(宿主机物理网卡的 MAC)
外层 IP 头(源=本宿主机,目的=远端宿主机) ← 物理网络只认识这个
UDP 4789 端口 + VXLAN 头(VNI=100)
内层:租户 A 的原始报文(源 10.0.0.5 → ...)

物理交换机看到的是"宿主机 → 宿主机"的普通 UDP 流量,它根本不知道、也不需要知道里面装的是哪个租户的包。物理网络(underlay)只负责把包裹送到正确的宿主机,租户网络(overlay)的寻址、隔离都在两端解封装时完成。

2.2 隔离真正发生的三个关卡

关卡 1:VM 入网时的"门禁"——端口绑定 VNI

每台 VM 的虚拟网卡接入 vSwitch 时,云平台控制面就已经把这条端口和一个 VNI 绑死了。这个绑定是平台下发的,租户无法修改。VM 就算被完全攻破、root 权限拿到手,它发出的报文进入 vSwitch 时仍会被强制打上 VNI=100 的标签——租户没有"冒充别的租户"的通道

关卡 2:vSwitch 转发时的"查无此路"

隔离的核心机制其实简单到只有一句话:vSwitch 的转发表里,不同 VNI 是完全独立的命名空间,转发查询永远在同一个 VNI 内进行。

  • 目的 MAC 在本机、同 VNI → 本地二层直接交付;
  • 目的 MAC 不在本机、同 VNI → 封装 VXLAN,发给目标宿主机的 VTEP;
  • 目的 MAC/IP 不在本 VNI 的表里 → 直接丢弃。

A 租户的 VM 发往 B 租户 IP 的报文,在 VNI=100 的转发表里查不到任何匹配项——不是因为"禁止",而是因为"根本不存在这条路由"

关卡 3:跨 VNI 通信必须过网关

如果两个租户确实需要通信,报文必须送到分布式网关/VPC Router。网关是唯一"能看见多个 VNI"的组件;是否放行,取决于控制面有没有下发对等连接、专线、VPN 等显式规则;默认没有规则 = 默认拒绝。

所以隔离模型是:数据面(vSwitch)无差别执行"VNI 之间不通",控制面(SDN 控制器)显式开通例外。

2.3 容易被忽略但同样关键的旁路封堵

机制 防的是什么
MAC/IP 反欺骗 租户在 VM 里把 IP 改成 B 租户的 IP 冒名访问;vSwitch 校验源 MAC/IP 与端口绑定不一致即丢弃
ARP 域收窄 ARP 请求只在同 VNI 内广播/代答,A 租户永远 ARP 不出 B 租户的 MAC
隔离的默认路由表 每个 VPC 有独立虚拟路由表,B 租户的网段在 A 的路由表里压根不存在
网关上的安全组/ACL 即使开通了对等连接,流量还要过状态防火墙
VTEP 白名单 防止恶意租户伪造外层 IP 直接注入伪造 VNI 的报文

2.4 一句话总结隔离的本质

VPC 的"逻辑隔离" = 把每个租户的网络身份(VNI)固化在租户无法触碰的宿主机数据面里,让跨租户流量不是因为被拦截而失败,而是因为"查无此路"而根本无法产生。

物理层完全共享,但租户能操控的边界止步于自己的虚拟网卡;从 vNIC 往外的第一跳开始,打标、查表、封装、路由的每一个决策都在云平台控制的组件里完成。

2.5 诚实的补充:它依赖什么前提

逻辑隔离不是魔法,它的安全性建立在几个前提上,这也是它和物理隔离的真正差距:

  • vSwitch/Hypervisor 无漏洞——历史上确实出过 VXLAN VNI 校验漏洞、虚拟化逃逸漏洞,云厂商靠快速热补丁和逃逸检测兜底;
  • 控制面不可被租户渗透——SDN 控制器、宿主机管理通道一旦失守,所有 VNI 都会暴露;
  • 硬件资源侧信道——网络带宽、宿主机缓存这类共享资源仍存在"吵闹邻居"问题,逻辑隔离不解决性能隔离。

正因为这些残余风险,强合规场景会在逻辑隔离之上再叠加:裸金属/专属宿主机、VPC 内流量加密(连云厂商的网关都看不到明文)、以及基于 TEE 的机密计算——把信任边界从"相信云平台的实现正确"收紧到"只相信硬件加密"


三、实战推演:故意让两个租户撞 IP、共宿主机

为了真正看清楚隔离发生在哪里,我们故意设计一个最恶劣的场景:两个租户使用完全相同的网段,两台分属不同租户的虚机落在同一台物理宿主机上。

3.1 场景设定

flowchart LR
    A1[VM-A1
172.16.0.5] -- vNIC p1 --> VS1 A2[VM-A2
172.16.0.6] -- vNIC p7 --> VS2 B1[VM-B1
172.16.0.6
与A2同IP!] -- vNIC p9 --> VS2 subgraph H1[宿主机 H1 / 10.10.0.11] VS1[vSwitch + VTEP1
按VNI分转发表] end subgraph H2[宿主机 H2 / 10.10.0.12] VS2[vSwitch + VTEP2
按VNI分转发表] end VS1 -- 物理网络 UDP 4789
只看到 H1→H2 --> VS2
角色 属性
租户 A VPC-A,网段 172.16.0.0/16,VNI = 10001
VM-A1 172.16.0.5,MAC 02:11:22:33:44:55,宿主机 H1
VM-A2 172.16.0.6,MAC 02:aa:bb:cc:dd:ee,宿主机 H2
租户 B VPC-B,网段 172.16.0.0/16(与 A 撞网段),VNI = 20002
VM-B1 172.16.0.6(与 A2 完全同 IP),宿主机 H2(与 A2 同一台物理机)
H1 / H2 物理网卡 IP 10.10.0.11 / 10.10.0.12,各跑一个 vSwitch,充当 VTEP

动作:VM-A1 ping 172.16.0.6。 这个目标 IP 同时是 A2 和 B1 的地址,网络必须准确知道"该给谁、不该给谁"。

3.2 正向流程:A1 → A2 报文一步步怎么走

第 0 步:A1 发 ARP 查询(隔离第一关卡)

A1 内核构造 ARP Request(目的 MAC = ff:ff:ff:ff:ff:ff):“谁是 172.16.0.6?” 这个广播不会走物理网络。vSwitch 查询控制面下发的租户 ARP/端口映射表:

1
2
端口 p1 (VM-A1)         → VNI=10001
VNI=10001, 172.16.0.6 → MAC 02:aa:bb:cc:dd:ee @ 远端 VTEP 10.10.0.12

vSwitch 直接代答(proxy ARP),把 A2 的 MAC 回给 A1。ARP 广播域被收窄到 VNI=10001 内部,永远"波及"不到 B 租户。

第 1 步:ICMP 帧从 A1 的 vNIC 发出

原始(内层)以太网帧:

1
2
3
4
5
源 MAC    : 02:11:22:33:44:55   (VM-A1)
目的 MAC : 02:aa:bb:cc:dd:ee (VM-A2)
源 IP : 172.16.0.5
目的 IP : 172.16.0.6
载荷 : ICMP Echo Request

第 2 步:vSwitch 打标 + 查表(隔离真正发生的第一站)

vSwitch 在入口处做三件事,全部由平台侧执行,租户无法干预:

  1. 按端口绑定强制打 VNI:p1 绑定了 VNI=10001,这帧报文被强制标记为租户 A;
  2. MAC/IP 反欺骗校验:源 MAC、源 IP 与控制面下发的绑定表比对,不一致直接丢弃;
  3. 查转发位置:在 VNI=10001 的专属转发表里查目的 MAC → 命中远端表项,对应 VTEP 地址 10.10.0.12。

这一步是整个隔离体系的根:vSwitch 的所有转发表按 VNI 分命名空间,查询永远发生在本租户那张表里。

第 3 步:VXLAN 封装(打包裹)

1
2
3
4
5
外层以太网头:源/目的 MAC = H1 物理网卡 ↔ 物理交换机下一跳
外层 IP 头:源 10.10.0.11 (H1),目的 10.10.0.12 (H2)
UDP 头:目的端口 4789 (VXLAN)
VXLAN 头(8 字节):VNI = 10001 ← 平台打上,租户改不了
载荷:[A1→A2 的完整原始以太网帧]

从这一刻起,物理网络只看到"H1→H2 的普通 UDP 流量"。

第 4 步:物理网络转发(不做租户判断)

物理交换机按外层目的 IP 做普通三层转发。这层不做任何隔离判断——隔离已经在两端 vSwitch 完成,underlay 只负责"送快递"。

第 5 步:H2 vSwitch 解封装(验身份证)

  1. 剥外层头,取出 VNI=10001;
  2. 合法性校验:来源 VTEP 是否在白名单、VNI 是否在本机合法集合内——不合法直接丢弃;
  3. 在 VNI=10001 的本机转发表里查目的 MAC → 命中本地端口 p7(VM-A2 的 vNIC)。

第 6 步:交付

vSwitch 把剥干净的原始帧过一道安全组(L3/L4 状态过滤)后,从 p7 发给 VM-A2。回程反向走同样的路。

整个流程中,报文从未"裸奔"在物理网络上,租户身份始终由 VNI 标记、由平台侧 vSwitch 把关——即使 A2 和 B1 同宿主机、同 IP,各自的流量在 vSwitch 的不同 VNI 表里走完全独立的路径。

3.3 反例:A1 恶意尝试访问 B1 会发生什么

假设 A1 被攻破,攻击者直接 ping 172.16.0.6 想试试能不能串到 B 租户:

  1. 卡在 ARP:ARP 广播被限定在 VNI=10001 内,vSwitch 只会用 A2 的 MAC 代答,永远 ARP 不出 B1 的 MAC;
  2. 伪造目的 MAC:即使猜到 B1 的真实 MAC 手工构帧,vSwitch 在 VNI=10001 的表里查不到 → 丢弃;
  3. 绕过 vSwitch 直接注入伪造 VXLAN 包(外层伪装成 VTEP、VNI 填 20002):H2 vSwitch 校验 VTEP 白名单,发现不合法 → 丢弃;
  4. 从 A 的 VPC 路由表找路:控制面从未下发指向 B 的路由,查表 miss → 丢弃。

每条路都是死胡同,原因高度一致:跨租户流量不是被"拦截",而是"查无此路"。

3.4 逐跳对照表

步骤 发生位置 动作 隔离判断 为什么必须在这层做
0 A1 内核 → vSwitch p1 ARP 广播 广播域限定 VNI=10001 防跨租户 ARP 泛洪/欺骗
1 vSwitch (H1) 入口 强制打 VNI=10001 端口身份固化 攻破 VM 也改不了租户归属
2 vSwitch (H1) 查表 VNI=10001 表内查目的 MAC 按 VNI 分命名空间 "查无此路"式硬隔离
3 vSwitch (H1) 封装 外层 IP + UDP 4789 + VNI VNI 由平台打上不可篡改 物理网络可区分身份但不暴露拓扑
4 物理交换机 按外层 IP 转发 不判断(不需要) underlay 保持通用
5 vSwitch (H2) 入口 VTEP 白名单 + VNI 合法性 伪造来源丢弃 防注入绕过
6 vSwitch (H2) 查表 VNI=10001 表查目的 MAC 查不到 → 丢弃 双向对称隔离
7 交付 vNIC 剥净后送入 安全组 L4 过滤 兜底细粒度控制

3.5 精确校准:四个容易忽略的实现细节

上面的流程是主干,四个细节需要精确化:

1. ARP 的处理方式取决于控制面实现,不总是"代答"

公有云 VPC 里普遍是 vSwitch 代答——广播根本不出宿主机;传统 EVPN-VXLAN 部署里更多是 ARP Suppression(抑制)——本地表命中就代答,未命中才把 ARP 作为 BUM 流量在 VNI 内泛洪(泛洪范围仍被 VNI 截断)。两种形式隔离效果一致,区别只是广播是否"漏出"本机。

2. 同宿主机的流量根本不封装 VXLAN

如果源 VM 和目的 VM 在同一台宿主机,vSwitch 在 VNI=10001 的本地转发表里直接命中本地端口,做的是本地二层交换——不封装、不出物理网卡、不经过 VTEP。VXLAN 只在跨宿主机时才登场。例子里 A2 和 B1 同宿主机同 IP,隔离靠的就是本地转发表的 VNI 命名空间,跟 VXLAN 封装无关。

3. 源 VTEP 校验发生在解封装一侧

校验由收包方的 vSwitch 执行:封装一侧只负责打标,不校验自己。OVS 里校验的形式通常是隧道表里登记的合法远端 VTEP IP 列表——来源 IP 不在表内则无法映射到合法隧道,直接丢弃。

4. 交付前的最后一道:安全组

剥离成原始帧后、送进 vNIC 前,vSwitch 还会按端口上挂的安全组规则做 L3/L4 状态过滤——这是租户自己定义的策略,属于授权后的细粒度控制,与 VNI 的"硬隔离"是叠加关系。

修正后的完整心智模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
VM 发包

[入口] vSwitch 按端口绑定打 VNI + MAC/IP 反欺骗

[ARP] VNI 内代答或 VNI 内泛洪(广播域被 VNI 截断)

[查表] 在 VNI 专属转发表查目的 MAC
├─ 本地命中 → 本地交换,直接交付(不经 VXLAN)
└─ 远端命中 → VXLAN 封装(外层 IP + VNI)→ underlay → 对端 vSwitch

[解封装] 校验源 VTEP 白名单 + VNI 合法性

[查表] VNI 表内查目的 MAC

[安全组] L3/L4 过滤

剥离原始帧 → 交付 vNIC

3.6 隔离层次总结

1
2
3
4
5
L1 物理层     :所有租户共享交换机/光纤 —— 不隔离(也不需要)
L2 Overlay 层 :VXLAN VNI —— 租户身份的唯一可信标识
L3 转发表层 :vSwitch 按 VNI 分命名空间 —— "查无此路"式硬隔离(真正的根)
L4 控制面层 :VPC 路由/对等连接显式开通 —— 跨租户通信必须显式授权修路
L5 应用层 :安全组/网络 ACL —— 授权后的细粒度过滤

最关键的认知:L3 是隔离的根——不是靠防火墙"拦截",而是靠"不存在那条路";L4 控制面决定要不要修路,L3 数据面决定有没有路。


四、那么,subnet 能不能做租户隔离?

答案:不能。 VNI + vSwitch 按租户分命名空间的转发表,才是 VPC 隔离租户的"根";subnet 回答的是另一个维度的问题——VPC 内部的分区控制。

subnet 在云里的真实角色:VPC 内的一段 IP 地址规划(CIDR),附属于一张路由表,本质上只是"地址分配和路由的记账单位",不是隔离边界。四个原因,一个比一个致命:

4.1 IP 是"租户自报的身份",不是平台担保的身份

subnet 隔离依赖路由器/防火墙按 IP 做判断,但 VM 里的 IP 是租户自己配置的:

1
ifconfig eth0 172.16.0.6   # 伪装成别的子网/别的机器的 IP

如果隔离只靠"目的 IP 属于哪个网段"来判断,源 IP 伪造就能绕过。对比 VNI:VNI 绑定在 vSwitch 端口上,由平台写入、租户改不了。这就是"逻辑地址"与"物理身份锚点"的差别——隔离强度取决于 enforcement point 在哪一层:越靠近租户触碰不到的地方(vSwitch 端口、VNI)越硬,越靠近租户可配置的层面(IP、路由)越软。

4.2 subnet 隔离是"有路但设卡",VNI 隔离是"根本没有路"

  • VNI 模式:租户 B 的 MAC 表项只存在于 VNI=20002 的转发表里,租户 A 的报文查询的是 VNI=10001 那张表,查不到就是查不到——那条路径在数据面上不存在;
  • subnet 模式:路由器上两张子网的路由都在同一张全局路由表里,隔离靠中间挂 ACL/防火墙规则"禁止转发"。一旦规则配错一条、防火墙被绕过一条路径,隔离就破了。

安全设计上,前者叫 deny by absence(默认无路),后者叫 deny by policy(有路设卡)。前者不依赖策略的正确性,后者完全依赖——而策略是会出错的。

4.3 撞网段问题:subnet 方案直接崩溃

公有云几百万租户,一定有大量租户都想用 172.16.0.0/16 或 10.0.0.0/8 这类私网段:

  • 路由器上同一个目的网段只能有一个下一跳——两个租户都用 172.16.0.0/16 时,全局路由表直接冲突;
  • 所以 subnet 方案要求所有租户网段全局唯一,这在租户规模上不可行。

而 VNI 模式下,报文的"归属"由 VNI 决定、内层 IP 原样保留,每个租户拥有独立的虚拟路由表和独立的 MAC 地址空间,撞网段完全合法。第三章那个 A2/B1 同 IP 同宿主机的例子,在纯 subnet 世界里根本不可能运转。

4.4 二层广播域拦不住

VNI 模式下广播域被 VNI 硬截断;而同一物理网络里的两台 subnet 机器,如果二层连通(没有 VLAN),ARP 广播双方都收得到——攻击者可以通过 ARP 泛洪/欺骗持续探测、投毒。

4.5 对比表

维度 VNI 隔离(VPC 根机制) subnet 隔离
身份锚点 vSwitch 端口绑定的 VNI,租户不可篡改 IP 地址,租户自配可伪造
隔离方式 转发表按 VNI 分命名空间,“查无此路” 路由表/ACL 策略拒绝,“有路设卡”
失效条件 需要 vSwitch 实现有 bug 任何一条策略配错即穿透
撞网段 天然支持,每租户独立地址空间 全局路由冲突,无法共存
广播域 硬截断在 VNI 内 取决于 VLAN 配置,易泛洪
隔离的层级 L2 虚拟化层(数据面) L3 路由策略层(控制面)

4.6 subnet 的正确战场:VPC 内部微分段

公道地说,subnet 并非无用,它的正确用法是在 VNI 已把租户硬隔离之后,做租户内部的子网微分段,机制是三层叠加:

  1. 路由表切分:把子网关联到不同路由表,去掉指向对方子网的路由——这是"收窄路径"的 subnet 版本;
  2. 网络 ACL:子网边界的无状态 L3/L4 过滤;
  3. 安全组:实例级有状态过滤,作用在 vNIC 上。

典型分层架构:public subnet 放对外服务,private subnet 放应用,隔离的 data subnet 放数据库且不放通往 IGW 的路由——通过"不给路由"实现数据库子网无法出网,这其实就是缩小版的 deny by absence。注意安全组在这个体系里反而最强——因为它同样下沉到了 vNIC/vSwitch 端口层执行。

历史上这也是真实演进路径:数据中心早期靠"VLAN + subnet + 防火墙分区"做隔离,撞上了 4094 个 VLAN 上限、网段全局唯一、策略人工维护出错这些墙,才发展出 VXLAN/VNI + SDN 控制面这套体系——把隔离从"运维纪律"升级成了"平台机制"


五、subnet 在路由表和交换机中的真实拓扑

subnet 有两层拓扑:一层是租户在控制台上看到的逻辑拓扑(VPC → 子网 → 实例),另一层是数据面真实存在的实现拓扑(子网 ↔ 二层 VNI/Bridge Domain ↔ 虚拟路由器 ↔ 底层 Leaf-Spine)。两层的错位正是困惑的根源。

5.1 层次全景

层级 组件 与 subnet 的关系
L0 物理层 Leaf(TOR)→ Spine 交换机,underlay IP/BGP 不感知 subnet:跨宿主机的子网流量只是一条宿主机间的 UDP 4789 普通流量
L1 Overlay 隧道层 VTEP + VXLAN 隧道 按隧道转发到目标宿主机,不管隧道里装的是哪个子网的帧
L2 二层虚拟网络层 二层 VNI ↔ Bridge Domain(BD),每个 subnet 对应一个 BD/VSI subnet 在这层第一次"实体化":同子网 = 同 BD = 二层互通;不同子网 = 二层隔离
L3 虚拟路由层 路由表(VPC 级)+ 分布式虚拟路由器 跨子网通信的唯一通道:出子网必须查本子网关联的路由表
L4 租户网络层 VPC 整体边界(三层 VNI / VPN 实例) subnet 的"天花板":所有子网都在同一个 VPC 命名空间内
L5 逻辑视图层 控制台上的 VPC → subnet → ENI → VM 只是地址记账和策略挂载点,不是转发实体

两个重要"错位":

  • subnet 与 AZ 没有物理绑定:公有云的 subnet 是区域级逻辑对象,同一子网的实例可以分布在多个 AZ 的不同宿主机上;控制面保证"subnet ID → VNI"的映射在区域内全局一致,但底层物理路径每个 AZ 各自独立;
  • subnet 与物理交换机没有绑定:一个子网的流量可能横跨几百台宿主机、几十台 Leaf 交换机;一台 Leaf 上的隧道里同时跑着上千个不同子网(不同 VNI)的流量。

5.2 具体例子:一个 VPC,2 个 AZ,3 类 subnet

flowchart TB
    subgraph VPC[租户 A 的 VPC / 172.16.0.0/16]
        subgraph AZ1[可用区 1]
            PUB1[Public-Subnet-AZ1
172.16.1.0/24
关联 RT-Public] PRIV1[Private-Subnet-AZ1
172.16.2.0/24
关联 RT-Private] end subgraph AZ2[可用区 2] PUB2[Public-Subnet-AZ2
172.16.3.0/24
关联 RT-Public] PRIV2[Private-Subnet-AZ2
172.16.4.0/24
关联 RT-Private] end DB[DB-Subnet / 172.16.5.0/24
关联 RT-DB] RT-Public[RT-Public] RT-Private[RT-Private] RT-DB[RT-DB] end IGW[Internet 网关] --- RT-Public NAT[NAT 网关] --- RT-Private RT-DB -.仅含 local 路由.- VPC

每张路由表的内容:

路由表 关联子网 路由条目
RT-Public 172.16.1.0/24、172.16.3.0/24 172.16.0.0/16 → local;0.0.0.0/0 → IGW
RT-Private 172.16.2.0/24、172.16.4.0/24 172.16.0.0/16 → local;0.0.0.0/0 → NAT 网关
RT-DB 172.16.5.0/24 172.16.0.0/16 → local(刻意不配出网路由)

三个结构细节:

  1. local 路由是隐式自动生成的,指向整个 VPC 网段,删不掉——它是"子网间互通"的物理基础;
  2. 0.0.0.0/0 是默认路由,决定子网的"出网属性"(public/private/DB 的差别就在这一条);
  3. 一个子网同一时刻只关联一张路由表(显式关联优先;没显式关联就吃 VPC 主路由表)。多子网可共享一张表——例子中 AZ1/AZ2 的 public subnet 共享 RT-Public,这是把"同策略子网"归类的常规做法。

5.3 数据面逐跳追踪:subnet 在转发中"实体化"在哪

部署:Web-VM(172.16.2.10,宿主机 H1,AZ1)→ DB-VM(172.16.5.20,宿主机 H2,AZ2)。

第一跳:Web-VM 判断目标不在本子网

VM 内核发现目的 IP 172.16.5.20 不在 172.16.2.0/24 内 → 关键分叉:同子网走二层(直接 ARP + 同 BD 的 VXLAN 转发),跨子网必须走三层(发给网关)。VM 把帧发给虚拟网关 MAC(SDN 控制器写入每个 VM 的默认网关,实际是分布式虚拟路由器在各宿主机上的接口 MAC)。

第二跳:vSwitch 识别"这是发给路由器的包"

H1 的 vSwitch 解析目的 MAC = 虚拟路由器接口 → 触发三层转发:剥离以太网头,按 172.16.5.0/24 查 RT-Private → 命中 local → 换成出接口,重新封装以太网头(源 MAC = 路由器,目的 MAC = ARP 查到的 DB-VM MAC)。公有云把这个路由功能分布到了每个宿主机 vSwitch 上(分布式路由)。

第三步:VXLAN 封装(换 VNI)

vSwitch 把"路由后"的帧封装进 VNI=BD(DB-Subnet)——注意:不是原子网的 VNI,而是目的子网的 VNI,外层 IP 打 H2 的地址,送进 underlay。

第四步:Leaf/Spine 转发(完全不看 subnet)

物理交换机按外层 IP 做普通转发——对里面装的子网、VPC、租户全部无感。

第五步:H2 vSwitch 解封装交付

剥外层头、验 VNI/VTEP、在 BD(DB-Subnet) 的表里查 DB-VM MAC、过安全组,交付。

整个路径说明一个要点:"子网"在物理网络上从未出现过,它只以 VNI(BD) 的形式存在于宿主机 vSwitch 的转发表里,以路由条目的形式存在于虚拟路由器里。物理网络是纯粹的信使。

5.4 与传统物理网络(VLAN 模式)对照

结构点 传统数据中心(VLAN+SVI) 公有云(VXLAN overlay)
子网的二层实体 一段 VLAN(12bit,全局 4094 个) 一个 BD/二层 VNI(24bit,1600 万)
子网间的路由点 核心交换机上的 SVI(VLAN 接口) 分布式虚拟路由器 + VPC 路由表
子网跨机柜/跨楼 受物理二层延伸(Trunk/堆叠)限制 underlay IP 路由,无二层延伸限制
子网跨 AZ 基本做不到(二层跨 DC 很脆) 逻辑上同一个 subnet(区域级对象),物理上每 AZ 独立 leaf-spine,靠控制面统一映射
谁决定"可达" 交换机配置 + STP/VLAN 剪枝 路由表条目 + VNI 命名空间

一句话归纳:传统网络里 subnet 是"物理绑定的 VLAN",云网络里 subnet 是"逻辑映射的 VNI + 路由表条目"——所有实体化都发生在宿主机 vSwitch 和虚拟路由器上,物理交换机退化为纯粹的 IP 信使。

5.5 按子网内 / 跨子网区分查表行为

  • 同子网两 VM:纯二层流程,vSwitch 在 BD(Private-Subnet) 的 MAC 表里查目的,不查路由表;
  • 跨子网两 VM(Web → DB):必须经虚拟路由器,两次查表(VM 出子网查路由表,路由后进入目的子网查 BD MAC 表);
  • 出 VPC(Web → 互联网):同跨子网,但出接口指向 IGW,由 IGW 做 NAT 后送进外部网络。

这就是为什么 RT-DB 不配出网路由就够了——子网内互访走 local,出网路径因为"路由表里没有那条"而不存在。路由表的"没有"决定"没有路径",与 VNI 的"查无此路"是一脉相承的设计哲学。


六、总结:贯穿全文的三条设计哲学

把全文收拢到三个可迁移的原则上:

1. 身份要锚定在租户触碰不到的层。

租户隔离的强度不取决于隔离机制多复杂,而取决于 enforcement point 的位置:VNI 绑死在 vSwitch 端口(硬)、安全组挂在 vNIC(硬)、tenant_id 过滤靠应用自觉(软)、subnet 划分靠 IP(最软,可伪造)。凡是租户能改的参数,都不能作为安全身份的依据。

2. 优先 deny by absence,而不是 deny by policy。

VNI 命名空间让跨租户路径"不存在",local 路由让子网间互通"天然有",IGW 路由的缺席让数据子网"出不了网"。相比之下,靠防火墙规则"有路设卡"的方案,安全性等于策略配置的零失误率——这在人身上是奢求,在平台上是纪律。

3. 物理层共享、逻辑层独立,是隔离与成本的帕累托解。

Leaf-Spine 上跑着所有租户的 UDP 包,宿主机上住着互相撞 IP 的邻居虚机,存储池里混着大家的加密数据——共享换来了云的成本曲线,而 VNI、Hypervisor、KMS、TEE 把逻辑边界守住了。残余风险(Hypervisor 漏洞、控制面失守、侧信道)不是被忽略,而是被强合规场景用裸金属、VPC 加密、机密计算逐级买断。

理解了这三条,再看云上任何隔离设计——不管是容器沙箱、数据库 RLS,还是对象存储的桶策略——你都能快速定位同一个问题:它的 enforcement point 在哪一层?租户的手能不能伸到那一层?答案是"够不着"的,就是可靠的隔离。