
我们线上集群的nginx-ingress已经跑了三年多累计管理着四百多个Ingress规则。这周终于完成了一项筹划已久的基础设施升级把Ingress nginx的流量入口整体切换到了Gateway API体系底层的控制器也换成了NGINX官方推出的Gateway Fabric。整个过程踩了十几个坑有配置映射的、有CRD版本兼容性的、还有多控制器并存时的路由冲突问题。今天把这套迁移方案完整复盘一下希望能给正在做同样决策的团队一些参考。坦白说标题里写“退役”多少有点标题党。Ingress v1这个API本身短期内不会被删除但整个Kubernetes社区的演进方向已经很明确了所有新功能都在往Gateway API上倾注各大云厂商和开源控制器都在加大对Gateway API的支持力度。Ingress nginx作为其中体量最大的一个实现长期用下来的痛点其实非常具体注解语法各控制器不统一、跨Namespace引用需要额外controller配置、灰度发布靠非标准注解、证书管理与路由规则耦合度高。这些问题的根源在于Ingress API本身表达能力有限只能用注解和annotation去弥补补到最后就是一团乱麻。下面从设计思路、核心概念、迁移实操、踩坑记录四个维度来整理这次的经验。1. 为什么要换掉 Ingress nginx注解地狱与标准化缺失1.1 一个注解就是一个战场用过Ingress nginx的同学应该都有这种体验一条简单的域名转发规则因为加了rewrite-target、ssl-redirect、proxy-body-size、enable-cors、limit-rps、affinity这些注解瞬间变成七八行的YAML。而这些注解的语法是Ingress nginx控制器自己定义的换一家控制器就全部失效。社区里为了兼容Ingress做了大量努力但注解本身永远是各写各的。以最常用的rewrite-target为例nginx-ingress的写法是nginx.ingress.kubernetes.io/rewrite-target: /$2这个$2的语义是nginx正则捕获组它要求你的path字段必须显式写出捕获组spec: rules: - host: api.example.com http: paths: - path: /order-service(/|$)(.*) pathType: Prefix这个写法有两个问题第一pathType是ImplementationSpecific这意味着在Ingress规范里这条规则的匹配行为完全取决于控制器实现根本不可移植第二$2这个概念在Ingress API里根本没有定义你必须了解nginx内部的正则替换逻辑才能看懂这条规则在干什么。而Gateway API的HTTPRoute下同等的需求是显式的URLRewrite filterrules: - matches: - path: type: PathPrefix value: /order-service filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: /语义一目了然匹配前缀/order-service替换前缀为/。没有捕获组没有$1、$2没有ImplementationSpecific这种灰色地带。这就是标准化的价值。1.2 Gateway API 的定位差异如果只用一句话描述Ingress和Gateway API的差别我会说Ingress是协议与实现捆绑的产物而Gateway API是分层解耦的标准。Ingress API只有一种资源所有能力全靠注解和fields堆在一条YAML里。而Gateway API拆成了四层抽象GatewayClass描述网关实现类似IngressClassGateway描述具体的网关实例监听哪些端口、绑定哪个ControllerHTTPRoute/TLSRoute/TCPRoute描述路由规则把请求路由到后端ServiceReferenceGrant描述跨Namespace引用的授权关系这个分层带来的直接好处是路由规则和网关实现解耦。你可以同时有两套GatewayClass一套是NGINX的一套是Envoy的HTTPRoute完全不用改。这在多环境、多云、双活容灾场景下价值巨大。另外Gateway API在API设计上还有几个Ingress难以做到的细节跨Namespace路由Ingress默认只能引用同Namespace的Service虽然可以通过nginx-ingress的nginx.ingress.kubernetes.io/backend-protocol等注解硬干但不是正规路子。Gateway API通过ReferenceGrant显式授权安全且可审计。权重灰度Ingress nginx的canary灰度靠canary-weight、canary-header几个注解实现而HTTPRoute直接把权重作为一等公民字段weight且支持精确到0-1000的细粒度控制。请求匹配维度HTTPRoute支持Header匹配、Query参数匹配、Method匹配Ingress只有Host和Path两个维度。证书管理Ingress的TLS配置需要把证书Secret和host绑定写在同一个Ingress资源里多个host共用证书时要么各写一份浪费Secret要么用ingress-nginx的default-ssl-certificate注解又是非标准。Gateway API支持在Gateway层面声明跨namespace的TLS凭据配合ReferenceGrant明确授权。1.3 什么时候不该换在展开迁移细节之前先泼一盆冷水。如果你的集群满足以下几个条件我的建议是暂时别动Ingress总数量少于20条且全是简单的hostpath转发没有复杂rewrite、跨namespace、灰度发布需求团队对Ingress nginx运维经验丰富对Gateway API一无所知近期没有大规模流量治理和网关扩展需求Gateway API是一套更复杂、更细粒度的抽象学习成本和运维成本实打实存在。基础设施升级的初衷应该是解决实际问题而不是追新。我们之所以决定迁移是因为灰度发布、跨命名空间访问、多控制器并存这些需求已经明确浮出水面Ingress的注解体系成了瓶颈解决方案只能靠打补丁。2. Gateway API 的核心概念速通2.1 四类核心资源接入Gateway API之前先把四个核心资源的角色搞清楚。GatewayClass可以类比为驾照定义了“我具备什么能力”。它由一个或多个Controller如NGINX Gateway Fabric、Envoy Gateway、Traefik实现负责管理该Class下的所有Gateway实例。集群里可以同时存在多个GatewayClass例如一个绑定NGF、一个绑定Envoy。Gateway是实际运行的网关实例类比为一个小区的大门。定义监听哪些端口HTTP 80、HTTPS 443、绑定的TLS证书、允许哪些Namespace的Route资源关联它。创建一个Gateway资源时Controller会实际拉起对应的Pod/Deployment/SLB等底层资源。HTTPRoute是路由规则本体类比为大门内的导引路牌。定义hostname、path匹配条件、后端Service、权重、过滤器重写、重定向、跨域等。一条HTTPRoute通常对应一个业务入口的完整规则集。ReferenceGrant是跨Namespace引用的授权凭证。默认情况下HTTPRoute只能引用同Namespace的Service和Gateway想让别的Namespace的Service暴露就必须在目标Namespace创建一个ReferenceGrant显式声明“允许来自某个Namespace的Route引用我的某个Service”。放在一起的流转关系是Cluster有GatewayClass → Controller创建Gateway → Gateway绑定监听端口 → HTTPRoute声明匹配规则 → 规则命中后端Service。2.2 请求流转链路一次HTTP请求从外网打到Gateway到后端Pod完整链路如下外部流量进入Gateway的Listener假设监听443/TLSGateway根据SNI和端口确定匹配的Listener以及Listener绑定的TLS证书封装好的请求进入HTTPRoute匹配阶段依次检查各Route的hostname、path、header、query命中优先级最高的Route后进入其filter链Rewrite、Redirect、RequestHeaderModifier等最终转发到backendRefs指定的Service对应的Endpoints如果配置了weight则按权重分发到多个Service这条链路和Ingress相比多了一个Route层但这多出来的一层恰好让多个Namespace、多套Service的接入变得干净了。2.3 与Ingress的对应关系映射Ingress v1 概念Gateway API 对应资源差异说明IngressClassGatewayClass类似但GatewayClass承担了Controller实现选择Ingress 实例Gateway HTTPRoute一个Ingress拆成网关实例和路由规则两个资源单个规则 host/pathHTTPRoute matchesGateway API支持多维度匹配注解 nginx.ingress.kubernetes.io/rewrite-targetHTTPRoute filter URLRewrite标准字段无控制器绑定注解 canary-weightHTTPRoute backendRefs weight原生于API支持0-1000跨Namespace Service 引用ReferenceGrant显式授权更安全默认TLS证书default-ssl-certificateGateway Listener 的 TLS 配置更直接支持跨NS凭据这张映射表在做迁移清单的时候可以直接拿来用逐条扫描Ingress规则翻译成对应的HTTPRoute定义。3. 迁移前盘点你的 Ingress 清单里都藏了什么3.1 按注解分类梳理迁移的第一步不是打开编辑器写YAML而是把现有Ingress规则彻底盘一遍。我们把线上400多条Ingress按照注解类型做了分类重点统计以下几类标准路由类host、path、pathType这些是Ingress规范内的字段迁移最简单重写重定向类rewrite-target、ssl-redirect、app-root、permanent-redirect认证与安全类auth-type、auth-secret、enable-cors、whitelist-source-range流量治理类canary-weight、canary-header、canary-by-cookie、upstream-hash-by、affinity调参类proxy-connect-timeout、proxy-read-timeout、proxy-body-size、limit-rps、limit-rpm其中标准字段和rewrite/redirect类基本都能映射到HTTPRoute的标准field或filter流量治理和调参类是迁移中最麻烦的因为Gateway API标准里并没有一一对应。比如nginx-ingress的upstream-hash-by基于IP哈希做会话保持HTTPRoute标准里没有这个能力只能依赖具体Controller的扩展字段或者改用ConsistentHash特性。3.2 识别非通用注解筛选出所有nginx.ingress.kubernetes.io/前缀的注解后用脚本检查每个注解在目标Controller文档中是否有对应实现。这一步最容易踩的坑是很多注解在Ingress nginx Controller里是全局生效的比如proxy-body-size但Gateway API里如果底层Controller不实现对应扩展请求就会在网关层被卡住。建议在盘点阶段生成一个字段映射表用这个表格驱动后续的迁移方案评审原Ingress注解Gateway API 标准字段/过滤器目标Controller扩展备注nginx.ingress.kubernetes.io/rewrite-targetURLRewrite filterNGF支持迁移顺畅nginx.ingress.kubernetes.io/ssl-redirectRequestRedirect filterNGF支持迁移顺畅nginx.ingress.kubernetes.io/canary-weightHTTPRoute weightNGF支持单位转换注意Ingress为0-100HTTPRoute为0-1000nginx.ingress.kubernetes.io/upstream-hash-by无Envoy Gateway的loadBalancer扩展 / NGF extension需要后端配合nginx.ingress.kubernetes.io/proxy-body-size无NGF扩展Annotation网格层不处理NGF需单独开nginx.ingress.kubernetes.io/whitelist-source-range无标准暂无NGF的HTTPRoute过滤器扩展待评估3.3 盘点清单模板给团队用的盘点checklist我整理成了这样收集所有Ingress YAML按Namespace分类导出为文件用脚本提取所有annotations键值统计出现频次对照Ingress nginx官方注解文档标注每个注解的适用性对归类为“无标准映射”的注解逐个确认业务是否仍需要该能力对确认不需要的注解直接在新配置中丢弃减少配置复杂度对必须保留的扩展能力确认目标Controller有对应功能否则需要调整业务方案4. Controller 与网关实现选型4.1 主流实现横向对比Gateway API的Controller选择比Ingress时期更丰富但也更让人眼花缭乱。我们横向评估了四类主流实现NGINX Gateway FabricNGFNGINX官方推出的Gateway API实现底层仍然是NGINX引擎兼容性好支持完整的Gateway API标准功能再加上NGINX自身的扩展注解。唯一的问题是NGINX的扩展注解相对较少且部分高级特性比如OIDC集成需要自行实现。Envoy Gateway基于Envoy代理CNCF项目社区非常活跃标准化程度高扩展点丰富。适合对可编程性要求高的场景同时它的扩展策略比NGF更显式。Traefik老牌网关Gateway API支持度不错配置语法与IngressRoute并存社区生态好。不过它的扩展机制通常走Traefik Plugin体系。云厂商控制器AWS Load Balancer Controller、GKE Gateway Controller等优点是和云厂商LB集成度高但通常只能绑定自家云环境对自建IDC不友好。更深一层说我们最终选了NGF和Envoy Gateway做双活验证。原因是NGF的配置语法和nginx-ingress保持高度一致团队现有排障经验基本可复用Envoy Gateway则更适合做统一配置文件的上游后续如果要做服务网格或者更复杂的L7策略它提供的扩展更标准化。4.2 环境准备在正式迁移前先要准备一套Gateway API的CRD。这里有一个大坑不同版本的Controller对CRD的版本要求差别很大。以NGF为例v1.0.0版本的NGF要求集群里安装Gateway API的v1.0.0 CRD而v1.2.0版本的NGF开始要求v1.1.0到v1.3.0则完全依赖v1.2.0。如果CRD版本太低NGF启动时会直接报错并退避。安装CRD的官方命令很简单kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml这个standard-install.yaml里包含了标准版所需的所有CRDGatewayClass、Gateway、HTTPRoute、ReferenceGrant等。如果后续需要实验性功能可以改用experimental-install.yaml但生产环境我建议只用standard。安装后验证一下CRD版本kubectl get crd gateways.gateway.networking.k8s.io -o yaml | grep gateway.networking.k8s.io/v15. 实操迁移从 Ingress 到 HTTPRoute5.1 搭建新的Gateway资源迁移的第一步是搭建网关底座。先创建一个GatewayClass和相应的Gateway。GatewayClass的YAML如下apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: nginx-gateway-class spec: controllerName: gateway.nginx.org/nginx-gateway-controller这里controllerName必须和NGF的Controller配置完全一致否则NGF不会认领这个GatewayClass。然后创建Gateway实例。假设我们有一个共用域名入口api.example.com需要HTTP/HTTPS监听apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: production-gateway namespace: gateway-system spec: gatewayClassName: nginx-gateway-class listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 hostname: api.example.com tls: certificateRefs: - kind: Secret name: api-example-com-tls namespace: cert-manager allowedRoutes: namespaces: from: All这个Gateway声明了一个80端口HTTP监听以及一个绑定api.example.com域名证书的443端口HTTPS监听。如果业务里还有其他域名可以继续增加listener或者在同一个listener下面通过TLS的SNI选择证书但那样需要配好hostname匹配规则。生产环境中更常见的做法是每个域名一个监听方便独立控制TLS和路由范围。5.2 编写第一条HTTPRoute我们拿一个最简单的Ingress规则做迁移练习order-api服务作用是把/orders前缀的请求转发到order-serviceNamespace下的order-serviceService的8080端口。原Ingress写法大致如下apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: order-api namespace: ecommerce spec: rules: - host: api.example.com http: paths: - path: /orders pathType: Prefix backend: service: name: order-service port: number: 8080对应的HTTPRouteapiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: order-api-route namespace: ecommerce spec: parentRefs: - name: production-gateway namespace: gateway-system sectionName: https hostnames: - api.example.com rules: - matches: - path: type: PathPrefix value: /orders backendRefs: - name: order-service namespace: ecommerce port: 8080 weight: 100这里有几个关键细节parentRefs里必须写清Gateway的Namespace和sectionName。sectionName指定打给HTTPS监听不写的话所有监听都会尝试接管这条Route容易产生不必要的冲突。hostnames字段负责匹配SNI和Host头比Ingress的rules.host更直观。backendRefs里的namespace如果和HTTPRoute同Namespace可以省略但显式写出来更清晰。weight默认100如果不做灰度可以不管做灰度时再调整权重。5.3 重写路径的迁移rewrite-target是Ingress里最常用的注解之一。我们线上有一个老服务后端只认根路径/但前端通过/bff/user访问。原Ingress配置metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: api.example.com http: paths: - path: /bff/user(/|$)(.*) pathType: ImplementationSpecific这条规则会把/bff/user/list重写成/list转发给后端Service。迁移到HTTPRoute后rules: - matches: - path: type: PathPrefix value: /bff/user filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: user-service port: 8080注意这里的ReplacePrefixMatch是把命中的/bff/user这个前缀替换成/所以请求/bff/user/list会变成/list和原Ingress的效果完全一致。如果后端需要保留部分前缀可以配合ReplaceFullPath或同时配置更多patches微调。还有一点值得提醒Ingress的rewrite-target: /把所有命中路径全部重置为根路径而Gateway API的ReplacePrefixMatch因为只替换匹配的前缀部分稍微灵活一些。迁移时务必区分“替换整个路径”和“替换前缀”两种语义分清楚再动手否则很容易把API路径调错。5.4 SSL重定向的统一处理Ingress nginx的ssl-redirect注解一般长这样nginx.ingress.kubernetes.io/ssl-redirect: true在HTTPRoute下HTTPS重定向用RequestRedirectfilter实现rules: - matches: - path: type: PathPrefix value: / filters: - type: RequestRedirect requestRedirect: scheme: https statusCode: 301把这个filter放在HTTPRoute的default规则里全域名范围内所有HTTP流量都会被重定向到HTTPS。实际使用中如果只想对特定子路径做重定向放在该路径对应的rule的filters里即可。5.5 灰度发布的迁移这是整个迁移里最“坑”的部分。Ingress nginx的canary注解是nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-weight: 20 nginx.ingress.kubernetes.io/canary-by-header: X-Canary nginx.ingress.kubernetes.io/canary-by-header-value: yes对应HTTPRoute的灰度能力需要拆解成两个部分考虑。基于Header的灰度NGF的HTTPRoute自定义扩展可以精确匹配Header但标准Gateway API在HTTPRoute的matches里也支持Header匹配。例如让HeaderX-Canary: yes的请求走新版本服务其他流量走旧版本spec: parentRefs: - name: production-gateway namespace: gateway-system sectionName: https hostnames: - api.example.com rules: - matches: - headers: - name: x-canary value: yes backendRefs: - name: order-service-v2 port: 8080 - matches: - path: type: PathPrefix value: / backendRefs: - name: order-service-v1 port: 8080基于权重的灰度直接分配权重即可spec: rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: order-service-v1 port: 8080 weight: 80 - name: order-service-v2 port: 8080 weight: 20这里的weight单位是0-1000Ingress的canary-weight单位是0-100。映射时要做换算例如Ingress里canary-weight: 20对应HTTPRoute里weight: 200但更直观的做法是直接把旧服务设为800、新服务设为200。权重值不精确影响不大关键是比例必须正确。实际操作中我建议先只切1%流量观察错误率确认没问题后再放大到5%、20%、50%直至100%。每档观察至少半天到一天如果监控指标有抖动就回退权重。5.6 灰度验证的关键指标迁移完成后验证不能只看“页面能打开”。我在灰度阶段重点观察四个指标网关本身错误率5xx比例这个要看Gateway Pod的监控后端Service的P99延迟看是否因为Gateway层多了处理环节导致延迟劣化TLS握手成功率证书有没有挂错WebSocket连接稳定性如果业务里有WebSocket这步必须测6. 踩坑实录与排查技巧6.1 CRD版本和Controller版本不匹配这是第一个坑。我们的测试集群之前装的是Gateway API v1.0.0部署NGF v1.3.0后Pod一直CrashLoopBackOff。kubectl logs看日志failed to get Gateway API version: the Gateway API CRDs are not installed correctly: expected v1.2.0解决办法是先升级CRD再安装Controller。顺序非常重要如果先安装了新版本Controller再删老CRDController甚至会直接报错退出。升级CRD的命令kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml6.2 同host同path的Ingress规则冲突静默Ingress nginx在处理两个Ingress配置了相同的hostpath时默认会按资源创建时间顺序选第一条生效后面的规则直接变成404。这个行为在Ingress时代我们早就习惯了。但在Gateway API下如果同一条路径在多个HTTPRoute里声明且这些HTTPRoute都关联到同一个Gateway情况会复杂得多。HTTPRoute有优先级规则匹配时按最大匹配精度优先commit时如果两个Route的hostname和path都完全一致Gateway会在状态里报告Conflicted并且该Route不生效。排查方式kubectl get httproute order-api -n ecommerce -o yaml | grep -A 20 status:如果status里有Conflicted就要检查是不是有两条Route规则完全重叠。我们的实际场景是一个历史遗留的子域名Service和主域名的Route规则重叠两个都指向同一个Service但一个新环境一个旧环境旧环境那条Route没清理干净导致新Route一直不生效。6.3 ExternalName Service不能直接映射NGF官方文档明确写了HTTPRoute的backendRefs不支持ExternalName Service。这个限制在Ingress里并不存在但Ingress时代的隐藏问题是ExternalName Service的DNS解析发生在数据面进程内如果后端域名频繁变化会出现连接后端的镜像重建问题。Gateway API推ReferenceGrant和BackendTLSPolicy就是为了把这类特殊情况显式化。迁移时如果遇到ExternalName Service建议改成真正的Kubernetes Service例如用Endpoints对象直接指向后端IP或者用BackendTLSPolicy标准扩展配置后端TLS验证不要在Gateway层兼容这种“作弊”写法。6.4 跨Namespace引用必须两步走我们在迁移过程中犯了一个低级错误HTTPRoute在ecommerce命名空间引用了dev-tools命名空间的log-service没有创建ReferenceGrant结果请求一直502。正确做法是在log-service所在命名空间创建ReferenceGrantapiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-ecommerce-ref namespace: dev-tools spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: ecommerce to: - group: kind: Service这个ReferenceGrant的意思很明确允许来自ecommerce这个Namespace的HTTPRoute引用本Namespace内名为log-service的Service。如果不创建Gateway API的Webhook会直接拒绝这条HTTPRoute或者更隐蔽地只在状态里报错。6.5 证书查找与校验Gateway的TLS配置支持证书Secret跨Namespace引用但Secret必须提前存在于目标Namespace。我们在迁移证书时踩到的问题是cert-manager刚签发的新证书因为DNS01挑战完成后还有一段传播延迟Gateway里引用了旧Secret名称导致NGF启动时找不到Secret整个Controller都拉起失败。排查方法kubectl get gateway -n gateway-system -o yaml | grep -B 5 -A 10 tls: kubectl get secret api-example-com-tls -n cert-manager另外注意如果Secret是Let‘s Encrypt签发的不要直接使用cert-manager生成的Secret名一般带随机后缀最好用一个固定的静态Secret作为引用对象让cert-manager通过secretName字段自动更新内容。这类“Secret in-place”模式在Ingress时代我们就在用迁移到Gateway API后依然是最稳的方式。6.6 监控与指标迁移后一定要建立Gateway层的监控。NGF的指标和nginx-ingress不太一样它暴露的是/metrics接口Prometheus格式主要看这几个指标nginx_gateway_http_requests_totalnginx_gateway_http_requests_duration_milliseconds_bucketnginx_gateway_connect_retries_total我们直接把NGF的metrics指标接入了Prometheus又在Grafana里搭了一个初步的Gateway质量看板。刚开始的几天每天都会打开看板对比Ingress时代的P99确认没有明显劣化才放心切最终流量。6.7 紧急回滚方案任何基础设施迁移都必须有回滚预案。我们的方案是保留Ingress Controller运行但把新流量切到Gateway后Ingress规则先不删除。如果发现问题直接把DNS或SLB切回Ingress入口或者给HTTPRoute加一条指向旧Service的权重100的规则。实际执行时的操作顺序分三步把流量切到Gateway观察24小时保留Ingress Controller运行但把nginx-ingress的Ingress规则删除或disabled验证没有别的自动恢复机制确认稳定后回收所有Ingress资源停掉旧Controller当时我们做了一个小小的“双跑”周期让Gateway和Ingress同时存在了接近一周用于全量对比日志和指标。这一步在别的迁移文章里很少被提到但对降低风险确实很有帮助。写在最后的一点体会这次迁移前后花了三个星期其中踩坑最深的两个地方是CRD版本兼容和跨Namespace授权。前者属于环境准备的疏忽后者属于对Gateway API资源模型理解不够扎实。如果你正在做迁移我建议把“先建ReferenceGrant”写进checklist第一条把“核对Controller版本与CRD版本”写进第二条。从长期维护的角度看Gateway API带来的收益非常确定。路由规则、TLS证书、灰度策略、日志格式在团队里终于有了统一的标准语言新人上手后不需要再花一周去学那几十个nginx-ingress注解。如果后续要把入口从NGINX切到Envoy或者换成云厂商的ALBHTTPRoute这些规则几乎可以原样搬走这才是标准化的真正价值。目前我们的生产集群已经稳定运行在Gateway API体系下两周ngnix-ingress Controller还在保留观察。下一步计划把TCPRoute和TLSRoute场景也迁过去顺便把现有的灰度发布流程再打磨一下。如果你有类似场景的迁移经验欢迎交流碰撞。