云网络中负载均衡如何访问后端vm

57 阅读6分钟

这是一个非常深入且贴近生产实践的问题,涉及 OpenStack、Nginx 负载均衡、Underlay 网络、虚拟机后端 的集成架构。

我们来详细解析:在 OpenStack 中如何使用 Nginx 实现云负载均衡,特别是当流量是 Underlay(物理网络) ,后端是 虚拟机(VM) 的场景。

一、核心问题澄清

你提到:

“使用 Nginx 实现云负载均衡,后端的实服务器是虚拟机,进入云的流量是 Underlay”

这其实描述了两种可能的架构模式:

  1. Nginx 部署在物理机(Underlay 网络)上,代理访问 OpenStack 内的虚拟机
  2. Nginx 部署在 OpenStack 内(作为 VM 或容器),但处理来自 Underlay 的流量

我们重点分析 第一种更典型的生产架构
👉 Nginx 部署在物理机(Underlay)上,作为外部流量入口,负载均衡到 OpenStack 内的虚拟机(VM)


✅ 二、整体架构图(文字描述)

text
深色版本
+---------------------+
|     外部客户端       |
+----------+----------+
           |
           | 流量进入 Underlay 网络
           ↓
+----------v----------+     +-------------------------+
|  Nginx LB (物理机)   |<--->| OpenStack Neutron 网络   |
|  - VIP: 10.1.1.100   |     |  - 租户网络(VXLAN/GRE) |
|  - 监听 80/443       |     |  - 虚拟机 VM1, VM2, VM3  |
+----------+----------+     +------------+--------------+
           |                              |
           | 通过物理网络可达              | 通过隧道(VXLAN)封装
           ↓                              ↓
     Underlay 网络                  Overlay 网络(租户隔离)

✅ 三、关键组件说明

组件说明
Nginx LB(物理机)部署在物理服务器上,直接接入数据中心 Underlay 网络(如 10.1.1.0/24)
VIP(Virtual IP)Nginx 绑定的公网或内网 IP,如 10.1.1.100,对外提供服务
OpenStack Neutron负责虚拟网络管理,支持 VXLAN/GRE 隧道实现租户隔离
VM(后端服务器)运行在 OpenStack 中的虚拟机,如 Web 服务器,IP 为 192.168.1.10
Underlay 网络物理网络(L3),Nginx 所在的网络平面
Overlay 网络虚拟网络(L2 over L3),VM 之间的通信网络

✅ 四、实现难点:Nginx 如何访问 OpenStack 内的 VM?

Nginx 在物理机(Underlay),VM 在虚拟网络(Overlay),默认不可达

🔹 解决方案:让 Nginx 能访问 VM 的网络

非常关键的补充:租户网络是 VXLAN 网络

这意味着 OpenStack 使用 Overlay 网络 实现租户隔离,虚拟机(VM)运行在 VXLAN 隧道封装的逻辑网络中,其 IP 地址对 Underlay 网络不可见。

我们现在聚焦于:

如何让部署在 Underlay 物理网络上的 Nginx 负载均衡器,访问位于 VXLAN Overlay 网络中的租户虚拟机?


✅ 一、核心挑战

问题说明
❌ 网络不可达Nginx 在物理网络(如 10.1.1.0/24),VM 在 VXLAN 虚拟网络(如 192.168.1.0/24),默认无法通信
❌ 封装隔离VXLAN 是 L2 over L3,数据包被封装在 UDP 中,物理机无法直接解封装
❌ ARP 不可达Nginx 发 ARP 请求,VM 不会响应(不在同一广播域)

🔹 Nginx 无法像访问普通服务器一样直接 proxy_pass192.168.1.10


✅ 二、解决方案(基于 VXLAN 租户网络)

以下是 在租户为 VXLAN 网络的前提下,让 Nginx(Underlay)访问 VM 的可行方案。


✅ 方案 1:Nginx 物理机接入 VXLAN 网络(推荐,高性能)

让物理机“加入”VXLAN 网络,成为 VXLAN 的 端点(VTEP)

🔹 实现原理:

  • 在 Nginx 物理机上创建 VXLAN 接口
  • 配置 VXLAN 隧道到 OpenStack 的 VXLAN 网关(通常是计算节点或网络节点)
  • 将租户网络 IP 分配给 Nginx 物理机

🔧 配置示例:

bash
深色版本
# 假设 VXLAN VNI=100,租户网络 192.168.1.0/24
# 网络节点 IP: 10.1.1.10(VTEP IP)

# 创建 VXLAN 接口
ip link add vxlan0 type vxlan id 100 \
    dev eth0 \
    dstport 4789 \
    remote 10.1.1.10  # 指向网络节点或任意计算节点

# 配置 IP
ip addr add 192.168.1.100/24 dev vxlan0
ip link set vxlan0 up

# 添加 ARP 静态条目(可选)
arp -s 192.168.1.10 aa:bb:cc:dd:ee:ff

📌 说明:

  • dstport 4789:VXLAN 标准端口
  • remote 10.1.1.10:指向 OpenStack 网络节点或计算节点 IP
  • 192.168.1.100:Nginx 在租户网络中的 IP

✅ Nginx 配置:

nginx
深色版本
upstream backend {
    server 192.168.1.10;  # VM1(租户网络 IP)
    server 192.168.1.11;  # VM2
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}

