NodePort在生产中不够用,因其端口受限(30000–32767)、依赖单节点导致单点故障、缺乏TLS卸载/限速/黑白名单等四层以上控制,且多节点间无健康检查与流量均衡。

Nginx 四层负载均衡可以作为 Kubernetes 集群外部流量的统一入口,有效绕过 NodePort 的端口范围限制、节点单点依赖和流量不均问题。它不替代 Service,而是前置在集群之外,把客户端请求按 TCP 层规则分发到多个 Node 的 NodePort,实现真正的高可用与横向扩展。
为什么 NodePort 在生产中不够用
NodePort 类型的 Service 虽然简单,但存在几个硬性短板:
- 端口固定在 30000–32767 范围内,无法暴露标准端口(如 80、443、22、3306)给外部直接访问
- 客户端必须直连某个具体 NodeIP:NodePort,一旦该节点宕机或网络异常,服务即中断
- Kube-proxy 使用 iptables/ipvs 做内部转发,但外部没有统一入口,无法做连接限速、黑白名单、TLS 卸载等四层以上控制
- 多节点间无自动负载感知,流量容易集中在某几个节点,尤其当使用 DNS 轮询时缺乏健康检查机制
Nginx 四层代理如何对接 Kubernetes NodePort
核心思路是:Nginx(部署在集群外)监听标准端口(如 80/443/3306),然后将 TCP 连接透传到后端多个 Kubernetes Worker 节点的 NodePort 上。整个过程不解析应用层内容,只做 IP+端口转发。
配置示例如下(需确保 Nginx 编译时启用 --with-stream):
stream {
upstream k8s_nodes {
server 192.168.10.11:30080 max_fails=3 fail_timeout=15s;
server 192.168.10.12:30080 max_fails=3 fail_timeout=15s;
server 192.168.10.13:30080 max_fails=3 fail_timeout=15s;
}
server {
listen 80;
proxy_pass k8s_nodes;
proxy_timeout 1h;
proxy_responses 1;
}
server {
listen 443;
proxy_pass k8s_nodes;
proxy_timeout 1h;
proxy_responses 1;
}
}
说明:
- 后端地址填的是各 Worker 节点的物理 IP + 对应的 NodePort(比如你定义的 webapp Service 的 nodePort 是 30080)
- max_fails/fail_timeout 实现主动健康检查:连续失败 3 次后暂停 15 秒,自动剔除异常节点
- proxy_timeout 和 proxy_responses 可防止长连接挂起或空闲断连
对比 LoadBalancer 类型 Service 的优势
云厂商提供的 LoadBalancer(如 AWS ALB、阿里云 SLB)虽能自动绑定弹性 IP 并做健康检查,但存在明显局限:
- 费用高:多数云平台对 LoadBalancer 实例单独计费,且带宽成本叠加
- 绑定强:通常只能关联一个 Service,难以复用同一入口承载多个不同端口的服务(如同时暴露 HTTP+MySQL+SSH)
- 可控性低:策略配置受限于云平台 UI/API,不支持自定义超时、连接数限制、源 IP 透传等精细控制
- 非云环境不可用:私有云、边缘集群、混合部署场景下无法依赖云 LB
而 Nginx 四层方案完全自主可控,可部署在物理机、VM 或容器中,一套配置复用多个协议和端口,还能和已有监控(Prometheus + nginx-module-vts)、日志(syslog + json 格式)体系无缝集成。
关键注意事项与调优建议
要让这套方案稳定运行,需关注以下实操细节:
- 防火墙放行:确保 Nginx 所在机器能访问所有 Worker 节点的 NodePort 端口(如 30080、30443),且 Worker 节点防火墙允许来自 Nginx 主机的入向连接
-
源 IP 保留:默认情况下,Kubernetes 中的 Pod 看到的是 NodeIP 而非真实客户端 IP。若需获取真实 IP,可在 Service 中设置 externalTrafficPolicy: Local,并配合 proxy_protocol(需 Nginx 开启
proxy_protocol on;)传递原始地址 -
连接数限制:在 stream 上下文中添加
limit_conn addr 1000;(配合limit_conn_zone $binary_remote_addr zone=addr:10m;)可防连接洪泛 - SSL 透传:若后端 NodePort 是 HTTPS(如 ingress-nginx 的 30443),Nginx 四层只需透传 TLS 流量,无需证书;若需终止 SSL,则必须改用七层 http{} 配置











