跳到内容
← 博客

Ingress NGINX 退役之后

承载约一半云原生环境入口流量的控制器已于 2026 年 3 月归档。实战迁移指南:真正会坏的地方、ingress2gateway 转不了的部分,以及一套可以随时回滚的切换流程。

·约 15 分钟
  • Kubernetes
  • Gateway API
  • Ingress
  • 平台工程
  • 迁移

如果你的集群仍然用 ingress-nginx 转发流量,那么你正在运行一个已经没有人负责修的软件。仓库已于 2026 年 3 月 24 日归档,不会再有新版本,不会再修 bug,而且最关键的一点是:无论出现什么漏洞,都不会再有安全补丁。那天什么都没坏——问题恰恰就在这里:入口照常工作,所以没有任何东西逼着你动手。

对比图:左侧是把流量路由到两个 Service 的 Kubernetes Ingress 资源,右侧是等价的 Gateway API 的 Gateway 与 HTTPRoute 对象
迁移不是全局替换。一个 Ingress 会拆成一个 Gateway,加上若干条 HTTPRoute——每一条对应一项你过去隐式获得的行为。

这是一份在截止日期之后写的迁移指南,而不是之前。内容包括:用四条命令量化影响范围,用证据而不是印象做选型,哪些 ingress-nginx 行为在翻译过程中会悄悄变味,以及一套在新数据面表现异常时能把流量切回去的发布顺序。

到底发生了什么,以及没有发生什么

时间线很短,但值得说准,因为二手解读把它传歪了不少。Kubernetes SIG Network 与 Security Response Committee 于 2025 年 11 月 11 日宣布退役。2026 年 1 月 29 日,Steering Committee 与 SRC 联合发布了一份措辞罕见直白的声明:退役之后继续使用 Ingress NGINX,等于让自己和用户暴露在攻击之下;而且现有的替代方案没有一个是可以直接平替的。[retire][steering]

问题截至 2026 年 8 月 15 日的答案
ingress-nginx 还在维护吗?不在。最后一个版本是 2026 年 3 月 19 日的 controller-v1.15.1(Helm chart 4.15.1,NGINX 1.27.1,针对 Kubernetes 1.31–1.35 测试)。[lastrel]
仓库是不是没了?没有删除——2026 年 3 月 24 日归档,转为只读。Issue 与 PR 已冻结;文档站点仍然在线。[repo]
我的集群会坏吗?不会。现有部署继续工作,安装产物(Helm chart 与容器镜像)也仍然可用。危险之处正在于此。[retire]
Ingress API 被废弃了吗?没有。它是 GA 状态且已冻结:不再有任何变更,也没有从 Kubernetes 中移除的计划。[ingressdoc]
有官方的替代控制器吗?没有。Kubernetes 作为项目只支持并维护 AWS 与 GCE 两个 Ingress 控制器。原本设想的继任者 InGate 从未发布过任何版本,并已于 2026 年 6 月 30 日自行归档。[ctrldoc][retire]

最后一行是最容易被误读的。Ingress API 本身并没有被废弃。官方文档写得很清楚:它是正式可用(GA)状态,项目没有任何将其移除的计划,只是被冻结了——不再有任何变更或更新。你的 networking.k8s.io/v1 Ingress 对象仍然是合法的 Kubernetes 资源,以后也是。停止维护的是读取它们的某一个控制器。[ingressdoc]

继续用下去,你接手的是什么

衡量风险最直接的方式,是看这个项目在最后几周里发布的安全修复。2026 年 2 月 2 日——Steering 声明发布四天后、仓库转为只读七周前——SRC 披露了 ingress-nginx 的四个漏洞:CVE-2026-1580、CVE-2026-24512、CVE-2026-24513 和 CVE-2026-24514。其中最严重的评级为 HIGH、8.8 分,在 v1.13.7 与 v1.14.3 中修复。[advisory]

CVE-2026-24512 是最该记住的一个。攻击者可以通过 Ingress 的 rules.http.paths.path 字段向 NGINX 注入配置,进而在控制器上下文中执行任意代码,并读取控制器能访问的全部 Secret——在默认安装下,那就是整个集群的 Secret。临时缓解措施是用一个 validating admission controller 拒绝 path type 为 ImplementationSpecific 的 Ingress。请注意这类漏洞对攻击者的门槛:只需要能创建 Ingress。任何拥有某个 namespace 写权限的人都符合条件。[cve24512]