✅ 效果:Nginx 和 VM 在同一 VXLAN 网络,可直接通信

✅ 优点:

  • 高性能,无 NAT 开销
  • 路径最短,延迟低
  • 支持双向通信

⚠️ 要求:

  • 网络节点或计算节点需支持 VXLAN 外部访问
  • 防火墙开放 UDP 4789
  • 需要与 OpenStack 网络团队协作

✅ 方案 2:使用 Floating IP + SNAT/DNAT(最常见)

让每个后端 VM 绑定一个 Floating IP(来自 Underlay 网段)

🔹 实现流程:

  1. OpenStack Neutron 为 VM 分配 Floating IP(如 10.1.1.201
  2. 网络节点通过 iptables DNAT 将 10.1.1.201:80 → 192.168.1.10:80
  3. Nginx 配置 upstream 为 Floating IPs
nginx
深色版本
upstream backend {
    server 10.1.1.201;  # VM1 的 Floating IP
    server 10.1.1.202;  # VM2 的 Floating IP
}

🌐 流量路径:

text
深色版本
Nginx → 10.1.1.201:80
        ↓
网络节点(DNAT)→ 192.168.1.10:80(VXLAN 封装)
        ↓
VM1 处理请求,响应返回网络节点 → SNAT 回 10.1.1.201 → Nginx

✅ 优点:

  • 简单,无需修改物理网络
  • OpenStack 原生支持

⚠️ 缺点:

  • 每个 VM 需要一个公网 IP(成本高)
  • 流量路径长(必须经过网络节点)
  • NAT 可能成为瓶颈

✅ 方案 3:使用 OpenStack Octavia(云原生 LBaaS)

不使用外部 Nginx,而是使用 OpenStack 原生的 Octavia,其后端使用 Nginx 实现。

🔹 架构:

  • Octavia 控制面创建 VIP(在 Underlay 网络,如 10.1.1.100
  • Octavia 调度一个 Nginx Amphora 虚拟机(运行在租户 VXLAN 网络中)
  • Amphora Nginx 转发到后端 VM
text
深色版本
外部流量 → VIP 10.1.1.100(网络节点路由)
           ↓
     Nginx Amphora VM(192.168.1.100,在 VXLAN 中)
           ↓
       后端 VM1, VM2(192.168.1.10/11

✅ 优点:

  • 完全云原生,自动扩缩容
  • 高可用(Amphora HA)
  • 无需外部物理机介入

⚠️ 缺点:

  • 性能受限于 VM 和 VXLAN 封装
  • 运维复杂度高

✅ 方案 4:使用物理网络网关(External Gateway)

在网络节点上配置 静态路由策略路由,让特定 Underlay IP 段能访问 VXLAN 内部。

🔹 实现:

  • 在网络节点上添加路由:

    bash
    深色版本
    ip route add 192.168.1.0/24 via 10.1.1.200 dev eth0
    
  • 10.1.1.200 是 Nginx 的 IP

  • 网络节点作为 VXLAN 网关,解封装后转发

✅ 但需确保 Nginx 能响应 ARP,且 OpenStack 允许外部访问


✅ 三、关键配置细节(以方案 1 为例)

1. VXLAN 隧道建立

  • 确保 Nginx 物理机与 OpenStack 网络节点之间 UDP 4789 互通
  • VXLAN ID(VNI)必须与租户网络一致

2. ARP 解析

  • VXLAN 是 L2 广播,但物理机无法参与
  • 可配置 静态 ARP 或使用 ARP 代理
bash
深色版本
arp -s 192.168.1.10 <VM-MAC>

3. MTU 问题

  • VXLAN 封装增加 50 字节头
  • 物理网络 MTU 应 ≥ 1550
  • Nginx 物理机 VXLAN 接口 MTU 设置为 1450
bash
深色版本
ip link set vxlan0 mtu 1450

4. 安全组(Security Group)

  • 确保 OpenStack 安全组允许来自 192.168.1.100(Nginx)的流量
  • 方向:Ingress, Port: 80, Source: 192.168.1.100/32

✅ 四、总结:在 VXLAN 租户网络下,Nginx 实现负载均衡的方式

方案是否推荐说明
✅ Nginx 接入 VXLAN(VTEP)⭐ 强烈推荐高性能,直接通信,适合 NFV
✅ 使用 Floating IP✅ 推荐简单,原生支持,但成本高
✅ 使用 Octavia + Nginx Amphora✅ 推荐云原生,自动化,适合大规模
❌ 直接 proxy_pass 私网 IP❌ 不可能VXLAN 隔离,无法路由

✅ 最终建议

如果你有权限修改网络配置,优先选择:

🎯 方案 1:Nginx 物理机作为 VXLAN 端点接入租户网络

  • 性能最优
  • 路径最短
  • 支持大规模流量

如果你只能使用标准 OpenStack 功能,选择:

🎯 方案 2:Floating IP + Nginx

  • 简单可靠
  • 无需网络改造

如果你希望完全云原生,选择:

🎯 方案 3:Octavia

  • 自动化、弹性、高可用

📌 记住:在 VXLAN 租户网络中,外部设备必须通过“隧道接入”或“NAT 映射”才能访问内部 VM,这是 Overlay 网络的本质。