Kubernetes Ingress Controller 深度解析:七层负载均衡的实现机制
在 Kubernetes 集群中Ingress Controller是实现七层负载均衡的核心组件。Service 基于四层 TCP/UDP 协议转发而 Ingress 可基于七层 HTTP/HTTPS 协议通过域名和路径做到更细粒度的流量划分。本文将以 Nginx Ingress Controller 为主要载体深度剖析其实现七层负载均衡的完整机制。题外话Kubernetes SIG Network 已于 2025 年 11 月宣布 Ingress NGINX 项目将于 2026 年 3 月退役不再发布新版本、修复漏洞或提供安全更新。但 Ingress API 本身作为 GA 的稳定 API 不会被废弃Ingress Controller 的实现机制和设计思想具有普适性是理解 Kubernetes 流量管理的核心知识。一、基础概念辨析1.1 Ingress API 与 Ingress Controller在 Kubernetes 流量管理中有两个极易混淆的概念Ingress API和Ingress Controller。Ingress APIKubernetes 管理流量的规范用声明式的方式描述外部流量如何进入集群内的 Service——如何通过域名访问服务、如何根据 URL 路径路由到不同后端服务、后端服务是谁、是否启用 HTTPS 加密。Ingress API 是说明书定义了应该怎么做。Ingress ControllerIngress API 的实现组件是具体执行者——监听 Ingress 资源变化将 Ingress 规则转换为实际的反向代理配置接收外部流量并按规则路由处理 TLS 终止提供健康检查、负载均衡、重试等流量治理能力。Ingress API 本身只是一个 API 对象如果没有 Ingress ControllerIngress 资源创建后不会产生任何实际效果。1.2 Ingress 与 Service 的职责边界Service 是四层抽象基于 TCP/UDP 协议主要通过 iptables 或 IPVS 实现转发。Ingress 是七层抽象基于 HTTP/HTTPS通过域名和路径实现精细化路由。两者关系Ingress 是 Service 的 Service。外部请求先到达 Ingress ControllerController 根据 Ingress 规则查找到对应的 Service再通过 Endpoint 查询到 Pod IP 地址最终将请求转发给 Pod。1.3 核心对象与组件Nginx Ingress 由以下三部分构成组件说明Ingress 资源YAML 定义的 API 对象描述转发规则域名、路径、后端 Service 映射Ingress ControllerGo 实现的控制器进程监听资源变化生成 Nginx 配置并管理 Nginx 生命周期Nginx反向代理和负载均衡引擎实际处理流量此外Ingress Controller 还会监听Service、Endpoint、Secret、ConfigMap等辅助资源。1.4 为什么需要 Ingress对比不同服务暴露方式方式层级优点缺点NodePort四层简单、不依赖云平台端口管理困难30000-32767 受限每端口对应一个服务多节点 IP 管理混乱LoadBalancer四层云厂商原生支持无侵入每 Service 需独立 LB成本高昂Ingress七层统一入口支持多 Service集中管理 TLS 证书支持高级路由策略需部署 Controller 组件有一定复杂度Ingress 充当第七层负载均衡器通过统一的入口域名/IP 支持多 Service 的路径和域名路由可集中管理 TLS 证书、应用多种策略。二、Nginx Ingress Controller 架构与工作原理2.1 整体架构Nginx Ingress Controller 在 Kubernetes 集群中以 Deployment 或 DaemonSet 形式运行Pod 内通常运行两个进程Nginx 进程流量处理和Controller 进程Go 实现配置管理。Controller 进程通过 Kubernetes Informer 机制监听 API Server 中 Ingress、Service、Endpoints、Secret、ConfigMap 等资源的变化。2.2 工作流程全景Ingress Controller 实现七层负载均衡的完整流程分为配置同步和请求转发两个阶段。阶段一配置同步监听与事件触发Controller 通过 Kubernetes Informer 监听 Ingress、Service、Endpoints、Secret 等资源的变化。当创建、更新或删除 Ingress 资源时API Server 通过回调机制通知 Controller。构建 Nginx 模型Controller 从集群中读取 Ingresses、Services、Endpoints、Secrets、Configmaps 等对象从零开始重建一个反映集群状态的 Nginx 模型。差异比较与决策将新构建的模型与当前运行的模型进行比较若相等跳过配置生成若仅 Endpoints 变化通过 HTTP POST 将新 Endpoints 列表发送给 Nginx 内的 Lua 处理程序不触发 Nginx 重载若差异超出 Endpoints基于新模型生成新的 Nginx 配置文件替换当前模型触发 Nginx 重载模板渲染Nginx 配置的最终表示通过 Go 模板nginx.tmpl生成以新模型作为模板变量的输入。阶段二请求转发外部客户端发起 HTTP/HTTPS 请求到达 Ingress Controller 暴露的入口通常通过 LoadBalancer 类型的 Service 对外暴露。Nginx 根据 server_name域名进行第一级匹配再根据 location路径进行第二级匹配。匹配到对应规则后Nginx 将请求转发到对应的 upstream一组后端 Pod 的 Endpoints。Ingress Controller 通过 Service 对应的 Endpoint 获取 Pod IP直接将请求转发到 Pod跳过 kube-proxy 的四层转发。2.3 关键设计Nginx 模型NGINX ModelNginx 模型是 Ingress Controller 最核心的设计。其本质是 Controller 维护的一个内部数据结构用来反映当前集群中 Ingress、Service、Endpoint、Secret、ConfigMap 等资源的聚合状态作为生成 Nginx 配置的唯一数据源。为什么需要模型直接原因在于 Kubernetes Informer 机制的局限性Informer 可以在资源变更时触发回调但无法告知这个变更是否会影响最终的 Nginx 配置文件。因此Controller 必须在每次变更时重建模型并与当前模型比较。模型的一个关键用途是检测冲突。例如当多个 Ingress 为同一主机定义了相同路径时规则会按CreationTimestamp排序先创建的规则优先。如果冲突涉及 TLS 配置或影响 Server 块的 annotation同样以最早创建的规则为准。这种设计保证了配置的可预测性。模型构建的冲突解决规则按CreationTimestamp字段排序 Ingress 规则先创建的规则优先同一主机的相同路径在多个 Ingress 中定义时最早规则胜出多个 Ingress 包含同一主机的 TLS 部分时最早规则胜出多个 Ingress 定义影响 Server 块配置的 annotation 时最早规则胜出并发控制模型构建是代价较高的操作通过工作队列work queue和互斥锁sync.Mutex确保同步循环串行执行避免丢失变更并防止并发冲突。2.4 重载策略与动态更新Nginx 配置变更通常需要执行nginx -s reload来生效但重载会中断现有连接影响生产稳定性。Nginx Ingress Controller 通过差异化重载策略和Lua 动态更新两个机制来优化这一问题。2.4.1 差异化重载策略需要重载的场景创建新的 Ingress 资源为现有 Ingress 添加 TLS 部分Ingress annotation 变更影响 Server 块配置Ingress 规则的新增、修改或删除不需要重载的场景仅 Endpoints 变更Pod 扩缩容、滚动更新仅不影响 Nginx 配置的 annotation 变更对于仅 Endpoints 变更的情况Controller 通过 HTTP POST 请求将新的 Endpoints 列表发送给 Nginx 内的 Lua 处理程序Lua 程序动态更新 upstream 配置完全避免 Nginx 重载。这得益于 OpenResty 的 lua-nginx-module。2.4.2 Lua 动态 Upstream 更新当后端 Pod 的 IP 地址发生变化如应用滚动更新、Pod 扩缩容若每次都重载 Nginx 进程会导致长连接中断、请求失败。Nginx Ingress Controller 利用 lua-nginx-module 实现了 upstream 的热更新Controller 将新的 Endpoint 列表通过内部 HTTP API 发送给 Nginx 内的 Lua 处理程序Lua 代码在 Nginx 进程内直接修改 upstream 的后端服务器列表无需reload实现了真正的零中断动态更新。2.4.3 配置热加载的整体流程2.4.4 总结对比变更类型处理方式是否重载对连接的影响新增/删除 Ingress 规则重建模型 → 模板渲染 → 重载是长连接中断TLS 证书更新重建模型 → 模板渲染 → 重载是长连接中断Pod 扩缩容Endpoints 变更重建模型 → Lua 动态更新否无影响仅 annotation 变更不影响 Nginx 配置重建模型后相等 → 跳过否无影响三、七层负载均衡的实现机制3.1 Ingress 资源结构到 Nginx 配置的映射Nginx 实现七层负载均衡的核心配置元素是server虚拟主机、location路由路径和upstream后端服务器组。Ingress 资源通过声明式语法将这些配置要素进行了抽象。映射关系Nginx 配置元素Ingress 字段说明server_namespec.rules[].host域名匹配locationspec.rules[].http.paths[].pathURL 路径匹配proxy_passspec.rules[].http.paths[].backend.service后端 ServiceupstreamService 对应的 Endpoints一组后端 Pod IP以下是一个典型 Ingress 资源配置示例yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress spec: rules: - host: foo.bar.com # → server_name http: paths: - path: /foo # → location /foo pathType: Prefix backend: service: name: s1 # → upstream 对应 s1 的 endpoints port: number: 80 - path: /bar # → location /bar pathType: Prefix backend: service: name: s2 port: number: 803.2 TLS/SSL 终止Ingress 支持在边缘层终止 TLS即 Ingress Controller 负责解密 HTTPS 流量然后将明文 HTTP 请求转发给后端 Pod。这种被称为SSL Termination或TLS Termination的做法主要有以下优势性能优化TLS 加密解密是 CPU 密集型操作将其卸载到 Ingress Controller 可显著减轻后端 Pod 的计算压力。证书集中管理TLS 证书作为 Kubernetes Secret 统一管理无需在每个后端服务中配置证书。简化后端后端 Pod 只需处理 HTTP 请求降低复杂度。配置示例yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-ingress spec: tls: - hosts: - example.com secretName: example-tls-secret # 引用 Secret 中的证书 rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 803.3 高级路由功能3.3.1 金丝雀发布Canary ReleaseNginx Ingress 通过 annotation 提供金丝雀发布能力支持基于 Header、基于 Cookie 和基于权重三种流量切分策略。核心 annotationnginx.ingress.kubernetes.io/canary: true标识为金丝雀 Ingressnginx.ingress.kubernetes.io/canary-by-header根据请求头值判断路由nginx.ingress.kubernetes.io/canary-by-cookie根据 Cookie 值判断路由nginx.ingress.kubernetes.io/canary-weight按百分比分配流量0-100优先级顺序canary-by-header → canary-by-cookie → canary-weight。示例分配 10% 流量到新版本yaml# 稳定版本 Ingress apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: stable-ingress spec: rules: - host: example.com http: paths: - path: / backend: service: name: stable-service port: number: 80 --- # 金丝雀版本 Ingress apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: canary-ingress annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-weight: 10 spec: rules: - host: example.com http: paths: - path: / backend: service: name: canary-service port: number: 803.3.2 URL 重写Nginx Ingress 支持通过 annotation 实现 URL 重写yamlmetadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: example.com http: paths: - path: /something(/|$)(.*) pathType: Prefix backend: service: name: backend-service port: number: 803.3.3 会话保持yamlmetadata: annotations: nginx.ingress.kubernetes.io/affinity: cookie nginx.ingress.kubernetes.io/session-cookie-name: route nginx.ingress.kubernetes.io/session-cookie-expires: 172800 nginx.ingress.kubernetes.io/session-cookie-max-age: 1728003.4 从 Service 到 Pod 的转发链路Ingress Controller 实现七层负载均衡的一个关键设计是直接使用 Endpoints API 绕过 kube-proxy。当 Ingress Controller 需要将请求转发到后端时它不会像普通四层 Service 那样经过 kube-proxy 的 iptables/IPVS 规则链而是直接读取 Endpoints API 获取 Pod 的真实 IP 地址然后由 Nginx 直接向 Pod IP 发起请求。这样设计的原因在于性能优化跳过 kube-proxy 的 iptables 链减少转发延迟。高级负载均衡Ingress Controller 可以在 Nginx 层面实现轮询、最少连接、IP Hash 等高级负载均衡算法而非依赖 kube-proxy 的简单轮询。会话保持通过 Nginx 直接与 Pod 通信可以实现基于 cookie 的会话保持这是通过 kube-proxy 难以实现的。健康检查Ingress Controller 可以主动对 Pod 进行健康检查及时剔除不健康的 Pod。数据流详解Ingress Controller 通过 Informer 监听 Service 变化根据 Service 的 selector 从 Endpoints API 获取匹配 Pod 的 IP 列表将 Pod IP 列表写入 Nginx upstream 配置或通过 Lua 动态更新Nginx 接收外部请求后根据负载均衡算法选择目标 Pod IPNginx 直接与 Pod IP 建立 TCP 连接并转发 HTTP 请求四、常用 Ingress Controller 对比与选型4.1 主流 Ingress Controller 横向对比Controller底层代理配置方式动态更新主要特点Nginx IngressNginx生成 nginx.conf reload需重载除 endpoints 外社区最广生态成熟TraefikTraefik动态配置无需重载服务发现原生支持Dashboard 友好HAProxyHAProxy动态配置可配置无需重载高性能企业级负载均衡算法KongOpenResty/Nginx动态配置 插件无需重载丰富的插件生态认证、限流、日志Istio Ingress GatewayEnvoyxDS 动态配置无需重载与服务网格统一细粒度流量治理Envoy GatewayEnvoyxDS 动态配置无需重载Kubernetes Gateway API 官方参考实现HigressEnvoyxDS 动态配置无需重载阿里云开源支持多协议和多标准4.2 选型建议场景推荐理由简单、稳定、小规模Nginx Ingress社区广泛简单易用但需注意 2026 年 3 月退役需快速迁移80% 场景兼容Traefik原生支持 nginx.ingress 注解几乎无侵入迁移高性能、高并发HAProxy性能卓越连接池算法成熟API 管理、插件丰富Kong丰富插件生态适合 API 网关场景微服务治理、服务网格集成Istio Ingress Gateway统一南北向和东西向流量管理面向未来Gateway APIEnvoy Gateway / Higress原生支持 Gateway API动态配置无重载4.3 Nginx Ingress 退役影响与应对2025 年 11 月Kubernetes SIG Network 宣布 Ingress NGINX 将于2026 年 3 月正式退役届时不再发布新版本、修复漏洞或更新安全补丁。应对方案短期方案迁移到 Traefik其 NGINX Ingress Provider 可原生理解nginx.ingress.kubernetes.io/*annotation约 80% 的场景无需修改 manifests。长期方案迁移到支持 Gateway API 的 Controller如 Envoy Gateway、Higress使用ingress2gateway工具转换 manifests。云厂商方案使用云厂商托管 Ingress Controller如 AWS ALB Ingress Controller、阿里云 ALB Ingress Controller运维成本低。重要说明退役的是Ingress NGINX Controller并非 Nginx 本身也不是 Ingress API。Ingress API 作为 GA 的稳定 APIKubernetes 社区不会将其移除。五、常见面试题与深度追问5.1 Ingress Controller 如何感知集群变化Ingress Controller 通过Kubernetes Informer机制感知集群变化。Informer 是 client-go 库提供的核心组件它与 API Server 建立 Watch 长连接当资源Ingress、Service、Endpoints、Secret 等发生增删改时API Server 会通过 Watch 流将事件推送给 InformerInformer 再通过注册的 ResourceEventHandler 回调函数通知 Controller。5.2 Ingress Controller 重启后配置会丢失吗不会。Ingress Controller 启动时会从 API Server 重新 List 所有 Ingress 资源重建 Nginx 模型并生成配置。Ingress 规则作为 API 对象持久化存储在 etcd 中Controller Pod 重启不影响 Ingress 配置。5.3 Endpoints 变更时如何做到不重载 Nginx通过lua-nginx-module实现。当仅 Endpoints 变更时Controller 将新的 Endpoints 列表通过 HTTP POST 请求发送给 Nginx 内的 Lua 处理程序Lua 程序动态修改 upstream 的后端服务器列表无需执行nginx -s reload实现热更新。5.4 多个 Ingress 规则冲突时如何处理按CreationTimestamp字段排序先创建的规则优先。冲突检测包括同一主机相同路径、同一主机 TLS 配置、影响 Server 块的 annotation 等。这种设计确保了配置的可预测性避免因多个 Ingress 定义同一路径导致行为不确定。5.5 为什么 Ingress Controller 直接转发到 Pod 而不经过 Service主要有四个原因性能优化跳过 kube-proxy 的 iptables 链减少延迟、高级负载均衡可在 Nginx 层面实现轮询、最少连接、IP Hash 等算法、会话保持可基于 cookie 实现无法通过 kube-proxy 实现、健康检查可主动对 Pod 进行健康检查。Ingress Controller 通过 Endpoints API 获取 Pod IP 后直接转发。5.6 Ingress 和 Gateway API 的区别是什么Ingress API设计于 2015 年最初目标只是为 HTTP 流量提供基本路由功能相对有限扩展依赖 annotation工程噩梦。Gateway API是其下一代替代品提供更丰富的路由能力HTTP、TCP、UDP、TLS 等、跨命名空间支持、更细粒度的角色权限分离。Kubernetes 官方推荐使用 Gateway API 而非 Ingress。5.7 Ingress Controller 如何实现高可用多副本部署以 Deployment 形式部署多个副本通过 Service 前端负载均衡分发流量DaemonSet 模式在每个 Node 运行一个 Controller 实例结合 hostNetwork 共享节点网络外部负载均衡器云环境下通过 LoadBalancer 类型的 Service 暴露云厂商 LB 提供高可用保证Pod 反亲和性配置 podAntiAffinity 确保副本分布在不同节点避免单点故障5.8 Ingress Controller 支持哪些负载均衡算法Nginx Ingress 默认使用轮询round-robin算法。可通过 annotation 配置其他算法nginx.ingress.kubernetes.io/load-balance: least_conn最少连接、ip_hashIP Hash用于会话保持、random随机。Ingress Controller 直接在 Nginx 层面实现这些算法而非依赖 kube-proxy。六、总结与展望Ingress Controller 通过将 Kubernetes Ingress 资源动态转换为底层反向代理配置实现了七层负载均衡。核心设计思想可概括为规范与执行器分离Ingress API 定义规则Ingress Controller 执行规则模型驱动配置通过 Nginx 模型聚合集群状态差异化决策是否需要重载分层负载均衡Ingress 负责七层路由Service 负责四层抽象Pod 负责实际处理动态更新优化利用 Lua 实现 endpoints 热更新避免频繁重载影响稳定性