10-Gateway API

Gateway API

概念引入

在文章 03 中,你学了 Ingress------K8s 的"大门保安",负责根据域名和路径把流量分发到不同 Service。但 Ingress 有几个痛点:

  • 表达能力弱:只支持 HTTP 的 host + path 匹配,想做 header 匹配、权重分流?不行
  • 配置不标准:每个 Ingress Controller 用不同的 annotation,换个 Controller 就要重写配置
  • 角色不分离:运维管网关基础设施,开发管路由规则,但 Ingress 把两者混在一个资源里

Gateway API 就是为了解决这些问题而生的新一代标准。
#mermaid-svg-rx3wZSNEvCbRZzCy{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rx3wZSNEvCbRZzCy .error-icon{fill:#552222;}#mermaid-svg-rx3wZSNEvCbRZzCy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rx3wZSNEvCbRZzCy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rx3wZSNEvCbRZzCy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rx3wZSNEvCbRZzCy .marker.cross{stroke:#333333;}#mermaid-svg-rx3wZSNEvCbRZzCy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rx3wZSNEvCbRZzCy p{margin:0;}#mermaid-svg-rx3wZSNEvCbRZzCy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy .cluster-label text{fill:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy .cluster-label span{color:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy .cluster-label span p{background-color:transparent;}#mermaid-svg-rx3wZSNEvCbRZzCy .label text,#mermaid-svg-rx3wZSNEvCbRZzCy span{fill:#333;color:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy .node rect,#mermaid-svg-rx3wZSNEvCbRZzCy .node circle,#mermaid-svg-rx3wZSNEvCbRZzCy .node ellipse,#mermaid-svg-rx3wZSNEvCbRZzCy .node polygon,#mermaid-svg-rx3wZSNEvCbRZzCy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rx3wZSNEvCbRZzCy .rough-node .label text,#mermaid-svg-rx3wZSNEvCbRZzCy .node .label text,#mermaid-svg-rx3wZSNEvCbRZzCy .image-shape .label,#mermaid-svg-rx3wZSNEvCbRZzCy .icon-shape .label{text-anchor:middle;}#mermaid-svg-rx3wZSNEvCbRZzCy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rx3wZSNEvCbRZzCy .rough-node .label,#mermaid-svg-rx3wZSNEvCbRZzCy .node .label,#mermaid-svg-rx3wZSNEvCbRZzCy .image-shape .label,#mermaid-svg-rx3wZSNEvCbRZzCy .icon-shape .label{text-align:center;}#mermaid-svg-rx3wZSNEvCbRZzCy .node.clickable{cursor:pointer;}#mermaid-svg-rx3wZSNEvCbRZzCy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rx3wZSNEvCbRZzCy .arrowheadPath{fill:#333333;}#mermaid-svg-rx3wZSNEvCbRZzCy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rx3wZSNEvCbRZzCy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rx3wZSNEvCbRZzCy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rx3wZSNEvCbRZzCy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rx3wZSNEvCbRZzCy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rx3wZSNEvCbRZzCy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rx3wZSNEvCbRZzCy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rx3wZSNEvCbRZzCy .cluster text{fill:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy .cluster span{color:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rx3wZSNEvCbRZzCy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rx3wZSNEvCbRZzCy rect.text{fill:none;stroke-width:0;}#mermaid-svg-rx3wZSNEvCbRZzCy .icon-shape,#mermaid-svg-rx3wZSNEvCbRZzCy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rx3wZSNEvCbRZzCy .icon-shape p,#mermaid-svg-rx3wZSNEvCbRZzCy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rx3wZSNEvCbRZzCy .icon-shape .label rect,#mermaid-svg-rx3wZSNEvCbRZzCy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rx3wZSNEvCbRZzCy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rx3wZSNEvCbRZzCy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rx3wZSNEvCbRZzCy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Gateway API(新)
GatewayClass

(基础设施类型)
Gateway

(网关实例)
HTTPRoute

