4. Ingress流量入口高可用

Ingress Controller 本身只是集群内的一组 Pod,它要真正对外提供七层入口能力,必须先解决“流量如何从集群外到达这些 Pod”的问题。这一层通常由 Service 或主机网络承担,而 Service 的不同类型决定了入口的可用性边界、故障域和运维方式。理解 LoadBalancer、NodePort、HostNetwork 以及外部负载均衡器集成这四种路径,是设计高可用入口的前提。

四种入口暴露方式的本质差异

从数据面看,四者的区别集中在三个问题:外部流量首先落到哪里、由谁做第一层转发、以及故障时流量能否自动切换。

  • LoadBalancer Service:由云厂商或 MetalLB 等控制器分配一个虚拟 IP(VIP),外部流量先到 VIP,再由负载均衡器转发到各节点的 NodePort,最后经 kube-proxy 或 IPVS 到达 Ingress Controller Pod。VIP 本身通常具备健康检查与多节点后端,天然具备一定高可用能力。
  • NodePort:在每个节点上开放同一端口(默认 30000–32767),外部流量直接打到任意节点的该端口。它不提供 VIP,也不做节点级健康检查,客户端需要自己选择节点或依赖前置负载均衡器。
  • HostNetwork:Ingress Controller Pod 直接使用宿主机网络命名空间,监听节点 IP 的 80/443。没有 Service 转发环节,路径最短、延迟最低,但端口被独占,且 Pod 调度到哪些节点,入口就只存在于哪些节点。
  • 外部负载均衡器集成:在集群外已有 F5、Nginx、LVS 或云 SLB 时,把节点或 NodePort 作为后端池,由外部设备统一做 VIP、健康检查和流量分发。它把高可用责任交给外部设备,集群侧只提供稳定的后端端点。

下面的图展示了四种方式从客户端到 Ingress Controller Pod 的流量路径与关键差异点。

客户端 Client ① LoadBalancer ② NodePort ③ HostNetwork ④ 外部负载均衡器 云 LB / MetalLB VIP + 健康检查 Node A :30080 Node B :30080 kube-proxy IPVS / iptables Ingress Pod nginx / traefik Node A :30080 Node B :30080 kube-proxy IPVS / iptables Ingress Pod nginx / traefik Node A :80/443 Node B :80/443 Ingress Pod hostNetwork: true F5 / Nginx / LVS VIP + 健康检查 Node A :30080 Node B :30080 kube-proxy IPVS / iptables Ingress Pod nginx / traefik 高可用关键点: ① VIP 自动漂移 + 多节点后端;② 无 VIP,需客户端或前置 LB 选节点;③ 路径最短但入口节点固定;④ 高可用由外部设备承担,集群只提供稳定后端。 共同要求:Ingress Controller 至少 2 副本、反亲和调度、就绪探针准确反映真实可用性。

LoadBalancer Service:云上与裸金属的两种实现

在公有云中,type: LoadBalancer 的 Service 会触发云控制器向云平台申请一个 SLB/CLB 实例,并自动把集群节点注册为后端。以阿里云 ACK 为例,一个典型的 Service 定义如下:

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  annotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-flag: "on"
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-type: "tcp"
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app.kubernetes.io/name: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443

这里有两个关键参数。第一是 externalTrafficPolicy:设为 Local 时,流量只转发到本节点上运行的 Ingress Pod,能保留客户端真实源 IP,但要求每个节点都有 Pod;设为 Cluster 时,流量可能被二次转发到其他节点,源 IP 会丢失,但后端覆盖更均匀。第二是健康检查类型,TCP 检查只能判断端口是否监听,HTTP 检查才能识别 Ingress Controller 是否真正可服务。

在裸金属环境中没有云控制器,需要用 MetalLB 等方案提供 VIP。MetalLB 的 L2 模式通过 ARP 宣告 VIP,同一时刻只有一个节点响应,故障时切换到其他节点,切换时间通常在秒级;BGP 模式则与上游路由器建立邻居,把 VIP 作为路由发布,收敛更快,但需要网络设备配合。

