Neutron VLAN 网络模型 + Linux bridge 驱动 + 集中式路由 完整实现方案整理

Neutron VLAN 网络模型 + Linux Bridge 驱动 + 集中式路由方案整理

By Opus 4.6

一、整体架构

text 复制代码
                        外部网络 / Internet
                              │
                              │
                    ┌─────────┴─────────┐
                    │   External Router  │
                    │   (物理路由器)      │
                    └─────────┬─────────┘
                              │
                              │ VLAN 100 (external)
                              │
┌─────────────────────────────┼─────────────────────────────────────┐
│                        Network Node                               │
│                                                                   │
│   ┌─────────────────────────┴─────────────────────────┐           │
│   │              eth1 (外部网络物理网卡)                │           │
│   │              接入外部网络                          │           │
│   └─────────────────────────┬─────────────────────────┘           │
│                             │                                     │
│   ┌─────────────────────────┴─────────────────────────┐           │
│   │           brq-external (Linux Bridge)              │           │
│   │           外部网络桥                                │           │
│   └──────┬──────────────────────────────┬─────────────┘           │
│          │                              │                         │
│   ┌──────┴──────┐                ┌──────┴──────┐                  │
│   │ qg-xxx      │                │ qg-yyy      │                  │
│   │ (router gw) │                │ (router gw) │                  │
│   └──────┬──────┘                └──────┬──────┘                  │
│          │                              │                         │
│   ┌──────┴──────────────────────────────┴──────┐                  │
│   │         qrouter-xxx namespace               │                  │
│   │         (Neutron L3 Agent 管理)             │                  │
│   │                                             │                  │
│   │   路由表 / NAT / iptables                   │                  │
│   │                                             │                  │
│   │   qr-aaa ──┬── qr-bbb                      │                  │
│   │   10.0.1.1 │   10.0.2.1                    │                  │
│   └──────┬─────┴────────┬───────────────────────┘                  │
│          │              │                                         │
│   ┌──────┴──────┐ ┌─────┴──────┐                                  │
│   │ brq-net1    │ │ brq-net2   │                                  │
│   │ VLAN 201    │ │ VLAN 202   │                                  │
│   └──────┬──────┘ └─────┬──────┘                                  │
│          │              │                                         │
│   ┌──────┴──────────────┴──────┐                                  │
│   │    eth0 (内部网络物理网卡)  │                                  │
│   │    trunk (承载 VLAN 201/202)│                                  │
│   └──────────────┬─────────────┘                                  │
│                  │                                                 │
└──────────────────┼─────────────────────────────────────────────────┘
                   │
            物理交换机 (trunk)
            承载 VLAN 201, 202
                   │
┌──────────────────┼─────────────────────────────────────────────────┐
│              Compute Node                                          │
│                  │                                                  │
│   ┌──────────────┴─────────────┐                                   │
│   │    eth0 (内部网络物理网卡)  │                                   │
│   │    trunk (承载 VLAN 201/202)│                                   │
│   └──────┬──────────────┬──────┘                                   │
│          │              │                                          │
│   ┌──────┴──────┐ ┌─────┴──────┐                                   │
│   │ brq-net1    │ │ brq-net2   │                                   │
│   │ VLAN 201    │ │ VLAN 202   │                                   │
│   └──────┬──────┘ └─────┬──────┘                                   │
│          │              │                                          │
│   ┌──────┴──┐     ┌─────┴───┐                                      │
│   │ tap-vm1 │     │ tap-vm3 │                                      │
│   │         │     │         │                                      │
│   └────┬────┘     └────┬────┘                                      │
│        │               │                                           │
│   ┌────┴────┐     ┌────┴────┐                                      │
│   │  VM-1   │     │  VM-3   │                                      │
│   │10.0.1.10│     │10.0.2.10│                                      │
│   │ net1    │     │ net2    │                                      │
│   └─────────┘     └─────────┘                                      │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

二、核心概念

三个角色

