Administrator
发布于 2026-07-29 / 2 阅读
0
0

cluster模式下的svc如何使用外部ng负载

注:该问题背景是,我在学习k8s技能时看到最新的云厂商使用clb+istio的模式实现服务网关注册管理,那么如果自建k8s如何实现呢?只能是nginx做负载,那么如果集群中的svc都是cluster怎么办呢?

核心解答:如果集群 Service 是 ClusterIP,外部 Nginx 怎么办?

这是一个非常经典的痛点。因为 ClusterIP 是 K8s 集群内部的虚拟 IP,外部的 Nginx 是无法直接访问 ClusterIP 的

要解决这个问题,业界通常有以下三种最佳实践:

方案 A:外部 Nginx 对接 NodePort(最主流)
外部 Nginx 不直接连 Pod,而是把后端指向 K8s 集群各个节点的 NodePort。

  • 流量链路外部用户 -> 外部 Nginx -> K8s 节点 NodePort -> kube-proxy -> ClusterIP Service -> Pod

  • 缺点:外部 Nginx 需要手动维护 K8s 节点的 IP 列表。当 K8s 节点扩缩容时,需要手动修改 Nginx 配置并 reload。

方案 B:外部 Nginx 对接 HostNetwork(性能最优)
正如我们之前讨论的,将 Istio 的入口网关(istio-ingressgateway)部署为 DaemonSet 并开启 hostNetwork: true

  • 流量链路外部用户 -> 外部 Nginx -> K8s 节点物理IP:端口 -> Istio Gateway Pod -> Service -> Pod

  • 优点:省去了 NodePort 和 kube-proxy 的转发,性能极佳。

  • 缺点:同样需要外部 Nginx 手动维护 K8s 节点的 IP 列表。

方案 C:外部 Nginx 动态对接 Pod IP(高级自动化)
如果你希望外部 Nginx 能够像 K8s 内部一样,直接感知 Pod 的上下线并自动更新 upstream,可以使用专门的控制器组件(例如 NLK - NGINX Load Balancer for Kubernetes)。

  • 原理:NLK 部署在 K8s 内部,它会实时 Watch K8s 的 Service 和 Endpoints 变化,一旦发现 Pod IP 变动,就通过 API 自动更新外部 Nginx 的上游配置。

  • 优点:完美解决了外部 Nginx 无法直连 ClusterIP 的问题,且实现了全自动化,无需手动维护节点列表。

NodePort与HostNetwork的区别

这两者的核心区别在于网络命名空间的隔离性以及流量转发的开销

1. 方案一:NodePort(经过 K8s 网络代理)

  • 原理:流量到达节点后,由 K8s 的 kube-proxy 组件(基于 iptables 或 IPVS)进行拦截和转发。

  • 特点:Pod 依然拥有自己独立的网络命名空间和虚拟 IP(ClusterIP)。

  • 优点:保留了 K8s 的网络隔离性,配置相对安全。

  • 缺点:流量多了一层 kube-proxy 的转发,存在微小的性能损耗;且 NodePort 端口范围受限(默认 30000-32767),不够优雅。

2. 方案二:HostNetwork(直接使用宿主机网络)

  • 原理:Pod 直接共享宿主机的网络命名空间。Pod 的 IP 就是宿主机的物理 IP,端口直接绑定在物理网卡上。

  • 特点:流量直达 Pod,没有任何中间代理层。

  • 优点:网络性能达到极致,几乎等同于原生主机通信,延迟极低。

  • 缺点:失去了网络隔离性;极易引发端口冲突(如果同一节点上调度了多个使用该端口的 Pod,会导致启动失败);Pod 副本数不能超过节点数。


评论