(路由规则)
Ingress(旧)
Ingress

一个资源管所有
角色分离:

运维管 Gateway

开发管 HTTPRoute

原理讲解

Gateway API 的三个核心资源

资源 谁管 作用 类比
GatewayClass 基础设施提供商 定义网关类型(如 nginx、envoy) "我要买什么型号的门"
Gateway 集群运维 创建网关实例,定义监听器和端口 "把门装在哪里,开几个口"
HTTPRoute 应用开发者 定义路由规则(路径、header、权重) "进哪个门走哪条路"

#mermaid-svg-9OcgCDK2oMCXOzNM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9OcgCDK2oMCXOzNM .error-icon{fill:#552222;}#mermaid-svg-9OcgCDK2oMCXOzNM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9OcgCDK2oMCXOzNM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9OcgCDK2oMCXOzNM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9OcgCDK2oMCXOzNM .marker.cross{stroke:#333333;}#mermaid-svg-9OcgCDK2oMCXOzNM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9OcgCDK2oMCXOzNM p{margin:0;}#mermaid-svg-9OcgCDK2oMCXOzNM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM .cluster-label text{fill:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM .cluster-label span{color:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM .cluster-label span p{background-color:transparent;}#mermaid-svg-9OcgCDK2oMCXOzNM .label text,#mermaid-svg-9OcgCDK2oMCXOzNM span{fill:#333;color:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM .node rect,#mermaid-svg-9OcgCDK2oMCXOzNM .node circle,#mermaid-svg-9OcgCDK2oMCXOzNM .node ellipse,#mermaid-svg-9OcgCDK2oMCXOzNM .node polygon,#mermaid-svg-9OcgCDK2oMCXOzNM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9OcgCDK2oMCXOzNM .rough-node .label text,#mermaid-svg-9OcgCDK2oMCXOzNM .node .label text,#mermaid-svg-9OcgCDK2oMCXOzNM .image-shape .label,#mermaid-svg-9OcgCDK2oMCXOzNM .icon-shape .label{text-anchor:middle;}#mermaid-svg-9OcgCDK2oMCXOzNM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9OcgCDK2oMCXOzNM .rough-node .label,#mermaid-svg-9OcgCDK2oMCXOzNM .node .label,#mermaid-svg-9OcgCDK2oMCXOzNM .image-shape .label,#mermaid-svg-9OcgCDK2oMCXOzNM .icon-shape .label{text-align:center;}#mermaid-svg-9OcgCDK2oMCXOzNM .node.clickable{cursor:pointer;}#mermaid-svg-9OcgCDK2oMCXOzNM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9OcgCDK2oMCXOzNM .arrowheadPath{fill:#333333;}#mermaid-svg-9OcgCDK2oMCXOzNM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9OcgCDK2oMCXOzNM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9OcgCDK2oMCXOzNM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9OcgCDK2oMCXOzNM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9OcgCDK2oMCXOzNM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9OcgCDK2oMCXOzNM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9OcgCDK2oMCXOzNM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9OcgCDK2oMCXOzNM .cluster text{fill:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM .cluster span{color:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9OcgCDK2oMCXOzNM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9OcgCDK2oMCXOzNM rect.text{fill:none;stroke-width:0;}#mermaid-svg-9OcgCDK2oMCXOzNM .icon-shape,#mermaid-svg-9OcgCDK2oMCXOzNM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9OcgCDK2oMCXOzNM .icon-shape p,#mermaid-svg-9OcgCDK2oMCXOzNM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9OcgCDK2oMCXOzNM .icon-shape .label rect,#mermaid-svg-9OcgCDK2oMCXOzNM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9OcgCDK2oMCXOzNM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9OcgCDK2oMCXOzNM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9OcgCDK2oMCXOzNM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 路由层(开发管)
基础设施层(运维管)
GatewayClass: nginx
Gateway: my-gateway

监听 :80 和 :443
HTTPRoute: web-route

/ → web-svc
HTTPRoute: api-route

