Ingress 控制器原理:资源定义、工作流程与控制面/数据面分离
Ingress 是 Kubernetes 中管理集群外部访问流量的标准 API 对象,而 Ingress 控制器则是负责将 Ingress 资源转化为实际路由规则并执行流量转发的核心组件。理解 Ingress 控制器的原理,需要从资源定义、工作流程以及控制面与数据面的分离架构三个维度展开。
2.1 Ingress 资源定义
Ingress 资源通过声明式 YAML 定义,描述了外部流量如何路由到集群内的 Service。一个典型的 Ingress 资源包含以下核心字段:
| 字段 | 说明 | 示例值 |
|---|---|---|
| apiVersion | API 版本 | networking.k8s.io/v1 |
| kind | 资源类型 | Ingress |
| metadata.name | Ingress 名称 | my-app-ingress |
| spec.ingressClassName | 指定使用的 Ingress 控制器 | nginx |
| spec.rules | 路由规则列表 | host + http.paths |
| spec.tls | TLS 证书配置 | secretName + hosts |
以下是一个完整的 Ingress 资源定义示例,展示如何将 app.example.com 的流量路由到 app-service 的 80 端口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
tls:
- hosts:
- app.example.com
secretName: app-tls-secret
关键点:Ingress 资源本身只是一个声明,不执行任何流量转发。真正的路由逻辑由 Ingress 控制器实现。spec.ingressClassName 字段在 v1 版本中替代了旧的 annotation 方式,用于明确指定控制器。
2.2 Ingress 控制器工作流程
Ingress 控制器的工作流程可以概括为“监听-转换-同步”三个核心步骤。控制器通过 Kubernetes API 持续监听 Ingress、Service、EndpointSlice 等资源的变化,并将这些声明式配置转换为数据面的实际路由规则。
- 监听阶段:控制器通过 Informer 机制监听 Ingress 资源及其依赖的 Service、Secret 的变化事件。
- 转换阶段:控制器将 Ingress 规则转换为数据面(如 Nginx、Envoy)的配置文件。例如,Nginx Ingress 控制器会生成
nginx.conf。 - 同步阶段:控制器将生成的配置文件推送到数据面进程,触发热加载或重载,使新规则生效。
性能关键:控制器的同步效率直接影响网关的收敛速度。在大规模集群中,EndpointSlice 的变更频率极高,控制器需要具备增量更新能力,避免全量重载导致连接中断。
2.3 控制面与数据面分离架构
现代云原生网关普遍采用控制面(Control Plane)与数据面(Data Plane)分离的架构设计。这种架构将路由决策逻辑与流量转发逻辑解耦,带来更高的可扩展性和运维灵活性。
| 维度 | 控制面(Control Plane) | 数据面(Data Plane) |
|---|---|---|
| 职责 | 监听 API、解析规则、生成配置 | 接收流量、执行转发、负载均衡 |
| 组件示例 | Ingress 控制器进程(如 nginx-ingress-controller) | Nginx、Envoy、HAProxy 代理进程 |
| 资源消耗 | CPU 密集型(配置解析、模板渲染) | 网络 I/O 密集型(连接处理、TLS 卸载) |
| 扩缩容策略 | 按 Ingress 资源数量扩缩 | 按流量吞吐量扩缩 |
| 故障影响 | 不影响已有路由规则,仅新规则无法生效 | 直接影响流量转发,导致服务中断 |
在 Kubernetes 中,Ingress 控制器通常以 Deployment 形式运行,控制面与数据面可以运行在同一个 Pod 内(如 Nginx Ingress),也可以分离为独立的微服务(如 Contour + Envoy)。分离架构的优势在于:
- 独立扩缩容:控制面与数据面可以根据各自的负载特征独立进行水平扩缩,避免资源争抢。
- 灰度升级:可以单独升级控制面逻辑而不影响正在处理流量的数据面进程。
- 故障隔离:控制面故障不会导致已建立的连接中断,数据面可以继续基于缓存的路由表转发流量。
注意:在 Nginx Ingress 控制器的默认部署模式中,控制面与数据面共享同一个容器。这意味着配置重载期间,Nginx worker 进程会短暂中断。对于长连接敏感的业务,建议使用支持热重载的控制器(如 Envoy 或基于 Lua 的 Nginx 变体)。
2.4 控制器选型对比
社区中主流的 Ingress 控制器在控制面与数据面的实现方式上存在差异,直接影响资源配额模型的设计。以下是三种常见控制器的对比:
| 控制器 | 数据面 | 配置同步方式 | 热重载支持 | 资源配额关注点 |
|---|---|---|---|---|
| Nginx Ingress | Nginx | 生成 nginx.conf + reload | 部分(Lua 模块可减少中断) | ConfigMap 大小、reload 频率 |
| Contour | Envoy | xDS 协议动态推送 | 完全支持 | EndpointSlice 变更速率、xDS 流数 |
| Traefik | 自研 Go 代理 | 内存热更新 | 完全支持 | 规则数量、中间件链长度 |
架构决策:在资源配额模型设计中,如果选择 Nginx Ingress,需要重点考虑 ConfigMap 的尺寸限制和 reload 对长连接的影响;如果选择 Contour 或 Traefik,则需要关注控制面与数据面之间的通信开销以及 xDS 流的稳定性。