ingress-nginx 退役倒计时:把入口控制器迁移当成一次生产变更来做

2026-07-10 24 预计阅读时间: 1 分钟
来源: cncf.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Kubernetes SIG Network 的 ingress-nginx controller 将在 2026 年 3 月退役。这个变化的重点不是“项目不再时髦”,而是它会直接改变生产集群的风险模型:继续停留在退役控制器上,意味着后续 CVE 可能没有补丁,新特性也会停止进入这条路线。对负责平台和业务稳定性的团队来说,现在该把入口层迁移放进路线图,而不是等到最后一个季度临时搬家。

退役真正影响的是运维边界

Ingress controller 不是一个普通 Deployment。它通常站在公网入口,处理 TLS、Host/Path 路由、Header、超时、重试、上传大小、WebSocket、gRPC,甚至还挂着外部负载均衡器和 DNS 记录。

所以 ingress-nginx 退役后的风险主要有三类:

  • 安全补丁断档:摘要中明确提到继续使用会带来未修补 CVE 的严重运维风险。入口层暴露面大,这类风险不能靠“内部服务没事”来抵消。
  • 功能停滞:Kubernetes Gateway API、云厂商 L7 能力、可观测性接口都在演进。如果 controller 停止功能更新,平台会被旧抽象锁住。
  • 事故恢复变慢:一旦遇到版本兼容、证书、负载均衡行为差异,退役项目的社区响应和维护资源会明显减少。

迁移不是简单替换镜像。更现实的做法是把它拆成资产盘点、候选控制器验证、双跑、流量切换和回滚预案。

先盘点:你到底用了多少 ingress-nginx 特性

很多集群表面上只有几十个 Ingress,实际依赖的是一堆 NGINX annotation。比如 rewrite、proxy body size、backend protocol、whitelist、auth、CORS、canary。迁移难度通常不由 Ingress 数量决定,而由这些 annotation 决定。

可以先跑一轮只读盘点,找出所有 Ingress、IngressClass 和 annotation:

kubectl get ingress -A -o json \
  | jq -r '.items[] | [
      .metadata.namespace,
      .metadata.name,
      (.spec.ingressClassName // "<none>"),
      ((.metadata.annotations // {}) | keys | join(","))
    ] | @tsv'

运行前需要本机有 kubectljq,并且当前 kubeconfig 指向目标集群。输出可以导入表格,按 annotation 分类评估:

kubectl get ingress -A -o json \
  | jq -r '.items[]
    | .metadata.annotations // {}
    | keys[]?' \
  | sort \
  | uniq -c \
  | sort -nr

这一步的目标不是马上选型,而是回答几个具体问题:哪些业务只用了标准 Ingress 字段,哪些业务深度依赖 NGINX 行为,哪些路由必须在迁移窗口内重点压测。

可以这样实践:新旧控制器并行,而不是原地覆盖

下面示例是一个可改造的迁移骨架,假设你要引入一个新的入口控制器,并通过不同的 IngressClass 做并行验证。具体 controller 可以是你们选定的替代方案;这里不声明某个特定实现是来源推荐,只展示迁移方法。

先保留旧的 nginx class,再新增一个候选 class:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: candidate-gateway
spec:
  controller: example.com/candidate-ingress-controller

应用它:

kubectl apply -f candidate-ingressclass.yaml
kubectl get ingressclass

然后复制一个低风险服务的 Ingress,改到新 class,并使用测试域名:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-candidate
  namespace: default
spec:
  ingressClassName: candidate-gateway
  rules:
    - host: echo-candidate.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: echo
                port:
                  number: 80

应用并检查地址分配:

kubectl apply -f echo-candidate-ingress.yaml
kubectl get ingress -n default echo-candidate
kubectl describe ingress -n default echo-candidate

如果你们有外部 DNS 自动化,测试域名可能会自动指向新负载均衡器;如果没有,就临时用 curl --resolve 验证,避免提前改公共 DNS:

curl -I --resolve echo-candidate.example.com:443:203.0.113.10 \
  https://echo-candidate.example.com/

203.0.113.10 改成新入口负载均衡器的 IP。这个方法适合验证 TLS、路由、Header、响应码和超时行为,不会影响原生产域名。

迁移检查表:别只测 200 OK

入口层迁移最容易漏掉的是“非主路径”行为。建议把检查项写进变更单,而不是靠值班工程师临场记忆。

HOST=echo-candidate.example.com
IP=203.0.113.10

curl -sv --resolve "$HOST:443:$IP" "https://$HOST/" -o /dev/null
curl -sv --resolve "$HOST:443:$IP" "https://$HOST/not-found" -o /dev/null
curl -sv --resolve "$HOST:443:$IP" -H 'X-Request-ID: migration-test-001' "https://$HOST/" -o /dev/null

实际项目里还要补充:

  • TLS 证书链和 SNI 是否正确。
  • HTTP 到 HTTPS 跳转是否符合预期。
  • 大文件上传、长连接、WebSocket、gRPC 是否正常。
  • 真实客户端 IP 是否还能进入应用日志。
  • WAF、认证、限流、白名单等边界能力是否有等价实现。
  • Prometheus 指标、日志字段和告警是否同步迁移。

如果大量依赖 nginx.ingress.kubernetes.io/* annotation,不要假设新控制器能逐字兼容。应逐项映射,能迁到标准字段就迁到标准字段,必须保留特殊行为的地方要写清楚替代配置。

采用建议:把 2026 年 3 月当作截止线,不当作开始线

比较稳妥的节奏是:先在非生产集群完成候选 controller 验证,再选择一两个低风险生产服务双跑,最后按业务域分批迁移。每一批都要有回滚路径,例如保留旧 Ingress、DNS TTL 降低、负载均衡器切换可逆。

不要等到 ingress-nginx 退役后才开始评估。那时你面对的不是一个技术迁移任务,而是安全风险、合规压力和生产变更窗口挤在一起。现在开始盘点 annotation、清理历史 Ingress、收敛入口策略,才有空间慢慢把入口层从“能跑”改成“可维护”。


相关推荐