惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
Spread Privacy
Spread Privacy
T
Threatpost
C
Cisco Blogs
P
Palo Alto Networks Blog
AI
AI
Cyberwarzone
Cyberwarzone
NISL@THU
NISL@THU
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
Latest news
Latest news
AWS News Blog
AWS News Blog
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
WordPress大学
WordPress大学
Vercel News
Vercel News
S
Securelist
爱范儿
爱范儿
J
Java Code Geeks
Know Your Adversary
Know Your Adversary
S
Schneier on Security
Hugging Face - Blog
Hugging Face - Blog
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
D
DataBreaches.Net
宝玉的分享
宝玉的分享
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
K
Kaspersky official blog
美团技术团队
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
量子位
博客园_首页
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
Google Online Security Blog
Google Online Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
T
Threat Research - Cisco Blogs
雷峰网
雷峰网
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed
S
Security Affairs

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
Kubernetes Gateway API 完全指南
小陈运维 · 2026-05-12 · via 博客园_首页

Kubernetes Gateway API 完全指南

目录

  1. 简介
  2. 基础概念
  3. 架构原理
  4. 实践指南
  5. 最佳实践
  6. 常见问题与故障排查

简介

Kubernetes Gateway API 是一个面向服务的、可扩展的 Kubernetes 流量管理标准,由 SIG-NETWORK 社区维护。它是 Ingress API 的演进版本,旨在解决 Ingress 在表达能力、扩展性和标准化方面的局限性。

为什么需要 Gateway API?

传统 Ingress 的局限性:

  • 功能有限:仅支持 HTTP/HTTPS,缺乏对 TCP、UDP、gRPC 等协议的原生支持
  • 扩展性差:不同 Ingress Controller 使用不同的注解(annotation),导致配置不兼容
  • 表达能力弱:难以实现复杂的流量管理场景(如流量分割、镜像、高级路由匹配)
  • 角色分离不清:基础设施团队和应用团队的职责边界模糊

Gateway API 的优势:

  • 角色导向:明确区分集群操作员、基础设施提供商和应用开发者的职责
  • 表达式丰富:支持更复杂的路由规则、流量管理和安全策略
  • 协议无关:原生支持 HTTP、HTTPS、TCP、UDP、gRPC、TLS 等多种协议
  • 标准化:通过 CRD(Custom Resource Definition)实现跨厂商的一致性
  • 可扩展:通过参数化配置支持厂商特定的扩展

基础概念

核心资源对象

Gateway API 定义了一组相互关联的资源对象,每个对象都有明确的职责:

1. GatewayClass (网关类)

作用:定义网关的实现类型和配置模板,由基础设施提供商创建和管理。

特点:

  • 集群级别资源(Cluster-scoped)
  • 引用具体的 Gateway Controller 实现
  • 一个集群可以有多个 GatewayClass(如 nginx、envoy、istio 等)

示例:

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx-gateway-class
spec:
  controllerName: gateway.networking.k8s.io/nginx-ingress-controller

2. Gateway (网关)

作用:表示实际的负载均衡器实例,定义监听器(Listeners)和网络端点。

特点:

  • 命名空间级别资源(Namespace-scoped)
  • 引用 GatewayClass 确定实现方式
  • 配置监听端口、协议、TLS 证书等
  • 由基础设施团队管理

示例:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: web-app
spec:
  gatewayClassName: nginx-gateway-class
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: All
    - name: https
      port: 443
      protocol: HTTPS
      tls:
        mode: Terminate
        certificateRefs:
          - name: tls-secret
            kind: Secret
      allowedRoutes:
        namespaces:
          from: Same

3. HTTPRoute (HTTP 路由)

作用:定义如何将 HTTP/HTTPS 流量路由到后端服务,是最常用的路由类型。

特点:

  • 支持基于路径、主机名、Header、Query 参数的路由规则
  • 支持流量权重分配(流量分割)
  • 支持请求/响应头修改
  • 支持 URL 重写和重定向
  • 由应用开发者管理

示例:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-app-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
      namespace: web-app
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 8080
          weight: 90
        - name: api-service-v2
          port: 8080
          weight: 10
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-service
          port: 80

4. TCPRoute (TCP 路由)

作用:路由 TCP 流量到后端服务,适用于数据库、消息队列等场景。

示例:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: database-route
  namespace: default