/api → api-svc
HTTPRoute: canary-route

/v2 → v2-svc (20%)

/v2 → v1-svc (80%)

Ingress vs Gateway API 对比

维度 Ingress Gateway API
标准化 ❌ 各 Controller 用不同 annotation ✅ 统一标准,跨 Controller 兼容
路由能力 仅 host + path host + path + header + query + method
流量分割 ❌ 不支持 ✅ 权重分流(金丝雀发布)
角色分离 ❌ 一个资源 ✅ 三层分离(Class/Gateway/Route)
协议支持 HTTP/HTTPS HTTP/HTTPS/TCP/TLS/gRPC
状态 稳定但功能受限 GA(正式可用),持续演进

HTTPRoute 的强大能力

yaml 复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: advanced-route
spec:
  parentRefs:
  - name: my-gateway
    sectionName: http
  hostnames:
  - "app.example.com"
  rules:
  # 规则 1:按 header 路由
  - matches:
    - headers:
      - name: x-version
        value: "v2"
    backendRefs:
    - name: v2-svc
      port: 80

  # 规则 2:按权重分流(金丝雀发布)
  - matches:
    - path:
        value: /api
    backendRefs:
    - name: api-v1
      port: 80
      weight: 90       # 90% 流量到 v1
    - name: api-v2
      port: 80
      weight: 10       # 10% 流量到 v2

  # 规则 3:请求重定向
  - matches:
    - path:
        value: /old-path
    filters:
    - type: RequestRedirect
      requestRedirect:
        path:
          type: ReplaceFullPath
          replaceFullPath: /new-path

迁移路径

大多数 Ingress Controller(Nginx Ingress、Traefik、Kong)已经支持 Gateway API。迁移步骤:

  1. 安装支持 Gateway API 的 Controller
  2. 创建 GatewayClass 和 Gateway
  3. 把 Ingress 规则逐一转换为 HTTPRoute
  4. 验证无误后删除旧 Ingress

动手实验

配套实验位于 docs/labs/beginner/gateway-api/

⚠️ 本实验安装 Gateway API CRD(资源定义),但不安装 Gateway Controller(需要额外网络下载镜像)。学习重点是资源结构和角色分离------Gateway 和 HTTPRoute 的定义方式、与 Ingress 的对比。

本实验用 Gateway API 重新实现 Ingress 的路由规则。

步骤 1:安装 CRD 并创建后端服务

bash 复制代码
cd docs/labs/beginner/gateway-api
bash setup.sh

步骤 2:认识 Gateway 资源

bash 复制代码
# 查看已创建的 Gateway
kubectl get gateway

# 查看 Gateway 的 YAML 定义
kubectl describe gateway my-gateway
cat manifests/gateway.yaml

解读gatewayClassName: nginx 指定用哪种网关实现,listeners 定义监听的端口和协议。这个资源由运维管理------决定网关实例的规格。

步骤 3:认识 HTTPRoute 资源

bash 复制代码
# 查看已创建的 HTTPRoute
kubectl get httproute

# 查看路由规则
kubectl describe httproute app-route
cat manifests/httproute.yaml

解读/api → api:5678/ → web:80。这个资源由开发管理------决定路由规则,不需要关心网关是用 nginx 还是 envoy 实现的。

步骤 4:验证后端服务

bash 复制代码
# 通过 port-forward 直接访问后端(无需网关控制器)
kubectl port-forward svc/web 8080:80 &
curl -s localhost:8080 | head -5
kill %1 2>/dev/null

kubectl port-forward svc/api 8081:5678 &
curl -s localhost:8081
kill %1 2>/dev/null

💡 在完整部署中,Gateway Controller 会自动配置代理,你不需要手动 port-forward。这里直接访问后端是为了验证服务可用。

步骤 5:理解流量分割(金丝雀发布)

bash 复制代码
# 查看权重分流路由定义
cat manifests/canary-route.yaml

