← 返回 Atlas
Kubernetes

Ingress 与外部网关

2015 年 Kubernetes 刚火,对外暴露服务只有 NodePort:每个服务开一个随机大端口。几百个服务就是几百个端口,运维疯了。Ingress 在 1.1 出现,把『外面怎么走进来』从每服务一个端口,变成一份路由表加一个看门的 controller。今天 nginx-ingress 和 traefik 是两个主流看门人,一个靠 annotation 抢地盘,一个靠 CRD 自立门户。

k8s · ingress · 网关

从 NodePort 到 Ingress:暴露方式的三次进化

ClusterIP 只在集群内可达,跨节点访问它要靠 NodePort:在每个节点开一个 30000+ 端口转发到 Service。服务一多端口就爆炸,而且端口不语义化(31337 是谁?)。LoadBalancer 借云厂商 LB 解决端口问题,但每个服务一个 LB,贵。Ingress 是 7 层路由:一份规则表声明『/api 去 service-a、/ 去 service-b』,一个 Ingress Controller(通常 nginx/traefik Pod)读规则、做代理、暴露一个统一入口。资源只是数据,controller 才是真正干活的。

nginx-ingress:规则多到要 annotation 来救

nginx-ingress 把 Ingress 规则渲染成 nginx.conf:controller 监听 API server 的资源变动,热生成配置并 reload。规则以外的能力全靠 annotation:nginx.ingress.kubernetes.io/rewrite-target 改路径、ssl-redirect 强制 HTTPS、proxy-body-size 调上传上限、canary 灰度。annotation 是字符串约定,拼错一个词静默不生效——这是它最大的坑,也是它功能最全的原因。

traefik:配置即代码,动态到可怕

traefik 不靠 Ingress 规则 + annotation,它原生读 CRD:IngressRoute 是类型化资源,match 用表达式(Host(api.example.com) && PathPrefix(/api))。改路由就是 Apply 一个 CRD,不用 reload,服务发现是动态的。它还自带 Dashboard、自动 Let's Encrypt 证书。代价是得先装 CRD 才能用——traefik 选择了把『配置』做成一等公民。

Ingress 只是网关的开始:Gateway API 要接管

Ingress 的痛点很实在:annotation 每个实现私有、不可移植;rewrite 这类语义各写各的,换个 controller 配置全废。Gateway API 从 2022 年开始 beta,把路由拆成 Gateway(入口)和 HTTPRoute(路由规则)两层,实现厂商(gateway controller)和路由语义分离。nginx 和 traefik 都在实现它,未来新集群值得直接上 Gateway API。

实战示例

minikube 上装 ingress-nginx,建一条路由:
01apiVersion: networking.k8s.io/v1
02kind: Ingress
03metadata:
04  name: demo
05spec:
06  rules:
07    - http:
08        paths:
09          - path: /api
10            backend:
11              service: { name: service-a, port: { number: 8080 } }
12          - path: /
13            backend:
14              service: { name: service-b, port: { number: 80 } }
curl http://$(minikube ip)/api 命中 service-a 的 /api 路径——注意是原样转发,路径带 /api 过去。想剥掉前缀就得加 nginx.ingress.kubernetes.io/rewrite-target: /,此时 /api/x 变成后端 /x。同一件事,traefikIngressRoute + PathPrefix(/api) 表达,这就是两派差异的缩影。

子关键词

Ingress Controller 真正看门的 Pod
读 Ingress 规则并实现代理的组件,常见 nginx-ingress、traefik、haproxy-ingress。Ingress 资源本身不产生流量。
nginx-ingress annotation 流派
把 Ingress 渲染成 nginx.conf,热 reload。功能全但行为藏在 annotation 里,rewrite/canary/ssl-redirect 全靠它。
traefik CRD 流派
用 IngressRoute CRD 表达路由,match 是表达式,配置类型化、可校验、动态生效。自带 Dashboard 与自动证书。
Gateway API 新一代入口标准
Gateway + HTTPRoute 分层,路由语义标准化,解决 Ingress annotation 不可移植。nginx/traefik 都在实现。
annotation controller 私有的配置
ngress 之外的增强配置全是 annotation 字符串。拼错静默失败,是 Ingress 排错第一大坑。
Service 类型 ClusterIP / NodePort / LB
Ingress 的前置演进:ClusterIP 集群内、NodePort 节点端口、LoadBalancer 云 LB。Ingress 站在它们之上做 7 层路由。

衍生角度

设计模式:声明式路由 + 控制器

Ingress 是声明式规则表,Controller 把规则翻译成实际反向代理配置。和 CRD/controller 是同一个骨架:资源声明期望,控制器拨现实。

概念拆解:Ingress 资源 vs Ingress Controller

资源只是数据,controller 才是流量入口。装了 Ingress 对象没装 controller,什么都不发生——这俩必须分开记。

风格架构:annotation 驱动 vs CRD 驱动

nginx 用 annotation(字符串约定,灵活但不可移植),traefik 用 IngressRoute CRD(类型化,校验强)。两种扩展范式的典型对局。

原理分析:为什么 Ingress 不可移植

核心语义(rewrite、正则、canary)每个实现私有,写在各自 annotation 里。跨 controller 迁移等于重写路由,这正是 Gateway API 想统一的原因。

实际用法与坑

  • 装了 Ingress 对象但没 Ingress Controller,什么都不发生:先 kubectl get ingressclass 确认有 controller。
  • annotation 大小写敏感且带版本前缀:nginx.ingress.kubernetes.io 拼错静默不生效,连日志都不一定报。
  • rewrite-target 要用捕获组:rewrite-target: /$2 配 pathType 里的正则,否则路径被吞 404。
  • traefik 的 IngressRoute 是 CRD:不先装 CRD 就用不了,和 Ingress 是两套资源。
  • HTTPS 自动证书靠注解:cert-manager 的 ClusterIssuer + ingress 上的 annotation 才会签发,证书 Pending 先查 issuer。

下一步动手做

在 minikube 装 nginx-ingress,建一条 /api 路由并 curl 验证;加 rewrite-target 剥前缀看路径变化;再装 traefik 用 IngressRoute 写同一条路由,对比两派写法;最后看一眼 Gateway API 的 HTTPRoute 长什么样。

相关书籍

Kubernetes in Action

Service 与 Ingress 章节,把 ClusterIP/NodePort/LB/Ingress 的演进和字段一次讲清。

关联关键词