spec:
  parentRefs:
    - name: tcp-gateway
      namespace: default
  rules:
    - backendRefs:
        - name: backend
          port: 3000

5. TLSRoute (TLS 路由)

作用:在 TLS 层面路由流量,支持 TLS Passthrough 模式。

示例:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: tls-passthrough-route
  namespace: default
spec:
  parentRefs:
    - name: tls-gateway
  hostnames:
    - "secure.example.com"
  rules:
    - backendRefs:
        - name: secure-service
          port: 443

6. UDPRoute (UDP 路由)

作用:路由 UDP 流量,适用于 DNS、游戏服务器等场景。

示例:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: UDPRoute
metadata:
  name: dns-route
  namespace: default
spec:
  parentRefs:
    - name: udp-gateway
  rules:
    - backendRefs:
        - name: dns-service
          port: 53

7. GRPCRoute (gRPC 路由)

作用:专门用于 gRPC 流量的路由,支持 gRPC 特有的元数据和方法匹配。

示例:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: grpc-service-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
  hostnames:
    - "grpc.example.com"
  rules:
    - matches:
        - method:
            service: helloworld.Greeter
            method: SayHello
      backendRefs:
        - name: grpc-service
          port: 50051

8. ReferenceGrant (引用授权)

作用:跨命名空间引用的安全机制,允许一个命名空间的资源引用另一个命名空间的资源。

示例:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-gateway-ref
  namespace: web-app
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      namespace: default
  to:
    - group: ""
      kind: Secret
      name: tls-secret

Gateway API vs Ingress 对比

特性 Ingress Gateway API
API 成熟度 Stable (v1) Graduating to Standard (v1)
协议支持 HTTP/HTTPS HTTP, HTTPS, TCP, UDP, gRPC, TLS
路由能力 基于路径和主机 路径、主机、Header、Query、方法等
流量管理 有限 权重分配、镜像、超时、重试
扩展机制 注解(非标准) 参数化配置 + CRD
角色分离 不明确 清晰的三层模型
跨命名空间 不支持 通过 ReferenceGrant 支持
TLS 配置 简单 灵活(Terminate/Passthrough)
供应商兼容性 差异大 标准化程度高

架构原理

整体架构

Gateway API 遵循 Kubernetes 的标准控制器模式,采用声明式 API 设计:

用户/开发者 → Kubernetes API Server → Gateway Controller → Data Plane
     ↓              ↓                        ↓                  ↓
  创建资源      存储CRD资源            监听变化并生成配置    代理处理流量

工作机制详解

1. 资源生命周期

创建阶段:

  1. 用户通过 kubectl apply 创建 Gateway API 资源
  2. API Server 验证资源格式并存储到 etcd
  3. Gateway Controller 通过 Watch 机制检测到新资源
  4. Controller 验证资源的语义正确性
  5. Controller 将配置转换为数据平面的具体配置
  6. Controller 更新资源的 Status 字段,反映配置状态

运行阶段:

  1. 数据平面(如 Envoy)加载最新配置
  2. 客户端请求到达负载均衡器
  3. 数据平面根据路由规则匹配请求
  4. 请求被转发到相应的后端服务
  5. 响应返回给客户端

更新阶段:

  1. 用户修改资源配置
  2. Controller 检测到变更
  3. 重新计算配置并推送到数据平面
  4. 数据平面热重载配置(无中断)

2. 控制平面与数据平面交互

控制平面组件:

  • Gateway Controller:核心控制器,负责资源协调
  • Configuration Generator:将 Gateway API 资源转换为代理特定配置
  • Status Updater:更新资源状态,提供可观测性

数据平面组件:

  • Proxy:实际的流量处理引擎(Envoy/Nginx/HAProxy 等)
  • Config Listener:监听配置变化并应用
  • Metrics Exporter:导出监控指标

3. 状态反馈机制

Gateway API 强调可观测性,每个资源都有详细的 Status 字段:

Gateway Status 示例:

status:
  conditions:
    - type: Accepted
      status: "True"
      reason: Accepted
      message: Gateway successfully accepted
    - type: Programmed
      status: "True"
      reason: Programmed
      message: Configuration programmed to data plane
  listeners:
    - name: http
      attachedRoutes: 5
      conditions:
        - type: Ready
          status: "True"

实践指南

环境准备