NodePort 与 HostNetwork 的取舍

NodePort 的最大问题是客户端必须知道节点 IP,且节点故障后客户端不会自动切换。因此它很少单独暴露给最终用户,更多是作为 LoadBalancer 或外部负载均衡器的后端。它的优势是简单、不依赖任何外部组件,适合测试环境或作为兜底入口。

HostNetwork 则把 Ingress Controller 直接绑到节点 80/443 端口。它的性能最好,因为没有 kube-proxy 的 DNAT 环节,也没有 Service 的额外一跳。但代价是:端口冲突风险高,Pod 必须调度到指定节点,节点故障时入口直接不可用。实践中通常配合 DaemonSet 让每个节点都运行一个 Ingress Pod,再在前端挂一个外部负载均衡器做健康检查和流量分发。

使用 HostNetwork 时,Ingress Controller 的 Pod 会占用宿主机 80/443 端口。如果节点上已有 Nginx、Apache 或其他服务监听这些端口,会导致 Pod 启动失败或端口冲突。部署前应确认节点端口占用情况,并避免与其他 HostNetwork 工作负载冲突。

外部负载均衡器集成:把高可用交给专业设备

当企业已有 F5、Nginx Plus、LVS 或云 SLB 时,最稳妥的做法是让外部设备承担 VIP 和健康检查,集群侧只提供稳定的后端端点。后端可以是 NodePort,也可以是 HostNetwork 下的节点 IP:80/443。

以 Nginx 作为外部负载均衡器为例,后端池配置如下:

upstream ingress_backend {
    least_conn;
    server 10.0.1.11:30080 max_fails=3 fail_timeout=10s;
    server 10.0.1.12:30080 max_fails=3 fail_timeout=10s;
    server 10.0.1.13:30080 max_fails=3 fail_timeout=10s;
    keepalive 32;
}

server {
    listen 80;
    location / {
        proxy_pass http://ingress_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_next_upstream error timeout http_502 http_503;
    }
}

这里 max_fails=3 fail_timeout=10s 表示 10 秒内失败 3 次就把该后端摘除,10 秒后再尝试恢复。proxy_next_upstream 让请求在遇到 502/503 时自动重试下一个后端,这是外部负载均衡器提供高可用的核心机制。健康检查建议使用 HTTP 探针指向 Ingress Controller 的 /healthz 端点,而不是简单 TCP 检查,因为 TCP 端口监听不代表七层转发正常。

高可用设计检查清单

检查项 LoadBalancer NodePort HostNetwork 外部 LB
是否有 VIP 有 无 无 有
节点故障自动切换 支持 不支持 不支持 支持
保留客户端源 IP Local 模式支持 需 Local 模式 天然支持 需配置 X-Forwarded-For
额外网络跳数 2–3 跳 2 跳 0 跳 1–2 跳
依赖外部组件 云控制器 / MetalLB 无 无 外部 LB 设备

无论选择哪种方式,Ingress Controller 自身的高可用都是前提:至少 2 个副本、通过 podAntiAffinity 分散到不同节点、配置 readinessProbe 指向真实健康端点、并设置合理的 terminationGracePeriodSeconds 让旧 Pod 在摘除后仍能处理完存量连接。入口层的高可用不是单一组件的能力,而是“外部 VIP + 节点冗余 + Controller 多副本 + 健康检查”共同构成的链路。

生产环境推荐组合:云上使用 LoadBalancer Service + externalTrafficPolicy: Local;裸金属使用 MetalLB BGP 模式或外部 F5/Nginx + NodePort 后端;HostNetwork 仅在追求极致延迟且能接受节点级故障域时使用。任何方案都应至少保留两个入口节点,并验证单节点宕机时业务不中断。