深色模式
Ingress 与 Ingress Controller
摘要:本文解释 Ingress 是什么、为什么必须配合 Ingress Controller 才能生效、常见实现(ingress-nginx、Traefik、Emissary 等)的差异,以及官方“Ingress API 已冻结、推荐 Gateway API”的现状。覆盖版本:Kubernetes v1.28+。
适用版本与前提
- Kubernetes:v1.28+。
- Ingress API:
networking.k8s.io/v1,自 v1.19 起 Stable。 - 工具:
kubectl。 - 前提:理解 Service(见
service.md)。
重要前提:Ingress API 已被冻结
版本相关(关键)
根据 Kubernetes 官方文档,Ingress API 已进入“冻结(frozen)”状态:它仍然 GA、可用、不会从 K8s 中移除,但不再开发、不会有任何进一步改动。官方明确推荐新项目优先使用 Gateway API。 这意味着:本篇讲解的 Ingress 语法在可预见的未来仍然有效、可落地,但新特性(更丰富的路由表达、跨命名空间共享网关等)只会落在 Gateway API 上。生产选型时应在“稳定性”与“未来演进”之间权衡。
背景与问题
Service 的 NodePort/LoadBalancer 只能做四层(TCP/UDP)暴露。当你有多个 HTTP 服务、想按域名/路径路由、统一做 TLS 终止与虚拟主机时,为每个服务各建一个 LB 既贵又难管。Ingress 就是 K8s 的七层(HTTP/HTTPS)入站路由抽象。
Ingress 资源 ≠ 数据面
这是最常见的误解:只写 Ingress 对象不会生效。Ingress 只是一份“期望路由规则”的声明,真正干活的叫 Ingress Controller(一个监听 Ingress 资源、并配置底层代理/负载均衡器的控制器,通常是 Nginx、Envoy、HAProxy 等)。
必须安装 Controller
集群里没有 Ingress Controller 时,kubectl apply 一个 Ingress 资源不会有任何效果,也不会报错在资源本身(状态里通常无 ADDRESS)。先确认集群已部署某个 Controller。
Ingress 资源示例
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: default
spec:
ingressClassName: nginx # 指定由哪个 Controller 处理
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
tls:
- hosts:
- app.example.com
secretName: app-tls # 包含 tls.crt / tls.key 的 Secret1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
要点:
ingressClassName:指定处理者。若省略,需存在带ingressclass.kubernetes.io/is-default-class=true注解的默认 IngressClass(官方仍建议显式定义默认类)。pathType:Prefix(前缀匹配)或Exact(精确匹配),v1 必须显式指定。tls:引用一个含证书的 Secret,Controller 负责终止 TLS。
注意
Ingress 只支持 HTTP/HTTPS 路由规则。要暴露非 HTTP 协议(如 gRPC 流式、TCP/UDP 自定义端口),通常用 LoadBalancer/NodePort,或在支持 TCP/UDP 的 Controller 里单独配置(如 ingress-nginx 的 tcp-services ConfigMap)。
Ingress Controller 实现差异
Ingress 只是规范,各 Controller 行为并不完全一致,尤其是很多高级能力只能通过**厂商注解(annotations)**实现,这会降低可移植性:
| Controller | 数据面 | 配置方式 | 备注 |
|---|---|---|---|
| ingress-nginx | Nginx | 大量 nginx.ingress.kubernetes.io/* 注解 | 最流行,[厂商特定] 注解多 |
| Traefik | 自研 | 原生 CRD / 兼容 Ingress | 动态、云原生友好 |
| Emissary / Contour | Envoy | CRD + Ingress | 基于 Envoy |
| HAProxy Ingress | HAProxy | 注解 + ConfigMap | 高性能四/七层 |
注解带来的可移植性问题
Ingress 标准只规范了 host/path 路由;rewrite、header 匹配、超时、后端 TLS、流量切分等几乎都靠注解。换 Controller 时,这些注解通常不通用,需要重写。这正是 Gateway API 要解决的痛点(见下)。
Gateway API:Ingress 的继任者
Gateway API(gateway.networking.k8s.io/v1)是一组表达力更强、面向角色的路由 API,核心资源:
GatewayClass:由哪个控制器实现(类比 IngressClass)。Gateway:负载均衡器/代理实例,声明监听端口、协议、TLS;通常由平台团队拥有。HTTPRoute/GRPCRoute:路由规则,由应用团队拥有,可跨命名空间挂到 Gateway 上。
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: team-a
spec:
parentRefs:
- name: shared-gateway
namespace: ingress
hostnames:
- app.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-svc
port: 801
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
优势(相对 Ingress):header 匹配、流量加权(灰度)、重写等是 API 字段而非注解,跨实现一致;支持跨命名空间共享网关与更细的 RBAC 角色分离。[版本相关] Gateway API 为附加组件,需安装 CRD,并非所有集群默认可用。
选型建议
- 维护已有 Ingress:继续用,无需强制迁移。
- 新项目、需要灰度/header 路由/多团队共享网关:优先 Gateway API(前提是所选 Controller 已支持)。
- 简单 host/path 规则、不依赖注解:纯 Ingress 仍然足够且被广泛理解。
生产实践
- 选一个 Controller 并固定
ingressClassName,避免多 Controller 抢同一个 Ingress。 - TLS 用 cert-manager 自动签发/续期,不要手填 Secret。
- 用
kubectl describe ingress <name>看Events与Address是否被正确填充。 - 监控 Controller 的
:10254/metrics(ingress-nginx)观察请求率、上游延迟、证书过期。
验证
bash
kubectl get ingressclass
kubectl get ingress example -o wide
kubectl describe ingress example # 看 Events 与 Address
# 无 DNS 时的测试:用 Host 头直连
curl -H 'Host: app.example.com' http://<controller-ip>/1
2
3
4
5
2
3
4
5
回滚与清理
bash
kubectl delete ingress example
# 卸载 Controller 见其官方文档;注意删除会同时移除外部 LB(如为 LoadBalancer 类型)1
2
2
故障排查
- Ingress 无 ADDRESS / 不生效:Controller 未安装,或
ingressClassName无对应 Controller。 - 路由 404:
pathType不匹配、后端 Service/端口名错误、或 Controller 未 reload(看 Controller Pod 日志)。 - TLS 失败:Secret 不存在或证书格式错误(需
tls.crt/tls.key)。
安全与合规
- 边缘代理是攻击面(历史上出现过 Ingress-Nginx 相关 CVE,如 CVE-2025-1974 类的准入控制器暴露问题
[未实测],务必保持 Controller 版本更新)。 - Ingress 并不绕过 NetworkPolicy;Controller 到后端 Pod 的流量仍受网络策略约束。
常见坑
- 以为 apply Ingress 就够:缺 Controller。
- 不同 Controller 注解不通用:迁移时重写规则。
- 忘记
pathType:v1 必须指定,否则 apply 会被拒或行为不符预期。
替代方案与权衡
- Gateway API:表达力与可移植性更好,是方向,但需额外安装且部分场景生态仍在成熟。
- Service Mesh(Istio/Linkerd):东西向 + 南北向统一治理,能力强但复杂度高。
- 直接用 LB per service:简单但成本高、难管理,仅适合少量服务。
参考资料
- Kubernetes 官方文档 - Ingress,访问日期:2026-10-08(含 Ingress API frozen 说明)。
- Kubernetes 官方文档 - Gateway API,访问日期:2026-10-08。
- Gateway API 官方站点,访问日期:2026-10-08。
- Ingress Controllers and the Gateway API(对比),访问日期:2026-10-08。