前置要求:

  • Kubernetes 集群 (v1.22+)
  • kubectl 命令行工具
  • Helm v3 (可选,用于简化安装)

步骤 1: 部署 metallb

自建集群没有LB所以需要一个负载

下载部署

# 下载应用包
wget https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml

# 修改镜像地址
# 自行找代理
sed -i "s#quay.io#quay.chenby.cn#g" metallb-native.yaml 
cat metallb-native.yaml | grep image
        image: quay.chenby.cn/metallb/controller:v0.14.5
        image: quay.chenby.cn/metallb/speaker:v0.14.5
        
# 执行部署
kubectl apply -f metallb-native.yaml

# 可以连接国际网络
# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml

查看运行情况

cby@DESKTOP-IKRNJQE:~$ kubectl -n metallb-system get all
NAME                             READY   STATUS    RESTARTS   AGE
pod/controller-9c6cff498-h7khm   1/1     Running   0          45m
pod/speaker-kp5wl                1/1     Running   0          45m

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/metallb-webhook-service   ClusterIP   10.68.104.187   <none>        443/TCP   45m

NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker   1         1         1       1            1           kubernetes.io/os=linux   45m

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           45m

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-9c6cff498   1         1         1       45m
cby@DESKTOP-IKRNJQE:~$

配置VIP的资源池

# 新版本metallb使用了CR(Custom Resources),这里我们通过IPAddressPool的CR,进行地址池的定义。
# 如果实例中不设置IPAddressPool选择器L2Advertisement;那么L2Advertisement默认为该实例所有的IPAddressPool相关联。

cat > metallb-config-ipaddresspool.yaml << EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.15-192.168.1.19
EOF

# 进行L2关联地址池的绑定。

cat > metallb-config-L2Advertisement.yaml << EOF
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool
EOF

# 执行部署
kubectl apply -f metallb-config-ipaddresspool.yaml
kubectl apply -f metallb-config-L2Advertisement.yaml

步骤 2: 安装 Envoy Gateway

执行部署

# https://gateway.envoyproxy.io/docs/install/install-helm/
# 安装网关 API CRD 和 Envoy 网关
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.7.3 -n envoy-gateway-system --create-namespace

创建测试应用

kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.7.3/quickstart.yaml -n default

# 查看访问地址
cby@DESKTOP-IKRNJQE:~$ kubectl get svc -n envoy-gateway-system
NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                                            AGE
envoy-default-eg-e41e7b31   LoadBalancer   10.68.120.80   192.168.1.15   80:32116/TCP                                       6s
envoy-gateway               ClusterIP      10.68.64.83    <none>         18000/TCP,18001/TCP,18002/TCP,19001/TCP,9443/TCP   30m
cby@DESKTOP-IKRNJQE:~$

测试访问

cby@DESKTOP-IKRNJQE:~$ curl --verbose --header "Host: www.example.com" http://192.168.1.15/get
*   Trying 192.168.1.15:80...
* Established connection to 192.168.1.15 (192.168.1.15 port 80) from 172.30.72.41 port 39072 
* using HTTP/1.x
> GET /get HTTP/1.1
> Host: www.example.com
> User-Agent: curl/8.18.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< content-type: application/json
< x-content-type-options: nosniff
< date: Mon, 11 May 2026 13:51:37 GMT
< content-length: 475
< 
{
 "path": "/get",
 "host": "www.example.com",
 "method": "GET",
 "proto": "HTTP/1.1",
 "headers": {
  "Accept": [
   "*/*"
  ],
  "User-Agent": [
   "curl/8.18.0"
  ],
  "X-Envoy-External-Address": [
   "192.168.1.100"
  ],
  "X-Forwarded-For": [
   "192.168.1.100"
  ],
  "X-Forwarded-Proto": [
   "http"
  ],
  "X-Request-Id": [
   "d30d74c9-2c8e-4249-8ca6-ee24156e3317"
  ]
 },
 "namespace": "default",
 "ingress": "",
 "service": "",
 "pod": "backend-869c8646c5-s4426"
* Connection #0 to host 192.168.1.15:80 left intact
}cby@DESKTOP-IKRNJQE:~$ 

其他可选实现:

  • Envoy Gateway: Envoy 官方实现
  • Istio: 服务网格方案
  • Contour: VMware 维护的 Envoy 控制器
  • Kong: Kong Ingress Controller

步骤 3: 创建 GatewayClass