text 复制代码
┌──────────────────────────────────────────────────────────────────┐
│                                                                  │
│  Controller Node                                                 │
│  ┌──────────────────────────────────────────────────────────┐    │
│  │  neutron-server                                          │    │
│  │  - 接收 API 请求                                         │    │
│  │  - 管理网络/子网/端口/路由器 数据库                        │    │
│  │  - 通过 RPC 通知各节点 Agent                              │    │
│  └──────────────────────────────────────────────────────────┘    │
│                                                                  │
│  Network Node                                                    │
│  ┌──────────────────────────────────────────────────────────┐    │
│  │  neutron-l3-agent          (管理路由器 namespace)          │    │
│  │  neutron-dhcp-agent        (管理 DHCP namespace)          │    │
│  │  neutron-linuxbridge-agent (管理 bridge + VLAN 子接口)    │    │
│  │  neutron-metadata-agent    (提供 metadata 服务)           │    │
│  └──────────────────────────────────────────────────────────┘    │
│                                                                  │
│  Compute Node                                                    │
│  ┌──────────────────────────────────────────────────────────┐    │
│  │  neutron-linuxbridge-agent (管理 bridge + VLAN 子接口)    │    │
│  │  nova-compute              (管理 VM)                      │    │
│  └──────────────────────────────────────────────────────────┘    │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

集中式路由的含义

text 复制代码
"集中式路由" 意味着:

  ┌─────────────────────────────────────────────────────────────┐
  │                                                             │
  │  所有跨子网的流量、所有访问外部网络的流量                      │
  │  都必须经过 Network Node 上的 qrouter namespace              │
  │                                                             │
  │  VM-1 (net1, 10.0.1.10)                                     │
  │    │                                                        │
  │    │ 跨子网或访问外网                                        │
  │    ▼                                                        │
  │  Compute Node eth0                                          │
  │    │                                                        │
  │    │ VLAN 201                                               │
  │    ▼                                                        │
  │  物理交换机                                                  │
  │    │                                                        │
  │    │ VLAN 201                                               │
  │    ▼                                                        │
  │  Network Node eth0                                          │
  │    │                                                        │
  │    ▼                                                        │
  │  qrouter namespace ← 路由 + NAT 都在这里做                   │
  │    │                                                        │
  │    │ 如果目标是 net2: 路由到 VLAN 202 → 物理交换机 → 计算节点  │
  │    │ 如果目标是外网:  NAT → 外部网络                         │
  │    ▼                                                        │
  │  目的地                                                     │
  │                                                             │
  └─────────────────────────────────────────────────────────────┘

  优点: 简单,状态集中
  缺点: Network Node 是瓶颈,是单点

三、Compute Node 详细结构

text 复制代码
┌──────────────────── Compute Node ──────────────────────────────────┐
│                                                                    │
│  物理网卡 eth0                                                     │
│  ┌────────────────────────────────────────────────────────────┐    │
│  │  eth0: trunk port                                         │    │
│  │  承载 VLAN 201, 202 ...                                   │    │
│  │                                                           │    │
│  │  内核自动创建 VLAN 子接口:                                  │    │
│  │  eth0.201 ──── 标记/去标记 VLAN 201 的帧                   │    │
│  │  eth0.202 ──── 标记/去标记 VLAN 202 的帧                   │    │
│  └────┬───────────────────────────────┬──────────────────────┘    │
│       │                               │                           │
│       │                               │                           │
│  ┌────┴─────────────────┐    ┌────────┴─────────────────┐         │
│  │  brq-<net1-id>       │    │  brq-<net2-id>           │         │
│  │  Linux Bridge        │    │  Linux Bridge            │         │
│  │                      │    │                          │         │
│  │  端口:               │    │  端口:                   │         │
│  │  - eth0.201 (上行)   │    │  - eth0.202 (上行)       │         │
│  │  - tap-vm1  (VM-1)   │    │  - tap-vm3  (VM-3)       │         │
│  │  - tap-vm2  (VM-2)   │    │  - tap-vm4  (VM-4)       │         │
│  │                      │    │                          │         │
│  │  安全组: iptables     │    │  安全组: iptables         │         │
│  │  在 tap 端口上        │    │  在 tap 端口上            │         │
│  │                      │    │                          │         │
│  └──────────────────────┘    └──────────────────────────┘         │
│       │           │                │           │                  │
│  ┌────┴───┐  ┌────┴───┐      ┌────┴───┐  ┌────┴───┐              │
│  │tap-vm1 │  │tap-vm2 │      │tap-vm3 │  │tap-vm4 │              │
│  └────┬───┘  └────┬───┘      └────┬───┘  └────┬───┘              │
│       │           │               │           │                   │
│  ┌────┴───┐  ┌────┴───┐      ┌────┴───┐  ┌────┴───┐              │
│  │  VM-1  │  │  VM-2  │      │  VM-3  │  │  VM-4  │              │
│  │  net1  │  │  net1  │      │  net2  │  │  net2  │              │
│  │10.0.1  │  │10.0.1  │      │10.0.2  │  │10.0.2  │              │
│  │  .10   │  │  .11   │      │  .10   │  │  .11   │              │
│  └────────┘  └────────┘      └────────┘  └────────┘              │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