# 创建资源(没有 Controller 不会有实际分流效果,但能学习 API 结构)
kubectl apply -f manifests/canary-route.yaml
kubectl get httproute canary-route -o yaml | grep -A10 backendRefs

关键字段weight: 80weight: 20------声明式地定义流量比例,不需要 annotation。

步骤 6:清理

bash 复制代码
bash teardown.sh

自检问题

  1. Gateway API 的三层结构(GatewayClass / Gateway / HTTPRoute)分别由谁管理?

查看答案 **GatewayClass** 由基础设施提供商定义(如 Nginx 提供 nginx GatewayClass)。**Gateway** 由集群运维管理------决定在哪里创建网关实例、监听哪些端口。**HTTPRoute** 由应用开发者管理------定义具体的路由规则。这种分离让运维和开发各司其职,互不干扰。

  1. Ingress 的 annotation 有什么问题?Gateway API 怎么解决的?

查看答案 Ingress 的 annotation 不是标准 API,不同 Controller(Nginx Ingress、Traefik、Kong)用不同的 annotation 实现相同功能。换 Controller 就要改 annotation。Gateway API 是 K8s 官方标准 API,所有兼容的 Controller 都支持相同的 HTTPRoute 语法,换 Controller 不需要改路由配置。

  1. 你的团队要做一个灰度发布(10% 流量到新版本),用 Ingress 和 Gateway API 分别怎么实现?

查看答案 **Ingress**:需要用 Controller 特定的 annotation 实现分流(如 Nginx Ingress 的 `canary` 注解),不可移植。**Gateway API**:直接在 HTTPRoute 的 backendRefs 中设置 `weight: 90` 和 `weight: 10`,标准 API,任何兼容的 Controller 都支持。

下一步

Gateway API 是 Ingress 的未来。你的基础功已经扎实了,接下来进入进阶实战阶段!

🎉 恭喜!你已经完成了 K8s Guide 初学者轨道的全部 11 篇文章。

从零基础到能独立部署、排查、运维 K8s 应用------你已经掌握了核心知识。接下来的面试轨道会帮你把这些知识转化为 Offer。


📚 本文来自 K8s Guide ------ 开源免费的 Kubernetes 中文学习指南

  • 🗺️ 初学者轨道 + 面试轨道,从零基础到拿 Offer 一站式覆盖
  • 🧪 每篇文章配套 Kind 实验脚本,本地一键运行
  • 🔗 本文源码:docs/beginner/20-gateway-api.md

如果对你有帮助,欢迎 Star! github.com/callmebg/k8s-guide

相关推荐
fiveym5 小时前
01 - iPXE + Clonezilla 网络装机原理解析
linux·运维·服务器·网络
虎头金猫5 小时前
如何在群晖NAS上通过Docker部署CloudSaver?群晖部署CloudSaver教程|聚合资源搜索并实现远程访问
运维·服务器·网络·python·docker·容器·pandas
反转180度6 小时前
Qt 6 + C++17 实现 SFTP 批量部署:工业设备运维工具实战解析
运维·c++·qt
雨辰AI7 小时前
RAG 知识库搭建:基于人大金仓构建信创运维问答机器人|全栈国产化落地完整版
运维·ai·机器人·ai编程
-今昭-7 小时前
Ansible
linux·运维·ansible
星野川崎2067 小时前
电商多店运维:云机长期挂机频繁掉线、账号无故风控原因剖析与解决方案
大数据·运维·云计算·电商
mounter6258 小时前
MACsec 全景解析:从技术演进、核心架构到 DPU 硬件卸载与 K8s 大规模调度实战
linux·kubernetes·linux kernel·kernel·macsec
IT邦德9 小时前
Dify1.6基于ubuntu系统的部署实战
linux·运维·ubuntu
蓝速科技10 小时前
蓝速科技会议电子门牌规模化部署与运维成本实测
运维·科技
许彰午10 小时前
# allbytaskid——一个接口扛六个DataStore
运维·服务器·php