cat > gatewayclass.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx-gateway-class
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF

应用配置:

kubectl apply -f gatewayclass.yaml
kubectl get gatewayclass

cby@DESKTOP-IKRNJQE:~$ kubectl get gatewayclass
gatewayclass.gateway.networking.k8s.io/nginx-gateway-class created
NAME                  CONTROLLER                                      ACCEPTED   AGE
eg                    gateway.envoyproxy.io/gatewayclass-controller   True       19m
nginx-gateway-class   gateway.envoyproxy.io/gatewayclass-controller   True       18s
cby@DESKTOP-IKRNJQE:~$ 

步骤 4: 部署示例应用

创建两个简单的后端服务用于测试:

cat > demo-app.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-app-v1
  template:
    metadata:
      labels:
        app: web-app-v1
    spec:
      containers:
      - name: web-app-v1
        image: registry.cn-hangzhou.aliyuncs.com/chenby/cby:nginx-v1
        ports:
        - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-app-v2
  template:
    metadata:
      labels:
        app: web-app-v2
    spec:
      containers:
      - name: web-app-v2
        image: registry.cn-hangzhou.aliyuncs.com/chenby/cby:nginx-v2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web-app-v2
  name: web-app-v2
spec:
  selector:
    app: web-app-v2
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web-app-v1
  name: web-app-v1
spec:
  selector:
    app: web-app-v1
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
EOF

同样创建 v2 版本,然后应用:

kubectl apply -f demo-app.yaml

测试查看