VLAN 子接口的作用

text 复制代码
eth0 收到一个带 VLAN tag 201 的帧:

┌─────────────────────────────────────────────────────────────┐
│ Dst MAC │ Src MAC │ 802.1Q: VLAN 201 │ EtherType │ Payload │
└─────────────────────────────────────────────────────────────┘
                          │
                          ▼
                    eth0 收到帧
                          │
                          │ 内核 VLAN 处理
                          ▼
                    eth0.201 剥离 VLAN tag
                          │
                          │ 帧变成普通以太网帧
                          ▼
                    brq-net1 (bridge)
                          │
                          │ 二层转发
                          ▼
                    tap-vm1 → VM-1


eth0.201 发送一个帧:

    VM-1 → tap-vm1 → brq-net1 → eth0.201
                                     │
                                     │ 自动加上 VLAN 201 tag
                                     ▼
                                   eth0 发出
                                     │
                         ┌───────────┴───────────────────┐
                         │ 带 VLAN 201 tag 的以太网帧     │
                         └───────────────────────────────┘

linuxbridge-agent 在计算节点做了什么

text 复制代码
neutron-linuxbridge-agent 启动后:

当 neutron-server 通知 "节点上有 VM 要接入 net1 (VLAN 201)" 时:

  ① 创建 VLAN 子接口 (如果不存在)
     ip link add link eth0 name eth0.201 type vlan id 201
     ip link set eth0.201 up

  ② 创建 Linux Bridge (如果不存在)
     brctl addbr brq-<net1-uuid-前11位>
     ip link set brq-<net1-uuid> up

  ③ 将 VLAN 子接口加入 Bridge
     brctl addif brq-<net1-uuid> eth0.201

  ④ VM 启动时,Nova 创建 tap 设备并加入 Bridge
     (实际上 tap 设备由 libvirt/qemu 创建)
     brctl addif brq-<net1-uuid> tap-<port-uuid-前11位>

  ⑤ 配置安全组
     iptables 规则挂在 tap 设备上

四、Network Node 详细结构