后面还有两个,而它们才真正把这个论点补完。CVE-2026-3288 于 2026 年 3 月 9 日披露,评级 HIGH、8.8,是通过 rewrite-target 注解进行的配置注入——正是下文语义对照表所警告的那个注解——在 v1.13.8、v1.14.4 和 v1.15.0 中修复。随后是 CVE-2026-4342,2026 年 3 月 19 日披露,同样 8.8 分、同样的向量:基于注释的配置注入,同样能在控制器中执行代码并读取整个集群的 Secret。它在 v1.13.9、v1.14.5,以及 controller-v1.15.1 中修复。也就是最终版本。这个项目发布的最后一样东西,就是一个安全补丁——距离仓库转为只读只有五天。此后再出现的问题,什么都不会有。[cve3288][cve4342][lastrel]

要看上限,可以参考 CVE-2025-1974——也就是 2025 年 3 月的「IngressNightmare」,CVSS 9.8。Kubernetes 项目当时的描述毫不含糊:Pod 网络上的任何东西都有很大机会接管你的集群,且不需要任何凭据。那一次还有补丁。下一次不会有了。[nightmare]

现有部署会继续正常工作,因此如果你不主动检查,很可能直到被入侵才会知道自己受影响。[steering]

关于规模:Steering Committee 与 SRC 援引 Datadog 的内部研究,称约 50% 的云原生环境依赖这个控制器。这个数字应当被当作量级参考而非精确统计——底层数据集未公开,且只反映 Datadog 所监控的环境——但项目自己 2025 年给出的「超过 40% 的 Kubernetes 集群」在量级上是吻合的。无论取哪个口径,这都不是边角料级别的收尾工作。

先确认自己是否受影响

做任何规划之前,先量化。第一条命令是 Kubernetes 项目自己给出的;后面三条告诉你实际工作量有多大——因为这次迁移的成本不取决于 Ingress 对象的数量,而取决于它们背后有多少种不同的注解。

# 1. The check the Kubernetes project itself publishes
kubectl get pods --all-namespaces \
  --selector app.kubernetes.io/name=ingress-nginx

# 2. Which controller image, and therefore which version, is actually running
kubectl get deploy -A -l app.kubernetes.io/name=ingress-nginx \
  -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.spec.template.spec.containers[0].image}{"\n"}{end}'

# 3. How much surface you have to translate: every Ingress bound to it
kubectl get ingress -A \
  -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\t"}{.spec.ingressClassName}{"\n"}{end}'

# 4. The real cost driver - the annotations, ranked by how often you use them
kubectl get ingress -A -o json \
  | jq -r '.items[].metadata.annotations // {} | keys[]' \
  | grep -F 'nginx.ingress.kubernetes.io/' | sort | uniq -c | sort -rn

第四条命令就是工作量估算。六十个 Ingress、四种注解的集群,是一个下午的事。十二个 Ingress、二十二种注解(其中还包括 configuration-snippet)的集群,是一个项目——现在你知道原因了。

动 YAML 之前先把目标定下来

诚实地说只有三条路,选哪条取决于你实际有多依赖 ingress-nginx 的行为。做选型短名单之前有一点要清楚:Kubernetes 作为项目支持并维护的 Ingress 控制器只有 AWS 和 GCE 两个。官方文档列表上的其余全部——Traefik、HAProxy、Contour、Kong、APISIX、Cilium、Higress、Istio 等等——都属于第三方。另外注意:kubernetes/ingress-nginx 已经完全不在那个页面上了。[ctrldoc]