cby@DESKTOP-IKRNJQE:~$ kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
backend-869c8646c5-s4426      1/1     Running   0          20m
web-app-v1-844db9d88f-tjwzz   1/1     Running   0          22s
web-app-v2-dd8d978b8-9stzg    1/1     Running   0          22s
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
backend      ClusterIP   10.68.86.118    <none>        3000/TCP   21m
kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP    60d
web-app-v1   ClusterIP   10.68.255.182   <none>        80/TCP     27s
web-app-v2   ClusterIP   10.68.113.128   <none>        80/TCP     27s
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ curl ^[[200~10.68.255.182~^C
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ curl 10.68.255.182
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ curl 10.68.113.128
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 

步骤 5: 配置基本 HTTP 路由

首先创建 Gateway:

cat > gateway.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: web-app
spec:
  gatewayClassName: nginx-gateway-class
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: All
EOF

创建 HTTPRoute:

cat > httproute-basic.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-app-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
      namespace: web-app
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-app-v1
          port: 80
        - name: web-app-v2
          port: 80
EOF

应用配置:

kubectl create namespace web-app
kubectl apply -f gateway.yaml
kubectl apply -f httproute-basic.yaml

# 验证
kubectl get gateway -n web-app
kubectl get httproute -n default

cby@DESKTOP-IKRNJQE:~$ kubectl get gateway -n web-app
NAME                 CLASS                 ADDRESS        PROGRAMMED   AGE
production-gateway   nginx-gateway-class   192.168.1.16   True         13s
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ kubectl get httproute -n default
NAME            HOSTNAMES             AGE
backend         ["www.example.com"]   26m
web-app-route   ["app.example.com"]   56s
cby@DESKTOP-IKRNJQE:~$ 

获取 LoadBalancer IP 并测试:

curl -H "Host: app.example.com" http://192.168.1.16

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 

步骤 6: 配置 TLS 终止

6.1 创建自签名证书(测试用)

openssl genrsa -out tls.key 2048
openssl req -new -key tls.key -out tls.csr -subj "/CN=app.example.com"
openssl x509 -req -in tls.csr -signkey tls.key -out tls.crt -days 365

kubectl create secret tls app-tls-secret \
  --cert=tls.crt \
  --key=tls.key \
  -n web-app

rm tls.key tls.csr tls.crt

6.2 更新 Gateway 配置启用 HTTPS

cat > gateway-with-tls.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: web-app
spec:
  gatewayClassName: nginx-gateway-class
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: All
    - name: https
      port: 443
      protocol: HTTPS
      tls:
        mode: Terminate
        certificateRefs:
          - name: app-tls-secret
            kind: Secret
            group: ""
      allowedRoutes:
        namespaces:
          from: All
EOF

应用更新:

kubectl apply -f gateway-with-tls.yaml

测试 HTTPS 访问:

curl -k -H "Host: app.example.com" https://192.168.1.16

cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 

步骤 7: 配置流量分割(金丝雀发布)

创建将 90% 流量发送到 v1,10% 流量发送到 v2 的路由:

cat > httproute-canary.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-app-canary-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
      namespace: web-app
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-app-v1
          port: 80
          weight: 90
        - name: web-app-v2
          port: 80
          weight: 10
EOF

应用配置:

kubectl delete -f httproute-basic.yaml
kubectl apply -f httproute-canary.yaml

cby@DESKTOP-IKRNJQE:~$ kubectl get HTTPRoute
NAMESPACE   NAME                   HOSTNAMES             AGE
default     backend                ["www.example.com"]   45m
default     web-app-canary-route   ["app.example.com"]   104s
cby@DESKTOP-IKRNJQE:~$

测试流量分割:

for i in {1..20}; do
  curl -s -H "Host: app.example.com" http://192.168.1.16 
done


cby@DESKTOP-IKRNJQE:~$ for i in {1..20}; do
  curl -s -H "Host: app.example.com" http://192.168.1.16 
done
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 

步骤 8: 高级路由配置

cat > httproute-header.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-based-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
      namespace: web-app
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - headers:
            - name: x-version
              value: v2
      backendRefs:
        - name: web-app-v2
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-app-v1
          port: 80
EOF

测试:

kubectl delete -f httproute-canary.yaml
kubectl apply -f httproute-header.yaml

# 不带 Header,访问 v1
curl -H "Host: app.example.com" http://192.168.1.16

# 带 Header,访问 v2
curl -H "Host: app.example.com" -H "x-version: v2" http://192.168.1.16


cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" -H "x-version: v2" http://192.168.1.16
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 

8.2 URL 重写

cat > httproute-rewrite.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: rewrite-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
      namespace: web-app
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api/v1
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /
      backendRefs:
        - name: web-app-v1
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /api/v2
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /
      backendRefs:
        - name: web-app-v2
          port: 80
EOF

测试使用

kubectl delete -f httproute-header.yaml
kubectl apply -f httproute-rewrite.yaml

curl -H "Host: app.example.com" http://192.168.1.16/api/v1
curl -H "Host: app.example.com" http://192.168.1.16/api/v2

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16/api/v1
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16/api/v2
<h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
cby@DESKTOP-IKRNJQE:~$ 

8.3 请求/响应头修改

cat > httproute-modify.yaml << EOF 
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-modify-route
  namespace: default
spec:
  parentRefs:
    - name: production-gateway
      namespace: web-app
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: X-Forwarded-Gateway
                value: "nginx-gateway"
            set:
              - name: X-Custom-Header
                value: "custom-value"
        - type: ResponseHeaderModifier
          responseHeaderModifier:
            add:
              - name: X-Powered-By
                value: "Gateway-API"
      backendRefs:
        - name: web-app-v1
          port: 80
EOF
kubectl delete -f httproute-rewrite.yaml
kubectl apply -f httproute-modify.yaml

curl -v -H "Host: app.example.com" http://192.168.1.16/

cby@DESKTOP-IKRNJQE:~$ curl -v -H "Host: app.example.com" http://192.168.1.16/
*   Trying 192.168.1.16:80...
* Established connection to 192.168.1.16 (192.168.1.16 port 80) from 172.30.72.41 port 46798 
* using HTTP/1.x
> GET / HTTP/1.1
> Host: app.example.com
> User-Agent: curl/8.18.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< server: nginx/1.29.8
< date: Mon, 11 May 2026 14:54:24 GMT
< content-type: text/html
< content-length: 128
< last-modified: Mon, 11 May 2026 14:02:13 GMT
< etag: "6a01e165-80"
< accept-ranges: bytes
< x-powered-by: Gateway-API
< 
<h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p>
* Connection #0 to host 192.168.1.16:80 left intact
cby@DESKTOP-IKRNJQE:~$

最佳实践

1. 安全管理

1.1 使用 RBAC 限制权限

为应用团队创建受限角色,只允许管理 Route 资源:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: gateway-route-manager
  namespace: default
rules:
  - apiGroups: ["gateway.networking.k8s.io"]
    resources: ["httproutes", "grpcroutes"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

1.2 使用 ReferenceGrant 控制跨命名空间访问

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-tls-ref
  namespace: cert-manager
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: Gateway
      namespace: web-app
  to:
    - group: ""
      kind: Secret
      name: wildcard-tls-cert

1.3 TLS 最佳实践

  • 使用通配符证书减少证书管理复杂度
  • 定期轮换证书,建议使用 cert-manager 自动化
  • 优先使用 TLS Terminate 模式
  • 强制 HTTPS,配置 HTTP 到 HTTPS 重定向

2. 性能优化

2.1 合理配置监听器

限制允许的路由来源,减少配置复杂度:

spec:
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              allow-gateway-access: "true"

2.2 避免过度复杂的路由规则

  • 合并相似的路由规则,减少配置数量
  • 使用最具体的匹配条件优先,提高匹配效率
  • 避免过多的 Header/Query 匹配,影响性能

3. 可靠性保障

3.1 渐进式发布策略

金丝雀发布流程:

  1. 部署新版本服务(v2)
  2. 配置 5% 流量到 v2
  3. 监控错误率和延迟
  4. 逐步增加流量比例(10% → 25% → 50% → 100%)
  5. 确认稳定后,移除旧版本
# 阶段 1: 5% 流量
backendRefs:
  - name: web-app-v1
    weight: 95
  - name: web-app-v2
    weight: 5

# 阶段 2: 25% 流量
backendRefs:
  - name: web-app-v1
    weight: 75
  - name: web-app-v2
    weight: 25

# 阶段 3: 100% 流量
backendRefs:
  - name: web-app-v2
    weight: 100

3.2 蓝绿部署

通过快速切换权重实现蓝绿部署:

# 初始状态: 100% 蓝色环境
backendRefs:
  - name: blue-service
    weight: 100
  - name: green-service
    weight: 0

# 切换时: 快速切换到绿色环境
backendRefs:
  - name: blue-service
    weight: 0
  - name: green-service
    weight: 100

4. 多租户隔离

4.1 命名空间隔离策略

spec:
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              environment: production

5. 调试和故障排查

5.1 常见问题诊断清单

问题 1: Gateway 状态为 "Not Accepted"

检查步骤:

# 1. 检查 GatewayClass 是否存在且有效
kubectl get gatewayclass

# 2. 检查 Controller 是否运行
kubectl get pods -n <controller-namespace>

# 3. 查看 Gateway 事件
kubectl describe gateway <name> -n <namespace>

# 4. 检查控制器日志
kubectl logs -n <controller-namespace> -l app=<controller-name>

问题 2: HTTPRoute 未被接受

检查步骤:

# 1. 验证 parentRefs 是否正确
kubectl get httproute <name> -o yaml

# 2. 检查 Gateway 是否允许该命名空间的路由
kubectl describe gateway <gateway-name> -n <namespace>

# 3. 验证后端服务是否存在
kubectl get svc <backend-service-name>

# 4. 检查 ReferenceGrant (如果跨命名空间)
kubectl get referencegrant -A

问题 3: 流量未正确路由

检查步骤:

# 1. 验证路由规则匹配条件
kubectl describe httproute <name>

# 2. 测试后端服务直接访问
kubectl run test --rm -i --tty --image=curlimages/curl -- \
  curl http://<service-name>.<namespace>.svc.cluster.local

# 3. 检查 Gateway 外部 IP
kubectl get gateway <name> -o jsonpath='{.status.addresses}'

# 4. 使用详细输出测试
curl -v -H "Host: <hostname>" http://<gateway-ip><path>

6. 生产环境建议

6.1 高可用架构

  • 部署多个 Controller 副本实现控制器高可用
  • 使用多个 Gateway 实例分散负载
  • 配置跨区域部署提高灾难恢复能力
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0

6.2 备份和恢复

  • 定期备份 Gateway API 资源配置
  • 使用 GitOps 工具(如 ArgoCD、Flux)管理配置
  • 建立配置变更审批流程
# 备份所有 Gateway API 资源
kubectl get gatewayclass,gateway,httproute,tcproute,referencegrant -A -o yaml > gateway-backup.yaml

6.3 容量规划

关键监控指标:

  • 每秒请求数 (RPS)
  • 平均/ P95/P99 延迟
  • 错误率 (4xx, 5xx)
  • 活跃连接数
  • 带宽使用率

6.4 版本升级策略

  • 先在测试环境验证新版本
  • 阅读发行说明,了解破坏性变更
  • 灰度升级,先升级部分节点
  • 保留回滚方案

7. 常见应用场景

场景 1: 多域名托管

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: multi-domain-route
spec:
  parentRefs:
    - name: production-gateway
  hostnames:
    - "app1.example.com"
    - "app2.example.com"
    - "app3.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: shared-backend
          port: 80

场景 2: API 网关

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-gateway-route
spec:
  parentRefs:
    - name: production-gateway
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /users
      backendRefs:
        - name: user-service
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /orders
      backendRefs:
        - name: order-service
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /payments
      backendRefs:
        - name: payment-service
          port: 8080

场景 3: A/B 测试

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: ab-test-route
spec:
  parentRefs:
    - name: production-gateway
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: variant-a
          port: 80
          weight: 50
        - name: variant-b
          port: 80
          weight: 50

常见问题与故障排查

FAQ

Q1: Gateway API 和 Ingress 可以共存吗?

A: 可以。它们使用不同的资源类型,可以同时在集群中运行。建议逐步迁移,先在新服务中使用 Gateway API。

Q2: 如何选择 Gateway Controller 实现?

A: 考虑因素:

  • 功能需求:是否需要 gRPC、TCP 等高级功能
  • 性能要求:吞吐量、延迟指标
  • 生态系统:与现有工具链的集成
  • 社区活跃度:维护频率、问题响应速度
  • 企业支持:是否需要商业支持

推荐选择:

  • 通用场景: Envoy Gateway、NGINX Gateway Fabric
  • 服务网格: Istio
  • 高性能: Envoy Gateway
  • 简单易用: Contour

Q3: Gateway API 的性能如何?

A: Gateway API 本身是控制平面,性能取决于数据平面实现(Envoy/Nginx 等)、配置复杂度和硬件资源。现代实现(如 Envoy)可以达到数十万 QPS,延迟在毫秒级。

Q4: 如何处理 WebSocket 连接?

A: HTTPRoute 天然支持 WebSocket,无需特殊配置。确保后端服务正确处理 Upgrade 头即可。

Q5: 可以实现速率限制吗?

A: Gateway API v1 标准不直接支持速率限制,但可以通过以下方式实现:

  • Controller 特定扩展(如 Envoy Gateway 的 RateLimitFilter)
  • 在服务网格层实现(Istio)
  • 使用外部速率限制服务

Q6: 如何迁移现有的 Ingress 配置?

A: 迁移步骤:

  1. 分析现有 Ingress 资源
  2. 映射 Ingress 规则到 HTTPRoute
  3. 创建对应的 Gateway 资源
  4. 测试新配置
  5. 逐步切换流量
  6. 删除旧 Ingress 资源

可以使用官方工具 ingress2gateway 辅助转换:

kubectl get ingress -A -o yaml | ingress2gateway -f -

Q7: Gateway API 支持哪些 Kubernetes 版本?

A: Gateway API v1 需要 Kubernetes 1.22+,推荐使用最新的稳定版 Kubernetes 以获得最佳支持。

Q8: 如何实现灰度发布的自动化?

A: 结合以下工具:

  • Argo Rollouts:渐进式交付
  • Flagger:自动化的金丝雀分析
  • 自定义控制器:根据监控指标自动调整权重

总结

Kubernetes Gateway API 代表了 Kubernetes 流量管理的未来方向。通过本教程,您应该已经掌握了:

  1. 核心概念:理解了 GatewayClass、Gateway、HTTPRoute 等资源的作用和关系
  2. 架构原理:了解了控制平面和数据平面的交互机制
  3. 实践能力:能够从零搭建 Gateway API 环境并配置各种路由场景
  4. 最佳实践:学会了安全管理、性能优化、可靠性保障等生产环境技巧

下一步学习建议:

  • 深入研究特定 Gateway Controller 的文档
  • 探索服务网格与 Gateway API 的集成
  • 学习 GitOps 工作流管理 Gateway 配置

祝您在 Kubernetes Gateway API 的学习之路上取得成功!

关于

https://www.oiox.cn/

https://www.oiox.cn/index.php/start-page.html

CSDN、GitHub、知乎、开源中国、思否、掘金、简书、华为云、阿里云、腾讯云、哔哩哔哩、今日头条、新浪微博、个人博客

全网可搜《小陈运维》

文章主要发布于微信公众号