text 复制代码
┌────────────────────── Network Node ─────────────────────────────────────┐
│                                                                         │
│  ┌──────────── Host Network Namespace ──────────────────────────────┐   │
│  │                                                                  │   │
│  │  eth0 (内部网络)        eth1 (外部网络)                          │   │
│  │  trunk: VLAN 201,202    flat 或 VLAN                             │   │
│  │     │                      │                                     │   │
│  │     ├── eth0.201           │                                     │   │
│  │     │     │                │                                     │   │
│  │     │  ┌──┴──────────┐  ┌─┴──────────────┐                      │   │
│  │     │  │ brq-net1    │  │ brq-external   │                      │   │
│  │     │  │             │  │                │                      │   │
│  │     │  │ 端口:       │  │ 端口:          │                      │   │
│  │     │  │ - eth0.201  │  │ - eth1         │                      │   │
│  │     │  │ - qr-aaa ───┼──┼── qg-xxx ──┐  │                      │   │
│  │     │  │ - tap-dhcp1 │  │             │  │                      │   │
│  │     │  └─────────────┘  └─────────────┘  │                      │   │
│  │     │                                    │                      │   │
│  │     ├── eth0.202                         │                      │   │
│  │     │     │                              │                      │   │
│  │     │  ┌──┴──────────┐                   │                      │   │
│  │     │  │ brq-net2    │                   │                      │   │
│  │     │  │             │                   │                      │   │
│  │     │  │ 端口:       │                   │                      │   │
│  │     │  │ - eth0.202  │                   │                      │   │
│  │     │  │ - qr-bbb ───┼───────────────┐  │                      │   │
│  │     │  │ - tap-dhcp2 │               │  │                      │   │
│  │     │  └─────────────┘               │  │                      │   │
│  │     │                                │  │                      │   │
│  └─────┼────────────────────────────────┼──┼──────────────────────┘   │
│        │                                │  │                          │
│        │    ┌───────────────────────────┼──┼──────────────────┐       │
│        │    │  qrouter-<router-uuid> namespace               │       │
│        │    │                           │  │                  │       │
│        │    │  ┌────────┐    ┌──────────┘  │    ┌────────┐   │       │
│        │    │  │ qr-aaa │    │ qg-xxx      │    │ qr-bbb │   │       │
│        │    │  │10.0.1.1│    │172.16.1.100 │    │10.0.2.1│   │       │
│        │    │  └────┬───┘    └──────┬──────┘    └────┬───┘   │       │
│        │    │       │               │                │       │       │
│        │    │       │    路由表:                      │       │       │
│        │    │       │    10.0.1.0/24 dev qr-aaa      │       │       │
│        │    │       │    10.0.2.0/24 dev qr-bbb      │       │       │
│        │    │       │    0.0.0.0/0   via 172.16.1.1   │       │       │
│        │    │       │    dev qg-xxx                   │       │       │
│        │    │       │                                │       │       │
│        │    │       │    iptables NAT:               │       │       │
│        │    │       │    SNAT 10.0.x.x → 172.16.1.100│       │       │
│        │    │       │    DNAT floating_ip → fixed_ip  │       │       │
│        │    │       │                                │       │       │
│        │    └───────┼────────────────────────────────┼───────┘       │
│        │            │                                │               │
│        │    ┌───────┼────────────────────────────────┼───────┐       │
│        │    │  qdhcp-<net1-uuid> namespace           │       │       │
│        │    │       │                                │       │       │
│        │    │  ┌────┴─────┐                          │       │       │
│        │    │  │ tap-dhcp1│                           │       │       │
│        │    │  │ 10.0.1.2 │                           │       │       │
│        │    │  │ dnsmasq  │                           │       │       │
│        │    │  └──────────┘                           │       │       │
│        │    └────────────────────────────────────────┘       │       │
│        │                                                     │       │
│        │    ┌────────────────────────────────────────┐       │       │
│        │    │  qdhcp-<net2-uuid> namespace           │       │       │
│        │    │                                │       │       │       │
│        │    │  ┌────┴─────┐                          │       │       │
│        │    │  │ tap-dhcp2│                           │       │       │
│        │    │  │ 10.0.2.2 │                           │       │       │
│        │    │  │ dnsmasq  │                           │       │       │
│        │    │  └──────────┘                           │       │       │
│        │    └────────────────────────────────────────┘       │       │
│        │                                                     │       │
└────────┼─────────────────────────────────────────────────────┘       │
         │                                                             │
└─────────────────────────────────────────────────────────────────────┘

qrouter namespace 内的配置

bash 复制代码
# 进入 router namespace
ip netns exec qrouter-<uuid> bash

# 查看接口
ip addr show

# qr-aaa: 10.0.1.1/24   (net1 的网关)
# qr-bbb: 10.0.2.1/24   (net2 的网关)
# qg-xxx: 172.16.1.100/24 (外部网络接口)

# 查看路由
ip route show
# 10.0.1.0/24 dev qr-aaa
# 10.0.2.0/24 dev qr-bbb
# default via 172.16.1.1 dev qg-xxx

# 查看 NAT 规则
iptables -t nat -S
# -A neutron-l3-agent-POSTROUTING -s 10.0.1.0/24 -j SNAT --to 172.16.1.100
# -A neutron-l3-agent-POSTROUTING -s 10.0.2.0/24 -j SNAT --to 172.16.1.100
# -A neutron-l3-agent-PREROUTING -d 172.16.1.200 -j DNAT --to 10.0.1.10  (floating ip)

五、四种典型流量路径

场景 1:同子网同节点(VM-1 → VM-2)

两个 VM 都在 Compute Node,都在 net1