目标方案什么情况下选它代价是什么
某个 Gateway API 实现
NGINX Gateway Fabric、Envoy Gateway、Traefik、Cilium、kgateway、Istio、Higress、agentgateway……
你想用真正在持续演进的那套 API;有多个团队往同一个共享入口挂路由;或者需要在平台方与应用方之间做权限与职责分离。改造量最大。Ingress 对象要拆成 Gateway 加 HTTPRoute,注解则变成 filter、policy,或者干脆无处安放。
换一个 Ingress 控制器
Traefik、HAProxy、Contour、Kong、APISIX、Higress、Istio……
存量是大量结构简单的 Ingress,迁移预算有限,只想用最短路径离开一个已停止维护的控制器。networking.k8s.io/v1 对象可以保留,但每一个 nginx.ingress.kubernetes.io/* 注解都要用新控制器的方言重写一遍。而且你落在一套已冻结的 API 上,要有再迁一次的心理准备。
云厂商提供的控制器或云原生网关
ACK 云原生 API 网关、TKE、AWS Load Balancer Controller、GKE Gateway、AGIC……
你只在一个托管平台上,重视有人可以对接支持,并愿意用可移植性换可支持性。厂商锁定,以及一个你无法完全审视其行为的数据面。在假设功能对齐之前先看一致性报告——有几个托管实现通过的扩展特性明显更少。

如果走 Gateway API 这条路:当前版本是 v1.6.0,2026 年 6 月底打标签,8 月 3 日正式发布公告。TCPRoute 与 UDPRoute 在该版本中从 Experimental 升级为 Standard 且版本号为 v1,与 Gateway、GatewayClass、HTTPRoute、GRPCRoute、TLSRoute、ListenerSet、ReferenceGrant、BackendTLSPolicy 并列。TCPRoute 与 UDPRoute 的 v1alpha2 版本自 v1.6 起废弃并将被移除。安装时请使用当前补丁版本 v1.6.1(2026 年 7 月 16 日发布),而不是 v1.6.0。关于集群版本:项目并没有公布一个固定的最低版本,其公开政策是支持最近五个 Kubernetes 次要版本,所以请拿这条政策去核对你的集群,而不是相信某篇博客里写的某个数字。[gw16][gw16rel][gw161][versioning]

v1.6 还有一处结构性变化值得提前规划:新的实验性资源现在放在独立的 API 组 gateway.networking.x-k8s.io 下,类型名带 X 前缀——比如 XBackend、XMesh。升级为 Standard 时会重命名进 gateway.networking.k8s.io 并去掉前缀。这是一个刻意设计的信号:如果你打算依赖的 kind 以 X 开头,它就不是一个可以用于生产的承诺。[gw16]

选型要看证据。Gateway API 项目为每个版本发布一致性(conformance)报告,逐条列出每个实现按路由类型通过了多少扩展特性。那张表比任何厂商对比页都更适合做初筛,包括本文——请查你打算实际运行的那个版本的行,不要看去年的。另外要注意:并非每个实现都会为每个版本提交报告,某一行缺失意味着「该版本没有提交报告」,而不是「不符合一致性」。[conform]

国内落地需要额外考虑两件事。第一是替代方案本身:Higress(阿里开源、基于 Envoy,主打对 Nginx Ingress 注解的兼容)与 Apache APISIX 都在官方 Ingress 控制器列表中,前者常被当作从 Nginx Ingress 平滑迁移的国产选项,因为它可以先以兼容 Ingress 的模式接管流量,再逐步转向网关自身的 API。第二是托管平台的节奏:如果你在 ACK 或 TKE 上,阿里云已就 Nginx Ingress Controller 旧版本发布过停止维护公告,实际迁移窗口往往由云厂商的组件升级周期决定,而不是由你的排期决定——所以第一步应该是查清你的托管集群提供哪个控制器、认证到 Gateway API 的哪个版本。

五个迁移后语义会变的行为

迁移翻车基本都发生在这一节,即使目标已经定了也值得读。ingress-nginx 累积了一批从来不在 Ingress 规范里的行为,你的应用如今在悄悄依赖它们,而任何符合一致性要求的 Gateway API 实现都不会复现这些行为。Kubernetes 项目专门把其中五条写成文档,就是为了让别人不必自己踩一遍。[gotchas]

ingress-nginx 的行为迁移后会怎样该怎么做
正则匹配按前缀且不区分大小写Gateway API 把 RegularExpression 的语义交给具体实现,而常见的基于 Envoy 的实现(Istio、Envoy Gateway、kgateway)做的是完整匹配且区分大小写,原本能匹配上的路径会匹配不上。显式改写为 (?i)/pattern.*ingress2gateway 已经会为你生成这种形式。
use-regex 会影响同一 host 下的所有 Ingress在某个 Ingress 上开启正则,会改变同一域名下毫不相干的其他 Ingress 的路径匹配方式。这种耦合会悄无声息地消失。按域名而不是按 Ingress 做盘点。那些只是因为「邻居」的注解才生效的路径会直接失效。
rewrite-target 会隐式打开 use-regex有些从未声明过正则的 Ingress,实际上处于正则语义之下。做审计时,把所有带 rewrite-target 的 Ingress 一律当作正则 Ingress 处理。
缺少结尾斜杠时自动产生 301符合一致性的 Gateway API 实现不会补这个重定向。依赖它的客户端会拿到应用返回的 404。要么显式加一个 RequestRedirect filter,要么在应用里修正路由。/path/path/ 都要测。
URL 在匹配前会被规范化(RFC 3986 §6.2)多数实现默认同样会规范化 ... 片段,但具体行为各不相同,重复斜杠和边界情况可能以和以前不同的形式到达你的服务。标准 Gateway API 无法配置。需逐实现验证,并在应用侧做路径校验。

实践中最难受的是结尾斜杠的重定向,因为它不会大声报错。过去访问 /api 会被重定向到 /api/,现在应用直接返回 404,而且错误出现在你的服务日志里而不是入口层——于是第一反应是「服务有 bug」,而不是「昨晚那次迁移」。

ingress2gateway:能转什么,转不了什么

官方转换工具是有的,而且比以前好用得多。ingress2gateway 于 2026 年 3 月 20 日以 SIG Network 子项目的身份发布 1.0。最主要的变化是:对 ingress-nginx 注解的覆盖从 3 个提升到 30 多个,包括 CORS、后端 TLS、正则匹配和路径重写。1.0 还新增了控制器级别的集成测试——在真实集群里同时拉起真实的 ingress-nginx 和真实的 Gateway API 控制器,比较二者的运行时行为,而不只是 diff 一下 YAML。[i2gblog]

# Install the official converter (Go 1.25.5 or newer to build from source)
go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0
# or: brew install ingress2gateway

# Convert a manifest on disk, without touching the cluster
ingress2gateway print --input-file ingress.yaml \
  --providers=ingress-nginx > gwapi.yaml

# Convert one namespace from a live cluster
ingress2gateway print --namespace shop \
  --providers=ingress-nginx > gwapi.yaml

# Convert everything, and keep the warnings - they are the migration backlog
ingress2gateway print --all-namespaces \
  --providers=ingress-nginx > gwapi.yaml 2> unsupported.log

支持九种 provider——ingress-nginxnginxtraefikkongistioapisixciliumgceopenapi——以及六种输出 emitter,其中包括 envoy-gatewaykgateway。其输出面向 Gateway API v1.5.0。它不会替你做的部分:[i2g]

  • configuration-snippetserver-snippet:不支持,也没有等价物。允许写任意 NGINX 指令,正是 Kubernetes 项目点名为「无法偿还的技术债」的那个设计决策。如果你的 snippet 里塞了业务逻辑,这些逻辑必须挪进应用、挪成 filter,或者挪进某个实现相关的策略 CRD。[retire]
  • proxy-body-size:Gateway API 没有等价字段。只能在数据面上配置,这也意味着它变成实现相关的配置,不再可移植。
  • proxy-read-timeout / proxy-send-timeout:只能尽力映射到 timeouts.request,二者并不等同。请在压测下重新测量,不要假设行为一致。
  • URL 规范化:标准 Gateway API 完全无法配置。如果你依赖它,本质上是在依赖数据面,必须逐个实现验证。

把工具的警告当成迁移待办清单,而不是噪音。它打到 stderr 的每一条,都是它没能搬过去的一项行为;而这些行为,每一条都是一次等着 DNS 切换来触发的生产事故。

Ingress 与 Gateway API 对照

一个最小但贴近真实的例子:一个域名、TLS,以及在 API 与 Web 前端之间划分的路径。把两者并排看是有意义的——Gateway API 版本更长,而多出来的长度并不是形式主义,而是 ingress-nginx 过去隐式提供给你的行为,现在被写了出来。

迁移前 —— 一个 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop-ingress
  namespace: shop
spec:
  ingressClassName: nginx
  tls:
    - hosts: [shop.example.com]
      secretName: shop-example-com-tls
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

迁移后 —— 一个 Gateway 加两个 HTTPRoute

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shop-gateway
  namespace: shop
spec:
  gatewayClassName: nginx          # must match an installed GatewayClass
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      hostname: shop.example.com
      allowedRoutes:
        namespaces:
          from: Same
    - name: https
      protocol: HTTPS
      port: 443
      hostname: shop.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - group: ""              # empty string = core API group
            kind: Secret
            name: shop-example-com-tls
      allowedRoutes:
        namespaces:
          from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-route
  namespace: shop
spec:
  parentRefs:
    - name: shop-gateway
      sectionName: https
  hostnames: [shop.example.com]
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-service
          port: 80
---
# ingress-nginx redirected HTTP to HTTPS for you. Gateway API does not.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-route-ssl-redirect
  namespace: shop
spec:
  parentRefs:
    - name: shop-gateway
      sectionName: http
  hostnames: [shop.example.com]
  rules:
    - filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 308

有三点值得注意。sectionName 把路由绑定到特定 listener,这是你把 HTTP 与 HTTPS 行为分开的方式。allowedRoutes 是 Ingress API 从来没有过的角色划分:平台团队拥有 Gateway 并决定哪些 namespace 可以挂上来,应用团队拥有各自的 HTTPRoute。而第三个对象的存在,只是为了复现 ingress-nginx 默认就会做的一次重定向——这句话大致也概括了整场迁移。[gwapi]

一套真正能回滚的切换流程

这次迁移最有用的一个性质是:两个控制器可以同时运行。它们是不同的对象,监听不同的资源,挂在不同的负载均衡器后面。没有任何东西要求你一次性切换,所以不要那么做。

  1. 把新控制器装在老的旁边。独立的 GatewayClass、独立 namespace、自己的 LoadBalancer Service 和自己的外部地址。流量仍然走 ingress-nginx。
  2. 转换并逐条审阅。对单个 namespace 跑 ingress2gateway,读完警告,手工补齐它翻译不了的注解。不要不读就 apply。
  3. 用相同的域名 apply Gateway API 对象。此时用户侧毫无变化——新控制器有自己的 IP,且没有任何 DNS 记录指向它。
  4. 直接对比两个入口。--resolve 逐个请求比对:状态码、重定向目标、响应头,尤其是结尾斜杠和正则这两类用例。这一步才是真正能抓住上面五个行为差异的地方。
  5. 灰度切换 DNS。低 TTL 记录、加权策略,或者先切一个非核心域名。在新入口扛过一次真实业务高峰之前,让 ingress-nginx 继续提供服务。
  6. 有意识地下线。删除 ingress-nginx 的 Deployment、Service、IngressClassValidatingWebhookConfiguration。把准入 webhook 留在集群里,就是几周后集群莫名其妙坏掉的典型原因。
# Install the Standard channel CRDs (server-side apply, as the project documents)
kubectl apply --server-side -f \
  https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml

# The Gateway must be Programmed before you move any traffic to it
kubectl get gateway shop-gateway -n shop \
  -o jsonpath='{.status.conditions[?(@.type=="Programmed")].status}{"\n"}'

# Every parentRef must be Accepted, and every backendRef ResolvedRefs.
# Nested ranges keep each condition paired with its own status.
kubectl get httproute shop-route -n shop -o jsonpath='{range .status.parents[*]}{.controllerName}{"\t"}{range .conditions[*]}{.type}={.status}{" "}{end}{"\n"}{end}'

# Compare old and new on the same request, before DNS moves.
# A cloud load balancer publishes either .ip or .hostname - AWS uses .hostname,
# so --connect-to is used instead of --resolve: it accepts both.
OLD=$(kubectl get svc -n ingress-nginx ingress-nginx-controller \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}')
NEW=$(kubectl get gateway shop-gateway -n shop \
  -o jsonpath='{.status.addresses[0].value}')
for edge in "$OLD" "$NEW"; do
  curl -sS -o /dev/null -w "$edge  %{http_code}  %{redirect_url}\n" \
    --connect-to "shop.example.com:443:$edge:443" https://shop.example.com/api
done

注意第二条命令里的 Programmed 状态。Gateway 对象存在,不等于它已经在提供服务;status conditions 才是契约,检查它的成本远低于在 DNS 切换过程中发现两者的差别。

ingress-nginx、NGINX Ingress 与 NGINX Gateway Fabric

三个彼此独立的项目,名字高度相似,而且恰恰在这次迁移期间造成了大量错误判断。有人从 ingress-nginx 迁到「NGINX Ingress」,以为换掉了什么,后来才发现不是那么回事;也有人干脆把 NGINX 整体排除,因为默认这三个一起死了。

项目维护方状态
kubernetes/ingress-nginx
「Ingress NGINX Controller」
Kubernetes 社区(SIG Network)已退役。2026 年 3 月 24 日归档为只读。你要迁走的就是它。[repo]
nginx/kubernetes-ingress
「NGINX Ingress Controller」
F5 / NGINX仍在活跃开发。支持 Ingress,并有自己的 CRD——VirtualServerVirtualServerRouteTransportServer——可跑在 NGINX OSS 或 NGINX Plus 上。[f5]
nginx/nginx-gateway-fabric
「NGINX Gateway Fabric」
F5 / NGINX仍在活跃开发。以 NGINX 为数据面的 Gateway API 实现——又是另一个项目,且通过一致性测试。[ngf]

Kubernetes 项目自己都觉得有必要专门澄清:两者都用 NGINX 作为数据面,但除此之外毫无关系。从社区控制器迁到 F5 的控制器是一次货真价实的迁移,同样有自己的一整套注解转换工作,而不是改个名字。[gotchas]

这一周我会做什么

如果还没开始:今天就把那四条排查命令跑一遍,因为注解的种类数是唯一能告诉你「这是一个下午还是一个季度」的数字。如果答案是「一个下午」,这周就做完,别再背着这个风险。如果答案是「一个季度」,有价值的动作依然是现在就并行装上第二个控制器,并迁移一个无关紧要的域名——因为第一次迁移正是你发现哪些「常识」其实只是 ingress-nginx 行为的时候。

更大的教训我在《无聊的云架构》里写过:最可能伤到你的组件,往往是没人想起来的那些,恰恰因为它们已经稳定跑了很多年。一个由一两位志愿者维护、却挡在半个云原生世界前面的 Ingress 控制器,在归档之前很久就已经是风险高度集中的点。值得顺手盘一下你的技术栈里还有什么是同样的形状——也值得像《什么时候不该用 Kubernetes》里那样问一句:这个平台带来的价值,配得上它让你承担的运维面吗?

常见问题

现在继续跑 ingress-nginx 安全吗?

它能跑,而且会继续跑下去。但它永远不会再收到任何安全补丁——而且值得看清最终版本到底是什么:controller-v1.15.1 正是 CVE-2026-4342 的修复,那是一个可以在控制器中执行代码、并读取整个集群 Secret 的配置注入漏洞,补丁与公告同日发布,距离仓库转为只读只剩五天。那已经是七周内的第六个同类漏洞。下一个不会有修复。如果你不得不再跑几周,至少要做到:限制谁可以创建 Ingress 对象;如果你的安装给了控制器集群级 Secret 访问权限,把它收回来;不要对外暴露准入 webhook。

Kubernetes 的 Ingress API 是不是也废弃了?

没有,这是最常见的误读。Ingress API 处于 GA 状态,享有正常的 GA 稳定性保证,Kubernetes 项目也明确表示没有移除计划。它只是被冻结了:不再继续开发。退役的只是社区的 NGINX 控制器,不是它所实现的那套 API。

ingress-nginx 和 nginx-ingress 有什么区别?

是两个不同组织的不同项目。kubernetes/ingress-nginx 由 Kubernetes 社区维护,现已归档。nginx/kubernetes-ingress 是 F5 的 NGINX Ingress Controller,仍在活跃开发。用 Kubernetes 项目自己的说法:两者都用 NGINX 作为数据面,但除此之外毫无关系。从一个换到另一个是一次真正的迁移,不是改名。

ingress2gateway 能自动迁移我的集群吗?

只能完成一部分。1.0 版本覆盖了 30 多个 ingress-nginx 注解(此前只有 3 个),是正确的起点。但 configuration-snippet 没有等价物且不支持,proxy-body-size 在 Gateway API 中没有对应字段,proxy 超时只能尽力映射,URL 规范化则根本无法表达。把它打到 stderr 的内容全部读完——那些输出就是你剩下的人工工作量。

应该迁到 Gateway API,还是只换一个 Ingress 控制器?

换控制器更快,也能保留现有对象,但你会落在一套已冻结的 API 上,而且每个注解仍然要用新方言重写一遍,所以大概率还得再迁一次。Gateway API 改造量更大,但开发都发生在那里,并且它能在拥有 Gateway 的平台团队与拥有各自路由的应用团队之间建立职责分离。存量是大量简单 Ingress,倾向于换控制器;多团队共享入口,则倾向于 Gateway API。

Higress、APISIX 这类方案适合替代 Nginx Ingress 吗?

两者都在 Kubernetes 官方文档的第三方 Ingress 控制器列表中,因此都是可选项。Higress 常被选中的原因是它对 Nginx Ingress 注解的兼容度较高,可以先以兼容模式承接流量,再逐步转到网关自身的 API,从而把切换风险拆成两步。但请不要凭定位选型:查你打算部署的版本的一致性报告,逐项确认你的注解被翻译成的那些扩展特性确实被支持,并确认它在你的托管平台上受支持。

安装 Gateway API 之前需要先升级 Kubernetes 吗?

项目并没有公布固定的最低 Kubernetes 版本,其公开政策是支持最近五个次要版本,所以请拿这条政策去核对你的集群,而不是相信博客里写的某个数字。安装当前补丁版本 v1.6.1(2026 年 7 月 16 日发布)的 Standard 通道 CRD,并按项目文档使用 server-side apply。如果改装 Experimental 通道,其 CRD 体积过大,客户端 kubectl apply 无法处理;另外实验性类型现在带 X 前缀并位于独立 API 组中,正是为了避免你不小心把生产建在上面。

同样的纪律也适用于底层密码学:后量子 SSH 与 TLS 一文说明了在这些系统所依赖的连接上应该验证什么。

参考来源

上文每一处论断都可以追溯到下列来源之一。全部为一手官方来源:Kubernetes 项目博客与文档、仓库状态、安全公告,以及 Gateway API 规范。

  1. Kubernetes blog — Ingress NGINX Retirement: What You Need to Know (11 Nov 2025)
  2. Kubernetes blog — Ingress NGINX: Statement from the Steering and Security Response Committees (29 Jan 2026)
  3. Kubernetes blog — Before You Migrate: Five Surprising Ingress-NGINX Behaviors You Need to Know (27 Feb 2026)
  4. GitHub — kubernetes/ingress-nginx (public archive, read-only since 24 Mar 2026)
  5. GitHub — ingress-nginx controller-v1.15.1, the final release (19 Mar 2026)
  6. Kubernetes Security Response Committee — [Security Advisory] Multiple issues in ingress-nginx (2 Feb 2026)
  7. kubernetes/kubernetes#136678 — CVE-2026-24512, configuration injection via the Ingress path field
  8. kubernetes/kubernetes#137560 — CVE-2026-3288, configuration injection via the rewrite-target annotation
  9. kubernetes/kubernetes#137893 — CVE-2026-4342, comment-based configuration injection (fixed by the final release)
  10. Kubernetes blog — Ingress-nginx CVE-2025-1974: What You Need to Know (24 Mar 2025)
  11. Kubernetes documentation — Ingress (the API is generally available and frozen)
  12. Kubernetes documentation — Ingress Controllers
  13. Gateway API — API overview and channel status
  14. Kubernetes blog — Gateway API v1.6: TCPRoute and UDPRoute Graduate to Standard (3 Aug 2026)
  15. GitHub — Gateway API v1.6.0 release notes
  16. GitHub — Gateway API v1.6.1, the current patch release (16 July 2026)
  17. Gateway API — v1.6 conformance reports by implementation
  18. GitHub — kubernetes-sigs/ingress2gateway
  19. Kubernetes blog — Announcing Ingress2Gateway 1.0: Your Path to Gateway API (20 Mar 2026)
  20. GitHub — nginx/kubernetes-ingress, the F5 NGINX Ingress Controller (a different project)
  21. GitHub — nginx/nginx-gateway-fabric, F5's Gateway API implementation
  22. Gateway API — versioning, release channels and graduation criteria

这篇有帮助吗?