K8s集群两者不同的对外暴露服务的方式
在工作中,我们暴露集群内的服务通常有几种方式,对于普通的http或者https,我们通常使用Ingress + Nginx ,对于原始的TCP或者UDP端口服务,可能需要选择 LoadBalancer ,它们的核心区别在于工作层级、协议支持和流量处理逻辑
1. 架构层级与协议支持
特性 | Ingress + Nginx | LoadBalancer |
---|---|---|
OSI 层级 | 应用层(L7) | 传输层(L4) |
支持的协议 | HTTP/HTTPS/HTTP2/WebSocket | TCP/UDP(原始协议透传) |
TLS 终止 | ✅ 可在 Ingress 层终止 HTTPS(解密后转HTTP) | ❌ 需后端自行处理加密 |
URL 路径路由 | ✅ 支持 /path 路由到不同服务 | ❌ 只能通过端口区分服务 |
2. 流量处理逻辑对比
Ingress + Nginx 的工作流程
- 客户端发起 HTTPS 请求(如
https://example.com
) - Nginx Ingress Controller:
- 终止 TLS(使用配置的证书解密流量)
- 根据
Ingress
规则路由到对应 Service - 默认以 HTTP 协议转发到后端 Pod(除非配置
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
)
- 后端 Pod 收到明文 HTTP 请求
LoadBalancer 的工作流程
- 客户端直接发送原始流量(TCP/UDP)
- 云厂商的 LoadBalancer(如 AWS NLB、GCP LB):
- 不解析应用层内容(无法识别 HTTP/HTTPS)
- 单纯转发数据包到后端节点的 NodePort
- Pod 直接收到原始流量(需自行处理 TLS 解密)
3. 关键差异场景
场景 1:HTTPS 服务
-
Ingress + Nginx:
# Ingress 配置示例(自动 HTTPS 终止) spec:tls:- hosts:- example.comsecretName: my-tls-secretrules:- host: example.comhttp:paths:- path: /backend:serviceName: my-serviceservicePort: 80
- 客户端 ↔ Nginx:HTTPS(加密)
- Nginx ↔ Pod:HTTP(明文)
-
LoadBalancer:
# Service 配置示例(需 Pod 自己处理 TLS) spec:ports:- name: httpsport: 443targetPort: 443protocol: TCP
- 客户端 ↔ Pod:全程 HTTPS(Pod 需加载证书)
场景 2:UDP 服务(如 STUN/VoIP)
-
Ingress + Nginx:
❌ 不支持(Nginx Ingress 仅限 HTTP 系协议) -
LoadBalancer:
✅ 完美支持(如 Coturn 的 UDP 3478 端口)ports: - name: stun-udpport: 3478protocol: UDP
4. 性能与高级功能
特性 | Ingress + Nginx | LoadBalancer |
---|---|---|
负载均衡算法 | 支持加权轮询、最少连接等 | 通常仅限轮询(依赖云厂商实现) |
WAF 集成 | ✅ 可集成 Web 应用防火墙 | ❌ 无法解析 HTTP 内容 |
流量镜像 | ✅ 支持 | ❌ 不支持 |
客户端真实 IP | 需配置 X-Forwarded-For | 需设置 externalTrafficPolicy: Local |
5. 如何选择?
-
选择 Ingress + Nginx 当:
- 暴露 HTTP/HTTPS 服务
- 需要基于域名或路径的路由
- 希望集中管理 TLS 证书
- 需要 L7 功能(如重定向、速率限制)
-
选择 LoadBalancer 当:
- 暴露非 HTTP 协议(如数据库、STUN/UDP、游戏服务器)
- 需要直接透传原始 TCP/UDP 流量
- 云厂商负载均衡器满足性能需求
常见误区
-
“LoadBalancer 也能处理 HTTPS?”
- ❌ 不能。云厂商的 L4 LB 只做端口转发,HTTPS 解密必须由后端完成。
-
“Ingress 能替代 LoadBalancer?”
- ❌ 不能。Ingress 本身需要
LoadBalancer
或NodePort
类型的 Service 作为底层支撑。
- ❌ 不能。Ingress 本身需要
-
“为什么 Coturn 不能用 Ingress?”
- STUN/TURN 依赖 UDP 协议和原始数据包,而 Ingress 是 HTTP 网关,无法处理此类流量。