text 复制代码
VM-1 (10.0.1.10)
  │
  │ dst MAC = VM-2 MAC (ARP 学到的)
  │ dst IP  = 10.0.1.11
  ▼
tap-vm1
  │
  ▼
brq-net1 (Linux Bridge)
  │
  │ FDB 查 dst MAC → 出端口 = tap-vm2
  │ 💡 纯二层转发,不出节点
  ▼
tap-vm2
  │
  ▼
VM-2 (10.0.1.11) ✅

流量路径:
  VM-1 → tap-vm1 → brq-net1 → tap-vm2 → VM-2

  不经过 Network Node ✅
  不经过物理网络 ✅
  不经过路由器 ✅

场景 2:同子网跨节点(VM-1 → VM-2')

VM-1 在 Compute-1,VM-2' 在 Compute-2,都在 net1

text 复制代码
Compute-1                   物理交换机              Compute-2
─────────                   ──────────              ─────────

VM-1 (10.0.1.10)                                    VM-2' (10.0.1.12)
  │                                                      ▲
  │ dst MAC = VM-2' MAC                                  │
  ▼                                                      │
tap-vm1                                              tap-vm2'
  │                                                      ▲
  ▼                                                      │
brq-net1                                             brq-net1
  │                                                      ▲
  │ FDB 查 dst MAC → 未知 → 泛洪                         │
  │ 或已学到 → 出端口 = eth0.201                          │
  ▼                                                      │
eth0.201                                             eth0.201
  │ 加 VLAN 201 tag                          剥 VLAN tag │
  ▼                                                      │
eth0 ──────────► 物理交换机 (VLAN 201) ──────────► eth0
                 trunk 转发

流量路径:
  VM-1 → tap → brq-net1 → eth0.201 → eth0
  → 物理交换机 (VLAN 201 二层转发)
  → eth0 → eth0.201 → brq-net1 → tap → VM-2'

  不经过 Network Node ✅
  不经过路由器 ✅
  纯二层 VLAN 转发 ✅

场景 3:跨子网(VM-1 net1 → VM-3 net2)⭐集中式路由

text 复制代码
Compute Node                 物理交换机              Network Node
────────────                 ──────────              ────────────

VM-1 (10.0.1.10, net1)                                      
  │                                                  
  │ dst IP = 10.0.2.10                               
  │ dst MAC = 网关 MAC (qr-aaa 的 MAC)               
  │ 💡 VM 发现目的 IP 不在同子网                      
  │    所以 dst MAC 填网关 MAC                        
  ▼                                                  
tap-vm1                                              
  │                                                  
  ▼                                                  
brq-net1                                             
  │                                                  
  │ FDB 查 dst MAC = qr-aaa MAC → 出端口 = eth0.201  
  ▼                                                  
eth0.201 → eth0                                      
  │                                                  
  │ VLAN 201                                         
  ▼                                                  
物理交换机 ──────────────────────────────────────────►
  │                                                  
  │ VLAN 201                                         
  ▼                                                  
                                              eth0 → eth0.201
                                                │
                                                ▼
                                           brq-net1
                                                │
                                                │ dst MAC = qr-aaa
                                                ▼
                                           qr-aaa (在 brq-net1 上)
                                                │
                                                │ 进入 qrouter namespace
                                                ▼
                                      ┌──────────────────────┐
                                      │ qrouter namespace    │
                                      │                      │
                                      │ 路由查找:            │
                                      │ 10.0.2.0/24          │
                                      │   → dev qr-bbb      │
                                      │                      │
                                      │ 修改 MAC:            │
                                      │ src MAC = qr-bbb MAC │
                                      │ dst MAC = VM-3 MAC   │
                                      │ (查 ARP 表)          │
                                      │ TTL - 1              │
                                      │                      │
                                      └──────────┬───────────┘
                                                 │
                                                 ▼
                                           qr-bbb
                                                │
                                                ▼
                                           brq-net2
                                                │
                                                ▼
                                           eth0.202 → eth0
                                                │
                                                │ VLAN 202
                                                ▼
物理交换机 ◄────────────────────────────────────
  │
  │ VLAN 202
  ▼
Compute Node (可能是同一个也可能不同)
eth0 → eth0.202 → brq-net2 → tap-vm3 → VM-3 (10.0.2.10) ✅


完整路径:
  VM-1 → tap → brq-net1 → eth0.201 → eth0
  → 物理网络 (VLAN 201)
  → Network Node eth0 → eth0.201 → brq-net1
  → qr-aaa → [qrouter: 路由] → qr-bbb
  → brq-net2 → eth0.202 → eth0
  → 物理网络 (VLAN 202)
  → Compute Node eth0 → eth0.202 → brq-net2
  → tap → VM-3

  💡 关键: 流量必须绕到 Network Node 做路由
  💡 即使 VM-1 和 VM-3 在同一个计算节点也要绕行!

场景 4:VM 访问外部网络(Floating IP / SNAT)

text 复制代码
VM-1 (10.0.1.10) → Internet (8.8.8.8)
Floating IP: 172.16.1.200 → 10.0.1.10

VM-1 (10.0.1.10)
  │
  │ dst IP = 8.8.8.8
  │ dst MAC = 网关 MAC (qr-aaa)
  ▼
tap → brq-net1 → eth0.201 → eth0
  │
  │ VLAN 201 → 物理网络
  ▼
Network Node: eth0 → eth0.201 → brq-net1 → qr-aaa
  │
  │ 进入 qrouter namespace
  ▼
┌──────────────────────────────────────────────────┐
│ qrouter namespace                                │
│                                                  │
│ 路由查找:                                        │
│   8.8.8.8 → default via 172.16.1.1 dev qg-xxx   │
│                                                  │
│ iptables NAT:                                    │
│                                                  │
│ 情况A: VM-1 有 Floating IP                       │
│   SNAT: src 10.0.1.10 → 172.16.1.200            │
│   (1:1 NAT)                                      │
│                                                  │
│ 情况B: VM-1 没有 Floating IP                     │
│   SNAT: src 10.0.1.10 → 172.16.1.100            │
│   (router 的网关 IP,多对一 SNAT)                 │
│                                                  │
└──────────────────────┬───────────────────────────┘
                       │
                       ▼
                  qg-xxx (172.16.1.100)
                       │
                       ▼
                  brq-external
                       │
                       ▼
                  eth1 (外部网络物理网卡)
                       │
                       ▼
                  外部物理路由器 → Internet


回包路径 (8.8.8.8 → VM-1):

Internet → 外部路由器 → eth1 → brq-external → qg-xxx
  │
  │ 进入 qrouter namespace
  │ DNAT: dst 172.16.1.200 → 10.0.1.10
  ▼
qr-aaa → brq-net1 → eth0.201 → eth0
  │
  │ VLAN 201 → 物理网络
  ▼
Compute Node: eth0 → eth0.201 → brq-net1 → tap → VM-1 ✅

六、Neutron 配置文件

neutron.conf (Controller)

ini 复制代码
[DEFAULT]
core_plugin = ml2

[ml2]
type_drivers = vlan,flat
tenant_network_types = vlan
mechanism_drivers = linuxbridge

[ml2_type_vlan]
network_vlan_ranges = physnet1:201:300
# physnet1 是物理网络标签
# 201-300 是可分配的 VLAN ID 范围

linuxbridge_agent.ini (Compute + Network Node)

ini 复制代码
[linux_bridge]
physical_interface_mappings = physnet1:eth0
# physnet1 这个标签对应物理网卡 eth0
# Neutron 会在 eth0 上创建 VLAN 子接口

[vxlan]
enable_vxlan = false
# 我们用 VLAN,不用 VXLAN

[securitygroup]
enable_security_group = true
firewall_driver = iptables

l3_agent.ini (Network Node)

ini 复制代码
[DEFAULT]
interface_driver = linuxbridge
external_network_bridge =
# 集中式路由,L3 agent 只跑在 Network Node 上

七、逐步创建网络的命令

bash 复制代码
# ═══════════ 1. 创建 Provider 网络 (外部网络) ═══════════

openstack network create \
  --provider-network-type flat \
  --provider-physical-network extnet \
  --external \
  ext-net

openstack subnet create \
  --network ext-net \
  --subnet-range 172.16.1.0/24 \
  --gateway 172.16.1.1 \
  --allocation-pool start=172.16.1.100,end=172.16.1.200 \
  --no-dhcp \
  ext-subnet


# ═══════════ 2. 创建租户网络 ═══════════

# net1 (VLAN 201)
openstack network create net1
# Neutron 自动从 201-300 范围分配一个 VLAN ID,比如 201

openstack subnet create \
  --network net1 \
  --subnet-range 10.0.1.0/24 \
  --gateway 10.0.1.1 \
  --dns-nameserver 8.8.8.8 \
  subnet1

# net2 (VLAN 202)
openstack network create net2

openstack subnet create \
  --network net2 \
  --subnet-range 10.0.2.0/24 \
  --gateway 10.0.2.1 \
  --dns-nameserver 8.8.8.8 \
  subnet2


# ═══════════ 3. 创建路由器 ═══════════

openstack router create router1

# 设置外部网关
openstack router set --external-gateway ext-net router1

# 连接内部子网
openstack router add subnet router1 subnet1
openstack router add subnet router1 subnet2


# ═══════════ 4. 创建 VM ═══════════

openstack server create \
  --image cirros \
  --flavor m1.tiny \
  --network net1 \
  vm1

openstack server create \
  --image cirros \
  --flavor m1.tiny \
  --network net2 \
  vm3


# ═══════════ 5. 分配 Floating IP ═══════════

openstack floating ip create ext-net
# 返回: 172.16.1.150

openstack server add floating ip vm1 172.16.1.150

八、每一步 Neutron 在节点上干了什么

创建 net1 后(VLAN 201)

此时还没有 VM,节点上不会立即创建设备。

VM-1 启动后(Compute Node)

bash 复制代码
# linuxbridge-agent 自动执行:

# 1. 创建 VLAN 子接口
ip link add link eth0 name eth0.201 type vlan id 201
ip link set eth0.201 up

# 2. 创建 Linux Bridge
brctl addbr brq-aaaabbbb111
ip link set brq-aaaabbbb111 up

# 3. 上行口加入 Bridge
brctl addif brq-aaaabbbb111 eth0.201

# 4. Nova/libvirt 创建 tap 并加入 Bridge
# (由 qemu 自动创建 tap)
brctl addif brq-aaaabbbb111 tap-xxxxxxxx

# 5. 安全组 iptables 规则
iptables -I FORWARD -m physdev --physdev-in tap-xxxxxxxx \
  -j neutron-linuxbridge-i-xxxxxxxx
# (实际规则更复杂)

路由器连接子网后(Network Node)

bash 复制代码
# l3-agent 自动执行:

# 1. 创建 router namespace
ip netns add qrouter-<router-uuid>

# 2. 创建 qr 接口并放入 namespace
# (实际上是创建 veth pair 或 tap,一端在 bridge,一端在 namespace)
ip link add qr-aaa type veth peer name ns-qr-aaa
brctl addif brq-net1 qr-aaa
ip link set ns-qr-aaa netns qrouter-<uuid>

# 3. 在 namespace 内配置 IP
ip netns exec qrouter-<uuid> ip addr add 10.0.1.1/24 dev ns-qr-aaa
ip netns exec qrouter-<uuid> ip link set ns-qr-aaa up

# 4. 同样处理 net2
ip netns exec qrouter-<uuid> ip addr add 10.0.2.1/24 dev ns-qr-bbb
ip netns exec qrouter-<uuid> ip link set ns-qr-bbb up

# 5. 设置外部网关
ip netns exec qrouter-<uuid> ip addr add 172.16.1.100/24 dev qg-xxx
ip netns exec qrouter-<uuid> ip route add default via 172.16.1.1

# 6. 配置 NAT
ip netns exec qrouter-<uuid> iptables -t nat -A POSTROUTING \
  -s 10.0.1.0/24 -o qg-xxx -j SNAT --to 172.16.1.100
ip netns exec qrouter-<uuid> iptables -t nat -A POSTROUTING \
  -s 10.0.2.0/24 -o qg-xxx -j SNAT --to 172.16.1.100

九、集中式路由的瓶颈分析

text 复制代码
┌───────────────────────────────────────────────────────────────┐
│                                                               │
│  集中式路由的流量路径问题:                                     │
│                                                               │
│                    Network Node                               │
│                    ┌──────────┐                               │
│                    │ qrouter  │                               │
│                    │          │                               │
│            ┌──────►│  路由    │◄──────┐                       │
│            │       │  NAT    │       │                       │
│            │       └──────────┘       │                       │
│            │                         │                       │
│            │ VLAN 201                │ VLAN 202              │
│            │                         │                       │
│      ┌─────┴─────┐            ┌──────┴────┐                  │
│      │ Compute-1 │            │ Compute-2 │                  │
│      │           │            │           │                  │
│      │  VM-1     │            │  VM-3     │                  │
│      │  net1     │            │  net2     │                  │
│      └───────────┘            └───────────┘                  │
│                                                               │
│  VM-1 → VM-3 的流量:                                         │
│  Compute-1 → 物理网络 → Network Node → 物理网络 → Compute-2  │
│                                                               │
│  即使 VM-1 和 VM-3 在同一台物理机上:                           │
│  Compute-1 → 物理网络 → Network Node → 物理网络 → Compute-1  │
│  💥 流量走了两趟物理网络 + 一次 Network Node                  │
│                                                               │
│  问题:                                                        │
│  1. Network Node 是性能瓶颈                                   │
│  2. Network Node 是单点故障 (需要 HA)                         │
│  3. 增加物理网络带宽消耗                                      │
│  4. 增加延迟                                                  │
│                                                               │
│  解决方案:                                                    │
│  → DVR (分布式虚拟路由)                                       │
│  → 每个 Compute Node 有自己的 router namespace                │
│  → 东西向流量本地路由                                         │
│                                                               │
└───────────────────────────────────────────────────────────────┘

十、验证和调试命令

bash 复制代码
# ═══════════ Compute Node 上 ═══════════

# 查看所有 bridge
brctl show

# 查看某个 bridge 的端口
brctl showmacs brq-aaaabbbb111

# 查看 VLAN 子接口
cat /proc/net/vlan/config

# 查看 tap 设备
ip tuntap show

# 查看 iptables 安全组规则
iptables -S | grep tap


# ═══════════ Network Node 上 ═══════════

# 查看所有 namespace
ip netns list

# 进入 router namespace
ip netns exec qrouter-<uuid> bash

# 查看路由表
ip netns exec qrouter-<uuid> ip route

# 查看 NAT 规则
ip netns exec qrouter-<uuid> iptables -t nat -S

# 查看接口
ip netns exec qrouter-<uuid> ip addr

# 在 router namespace 内抓包
ip netns exec qrouter-<uuid> tcpdump -i qr-aaa -nn

# 进入 DHCP namespace
ip netns exec qdhcp-<uuid> bash
ip netns exec qdhcp-<uuid> ps aux | grep dnsmasq

一句话总结

Neutron VLAN + Linux Bridge + 集中式路由方案中:每个租户网络对应一个 VLAN ID + 一个 Linux Bridge,VLAN 子接口作为 Bridge 的上行口连接物理网络实现二层互通;所有跨子网和外部流量必须绕行 Network Node 上的 qrouter namespace 做三层路由和 NAT。简单可靠但 Network Node 是瓶颈和单点。

相关推荐
MekoLi292 小时前
Arthas 安装与使用全流程教程
后端·面试
JavaGuide2 小时前
美团面试:为什么要用分布式缓存?本地缓存呢?多级缓存一致性如何保证?
数据库·redis·后端·缓存·大厂面试
JavaGuide2 小时前
为什么要用分布式缓存?本地缓存呢?多级缓存一致性如何保证?
redis·后端
yuanlaile2 小时前
2026后端趋势:Java 老了?Go 才是未来?
java·后端·golang·go与java·后端学什么
我爱娃哈哈2 小时前
SpringBoot + 事件溯源 + CQRS:高一致性与高性能读写分离架构
后端
Java水解2 小时前
Go map 底层原理
后端
南方的耳朵3 小时前
Linux 创建 TAP 类型虚拟设备的命令
后端
掘金码甲哥3 小时前
MetalLB才是给Ingress这个老登做负重前行的那个男人
后端
野犬寒鸦4 小时前
从零起步学习计算机操作系统:内存管理篇
服务器·后端·学习·缓存·面试