Skip to content

第13章 NodeIP:NodePort vs VIP:NodePort 深度解析

本章分析直接用 <NodeIP>:<NodePort> 访问与通过 <VIP>:<NodePort>(负载均衡器)访问的区别、潜在问题、流量均衡性,以及生产环境最佳实践。


13.1 两种访问方式是什么

NodeIP:NodePort

直接访问某个 Kubernetes 节点的 IP 地址和该 Service 的 NodePort:

bash
curl http://192.168.1.10:30080
curl http://192.168.1.11:30080
curl http://192.168.1.12:30080

特点:

  • 每个节点都会监听这个 NodePort。
  • 外部客户端需要知道具体节点的 IP。
  • 访问的是单个节点,不是集群整体入口。

VIP:NodePort

通过一个虚拟 IP(VIP)访问,VIP 由外部负载均衡器、MetalLB、Keepalived 等提供:

bash
curl http://10.0.0.100:30080

其中 10.0.0.100 是 VIP,后端可能是:

text
192.168.1.10:30080
192.168.1.11:30080
192.168.1.12:30080

特点:

  • 客户端只感知一个入口地址。
  • VIP 层负责健康检查和高可用。
  • 流量会先到达 VIP,再由 VIP 分发到某个节点的 NodePort。

13.2 直接用 NodeIP:NodePort 的问题

单点故障

如果你只配置一个节点的 IP:

bash
curl http://192.168.1.10:30080

一旦 192.168.1.10 宕机、网络中断、kube-proxy 异常,这个访问入口就彻底失效。

即使 Service 后端还有健康的 Pod,客户端也无法访问。

流量不均衡

如果所有客户端都写死同一个 NodeIP:

text
所有流量 → 192.168.1.10:30080
  • 这台节点的网络带宽、CPU、连接数会成为瓶颈。
  • 后端 Pod 的负载分布取决于 externalTrafficPolicy。

源 IP 问题

默认 externalTrafficPolicy=Cluster 时:

  • 流量进入任意节点后,可能被 SNAT 成节点 IP。
  • Pod 看到的源 IP 是节点 IP,不是真实客户端 IP

客户端维护成本高

如果客户端需要高可用,必须自己维护多个 NodeIP 列表并做故障切换。这本质上是把负载均衡的职责推给了客户端。

节点迁移/扩缩容不友好

节点 IP 可能因为故障替换、扩缩容、云厂商重建而变化。客户端写死 NodeIP 后,每次节点变动都要修改配置。


13.3 通过 VIP:NodePort 访问

VIP 的来源

场景VIP 提供方式说明
公有云云厂商 LoadBalancer如 AWS ELB、阿里云 SLB、腾讯云 CLB
裸金属/自建MetalLB通过 BGP 或 Layer 2 宣告 VIP
高可用需求Keepalived + HAProxy/Nginx传统方案
企业内部F5、A10、LVS 等硬件/软件负载均衡已有基础设施

流量路径

text
外部客户端


   VIP:NodePort

    ├── LB 健康检查 → 剔除异常节点


┌─────────────────┐
│ 负载均衡器       │
│ (round-robin/   │
│  least-conn)    │
└────────┬────────┘

    ┌────┼────┐
    ▼    ▼    ▼
Node-1 Node-2 Node-3
:30080 :30080 :30080
    │    │    │
    ▼    ▼    ▼
 Pod-A Pod-B Pod-C

VIP 的优势

  • 高可用:某个节点故障,VIP 自动将流量切到其他节点。
  • 入口统一:客户端只配一个地址。
  • 健康检查:LB 自动剔除没有后端 Pod 或节点本身故障的后端。
  • 负载分发:由 LB 在多个节点间分配流量。

13.4 流量均衡性分析

externalTrafficPolicy=Cluster 时

text
客户端 → VIP → 随机/轮询选择一个 Node → kube-proxy 再负载均衡到所有 Pod
  • 节点间:由 VIP 的调度算法决定,通常较均衡。
  • Pod 间:kube-proxy 会再次负载均衡到所有后端 Pod,整体相对均衡。
  • 缺点:流量可能经过两次转发;源 IP 被 SNAT。

externalTrafficPolicy=Local 时

text
客户端 → VIP → 选择一个 Node → 只能转发到该 Node 上的 Pod
  • Pod 间流量取决于 Pod 分布。
  • 如果 Pod 分布不均:
text
Node-1: 3 个 Pod
Node-2: 1 个 Pod
Node-3: 0 个 Pod

VIP 轮询 3 个节点:

  • 1/3 流量到 Node-1,由 3 个 Pod 分摊。
  • 1/3 流量到 Node-2,由 1 个 Pod 处理。
  • 1/3 流量到 Node-3,没有 Pod,连接被丢弃

结论:Pod 分布不均时,Local 模式会导致明显的流量不均衡,甚至丢包。

为什么会不均衡?

VIP 的负载均衡粒度是节点,不是 Pod。

  • VIP 认为每个节点是等权的。
  • 但每个节点上的 Pod 数量可能不同。
  • 因此 VIP 轮询节点 ≠ Pod 间轮询。

如何优化 Local 模式下的均衡性?

  1. 使用 Pod 拓扑分布约束(Topology Spread Constraints)
yaml
spec:
  topologySpreadConstraints:
    - maxSkew: 1
      topologyKey: kubernetes.io/hostname
      whenUnsatisfiable: DoNotSchedule
      labelSelector:
        matchLabels:
          app: web
  1. LB 启用基于 Pod 数量的权重调度
  2. LB 健康检查配合 Local 模式,避免发给空节点

13.5 生产环境建议

  1. 不要直接暴露 NodeIP:NodePort 给客户端,除非临时测试。
  2. 优先使用 LoadBalancer 或 Ingress
  3. 裸金属/自建集群使用 MetalLB
  4. 使用 Ingress 做七层路由
  5. 监控和告警:监控每个节点的 NodePort 连接数、Pod 间流量分布,对 Local 模式告警空节点或 Pod 分布不均。

13.6 本章小结

对比项NodeIP:NodePortVIP:NodePort
可用性低,单节点故障即中断高,VIP 自动剔除故障节点
入口统一性差,多个 NodeIP好,一个 VIP
流量均衡差,依赖客户端选择较好,依赖 VIP 调度
源 IP 保留看 externalTrafficPolicy看 externalTrafficPolicy
维护成本
生产推荐度❌ 不推荐✅ 推荐

本章练习

  1. 画出 NodeIP:NodePort 和 VIP:NodePort 的数据包路径图。
  2. 分析:在什么情况下 Local 模式会比 Cluster 模式更均衡?
  3. 为你的业务场景选择合适的访问方式,并说明理由。