功能概述

HTTP 查询参数匹配是 Gateway API 的扩展支持功能,适用于以下场景:

  • 根据版本参数(如 version=v1)路由到不同的后端服务
  • 根据用户类型或权限参数路由到不同的处理逻辑
  • 根据产品类别或搜索条件路由到专门的服务
  • 实现基于查询参数的 A/B 测试或灰度发布

基本语法结构

在 HTTPRoute 资源中,查询参数匹配通过 spec.rules.matches[*].queryParams 字段定义:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:                                 # 元数据,包含资源的基本信息
  name: query-param-matching              # 路由名称,用于标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:                                     # 规格,定义路由的详细配置
  parentRefs:                             # 父引用,指定关联的Gateway资源
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:                                  # 路由规则,定义如何匹配和路由请求
  - matches:                              # 匹配条件,定义请求需要满足的条件
    - queryParams:                        # 查询参数匹配,根据URL查询参数进行匹配
      - name: <参数名>                     # 参数名称,要匹配的查询参数名
        value: <参数值>                    # 参数值,要匹配的查询参数值
    backendRefs:                          # 后端引用,定义匹配后路由到的后端服务
    - name: <后端服务名>                   # 后端服务名称,要路由到的Service名称
      port: <端口号>                       # 后端服务端口,Service的端口号

匹配规则详解

单个查询参数匹配

当只需要根据单个查询参数的值进行路由时,可以使用以下配置:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: single-query-param-route          # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # 当查询参数 animal=whale 时路由到 infra-backend-v1
  - matches:
    - queryParams:
      - name: animal                      # 参数名称,要匹配的查询参数名
        value: whale                      # 参数值,要匹配的查询参数值
    backendRefs:
    - name: infra-backend-v1              # 后端服务名称,匹配成功后路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号
  # 当查询参数 animal=dolphin 时路由到 infra-backend-v2
  - matches:
    - queryParams:
      - name: animal                      # 参数名称,要匹配的查询参数名
        value: dolphin                    # 参数值,要匹配的查询参数值
    backendRefs:
    - name: infra-backend-v2              # 后端服务名称,匹配成功后路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号

当请求包含 animal=whale 查询参数时,会被路由到 infra-backend-v1 服务;当请求包含 animal=dolphin 查询参数时,会被路由到 infra-backend-v2 服务。需要注意的是,查询参数的匹配是精确匹配,大小写敏感。

多个查询参数匹配

当需要根据多个查询参数的组合进行路由时,可以在同一个 matches 中定义多个查询参数:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: multi-query-param-route           # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # 当同时满足 animal=dolphin AND color=blue 时路由到 infra-backend-v3
  - matches:
    - queryParams:
      - name: animal                      # 参数名称,第一个要匹配的查询参数名
        value: dolphin                    # 参数值,第一个查询参数的匹配值
      - name: color                       # 参数名称,第二个要匹配的查询参数名
        value: blue                       # 参数值,第二个查询参数的匹配值
    backendRefs:
    - name: infra-backend-v3              # 后端服务名称,匹配成功后路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号

只有当请求同时包含 animal=dolphincolor=blue 两个查询参数时,才会被路由到 infra-backend-v3 服务。多个查询参数之间是 AND 逻辑关系,必须全部满足。

OR 逻辑匹配

当需要实现 OR 逻辑(满足任一条件即可)时,可以在同一个 rule 中定义多个 matches

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: or-query-param-route              # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # 满足任一条件即路由到 infra-backend-v3
  - matches:
    # 条件1: animal=dolphin AND color=blue
    - queryParams:
      - name: animal                      # 参数名称,第一个查询参数名
        value: dolphin                    # 参数值,第一个查询参数的匹配值
      - name: color                       # 参数名称,第二个查询参数名
        value: blue                       # 参数值,第二个查询参数的匹配值
    # 条件2: ANIMAL=Whale
    - queryParams:
      - name: ANIMAL                      # 参数名称,注意大小写敏感
        value: Whale                      # 参数值,注意大小写敏感
    backendRefs:
    - name: infra-backend-v3              # 后端服务名称,满足任一条件时路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号

当请求满足第一个条件(animal=dolphincolor=blue)时,会被路由到 infra-backend-v3 服务;当请求满足第二个条件(ANIMAL=Whale)时,也会被路由到 infra-backend-v3 服务。多个 matches 之间是 OR 逻辑关系,满足任一即可。

与其他匹配类型组合

查询参数匹配可以与路径匹配、头部匹配等其他匹配类型组合使用:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: combined-match-route              # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # 路径前缀为 /path1 且查询参数 animal=whale
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /path1                     # 路径前缀值
      queryParams:
      - name: animal                      # 参数名称,要匹配的查询参数名
        value: whale                      # 参数值,要匹配的查询参数值
    backendRefs:
    - name: infra-backend-v1              # 后端服务名称,匹配成功后路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号
  
  # 头部包含 version=one 且查询参数 animal=whale
  - matches:
    - headers:
      - name: version                     # 头部名称,要匹配的HTTP头部
        value: one                        # 头部值,要匹配的HTTP头部值
      queryParams:
      - name: animal                      # 参数名称,要匹配的查询参数名
        value: whale                      # 参数值,要匹配的查询参数值
    backendRefs:
    - name: infra-backend-v2              # 后端服务名称,匹配成功后路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号
  
  # 路径前缀为 /path2 且头部包含 version=two 且查询参数 animal=whale
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /path2                     # 路径前缀值
      headers:
      - name: version                     # 头部名称,要匹配的HTTP头部
        value: two                        # 头部值,要匹配的HTTP头部值
      queryParams:
      - name: animal                      # 参数名称,要匹配的查询参数名
        value: whale                      # 参数值,要匹配的查询参数值
    backendRefs:
    - name: infra-backend-v3              # 后端服务名称,匹配成功后路由到的服务
      port: 8080                          # 后端服务端口,服务的端口号

当请求路径以 /path1 开头且包含 animal=whale 查询参数时,路由到 infra-backend-v1;当请求头部包含 version=one 且包含 animal=whale 查询参数时,路由到 infra-backend-v2;当请求路径以 /path2 开头、头部包含 version=two 且包含 animal=whale 查询参数时,路由到 infra-backend-v3。同一 matches 中的不同匹配类型之间是 AND 逻辑关系。

高级用例

版本控制路由

利用查询参数匹配实现 API 版本控制:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: api-version-route                 # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # API v1 路由
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /api                       # 路径前缀值
      queryParams:
      - name: version                     # 参数名称,版本参数名
        value: v1                         # 参数值,版本号v1
    backendRefs:
    - name: api-v1-service                # 后端服务名称,API v1的服务
      port: 80                            # 后端服务端口,服务的端口号
  
  # API v2 路由
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /api                       # 路径前缀值
      queryParams:
      - name: version                     # 参数名称,版本参数名
        value: v2                         # 参数值,版本号v2
    backendRefs:
    - name: api-v2-service                # 后端服务名称,API v2的服务
      port: 80                            # 后端服务端口,服务的端口号
  
  # 默认路由(无版本参数时)
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /api                       # 路径前缀值
    backendRefs:
    - name: api-default-service           # 后端服务名称,默认API服务
      port: 80                            # 后端服务端口,服务的端口号

当请求 /api 且包含 version=v1 时,路由到 api-v1-service;当请求 /api 且包含 version=v2 时,路由到 api-v2-service;当请求 /api 不包含版本参数时,路由到 api-default-service

多条件搜索路由

根据多个查询参数组合实现复杂的搜索路由:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: search-route                      # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # 产品搜索路由
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /search                    # 路径前缀值
      queryParams:
      - name: type                        # 参数名称,搜索类型参数
        value: product                    # 参数值,产品搜索
      - name: category                    # 参数名称,分类参数
        value: electronics                # 参数值,电子产品分类
    backendRefs:
    - name: product-search-service        # 后端服务名称,产品搜索服务
      port: 80                            # 后端服务端口,服务的端口号
  
  # 内容搜索路由
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /search                    # 路径前缀值
      queryParams:
      - name: type                        # 参数名称,搜索类型参数
        value: content                    # 参数值,内容搜索
    backendRefs:
    - name: content-search-service        # 后端服务名称,内容搜索服务
      port: 80                            # 后端服务端口,服务的端口号

当请求 /search 且包含 type=productcategory=electronics 时,路由到 product-search-service;当请求 /search 且包含 type=content 时,路由到 content-search-service

调试模式路由

根据是否存在调试参数路由到调试服务:

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: debug-route                       # 路由名称,标识此HTTPRoute资源
  namespace: default                      # 命名空间,资源所在的命名空间
spec:
  parentRefs:
  - name: example-gateway                 # Gateway名称,要关联的Gateway资源名称
  rules:
  # 调试模式路由(只要存在 debug 参数即匹配)
  - matches:
    - queryParams:
      - name: debug                       # 参数名称,调试参数(仅需存在,无需指定值)
    backendRefs:
    - name: api-debug-service             # 后端服务名称,调试模式服务
      port: 80                            # 后端服务端口,服务的端口号
  
  # 生产模式路由(无 debug 参数时)
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /                          # 路径前缀值(根路径)
    backendRefs:
    - name: api-production-service        # 后端服务名称,生产模式服务
      port: 80                            # 后端服务端口,服务的端口号

当请求包含 debug 参数时(无论值是什么),路由到 api-debug-service;当请求不包含 debug 参数时,路由到 api-production-service

最佳实践

  1. 优先级顺序:在定义多个规则时,应将更具体的匹配规则放在前面,更通用的规则放在后面,因为 Gateway API 会按照规则定义的顺序进行匹配

  2. 参数命名规范:建议使用小写字母和连字符(如 product-category)作为查询参数名,保持一致性

  3. 组合使用:合理组合路径匹配、头部匹配和查询参数匹配,实现更精细的路由控制

  4. 性能考虑:过多的查询参数匹配可能会影响路由性能,建议只使用必要的参数进行匹配

  5. 可维护性:为每个路由规则添加注释,说明其匹配条件和用途,提高可维护性

生产环境推荐配置

在生产环境中使用 HTTP 查询参数匹配时,需要考虑高可用性、安全性、性能和可维护性等因素。以下是一些推荐配置:

高可用性配置

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: production-query-param-route      # 路由名称,生产环境查询参数路由
  namespace: production                   # 命名空间,生产环境命名空间
spec:
  parentRefs:
  - name: production-gateway              # Gateway名称,生产环境Gateway
    namespace: gateway-system             # Gateway所在命名空间
  rules:
  - matches:
    - queryParams:
      - name: version                     # 参数名称,版本参数
        value: v1                         # 参数值,版本号v1
    backendRefs:
    - name: api-v1-service                # 后端服务名称,主要v1服务
      port: 80                            # 后端服务端口,服务的端口号
      weight: 50                          # 权重值,负载均衡权重
    - name: api-v1-service-backup         # 后端服务名称,v1备份服务
      port: 80                            # 后端服务端口,服务的端口号
      weight: 50                          # 权重值,负载均衡权重
  - matches:
    - queryParams:
      - name: version                     # 参数名称,版本参数
        value: v2                         # 参数值,版本号v2
    backendRefs:
    - name: api-v2-service                # 后端服务名称,v2服务
      port: 80                            # 后端服务端口,服务的端口号
      weight: 100                         # 权重值,负载均衡权重

配置要点

  • 使用权重负载均衡提高服务可用性
  • 为关键服务配置备份实例
  • 将 Gateway 和 HTTPRoute 放在不同命名空间,实现更好的权限隔离

安全性配置

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: secure-query-param-route          # 路由名称,安全查询参数路由
  namespace: production                   # 命名空间,生产环境命名空间
  annotations:
    # 配置 TLS 证书
    cert-manager.io/cluster-issuer: "letsencrypt-prod"  # cert-manager 集群发行者配置
spec:
  parentRefs:
  - name: secure-gateway                  # Gateway名称,安全Gateway
    namespace: gateway-system             # Gateway所在命名空间
    sectionName: https                    # Gateway部分名称,指定使用HTTPS
  hostnames:
  - "api.example.com"                     # 主机名,限制访问域名
  rules:
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /api                       # 路径前缀值
      queryParams:
      - name: access_token                # 参数名称,访问令牌参数
        value: "{{ACCESS_TOKEN}}"          # 参数值,访问令牌(实际使用时应通过secrets管理)
    backendRefs:
    - name: secure-api-service            # 后端服务名称,安全API服务
      port: 8080                          # 后端服务端口,服务的端口号

配置要点

  • 使用 TLS 加密保护传输数据
  • 通过 hostnames 限制访问域名
  • 避免在配置中硬编码敏感信息

性能优化配置

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: performant-query-param-route      # 路由名称,高性能查询参数路由
  namespace: production                   # 命名空间,生产环境命名空间
spec:
  parentRefs:
  - name: production-gateway              # Gateway名称,生产环境Gateway
    namespace: gateway-system             # Gateway所在命名空间
  rules:
  # 优先匹配高频请求
  - matches:
    - queryParams:
      - name: version                     # 参数名称,版本参数
        value: stable                     # 参数值,稳定版本
    backendRefs:
    - name: stable-api-service            # 后端服务名称,稳定版本API服务
      port: 80                            # 后端服务端口,服务的端口号
  # 次优先匹配测试版本
  - matches:
    - queryParams:
      - name: version                     # 参数名称,版本参数
        value: beta                       # 参数值,测试版本
    backendRefs:
    - name: beta-api-service              # 后端服务名称,测试版本API服务
      port: 80                            # 后端服务端口,服务的端口号
  # 最后匹配默认版本
  - matches:
    - path:
        type: PathPrefix                  # 路径匹配类型,前缀匹配
        value: /                          # 路径前缀值(根路径)
    backendRefs:
    - name: default-api-service           # 后端服务名称,默认API服务
      port: 80                            # 后端服务端口,服务的端口号

配置要点

  • 将高频请求的匹配规则放在前面,减少匹配时间
  • 保持规则简洁,避免过多的查询参数匹配
  • 使用默认路由作为兜底,提高系统可靠性

监控和可观测性

apiVersion: gateway.networking.k8s.io/v1  # API版本,Gateway API的版本	kind: HTTPRoute                          # 资源类型,定义HTTP路由规则
metadata:
  name: monitored-query-param-route        # 路由名称,带监控的查询参数路由
  namespace: production                   # 命名空间,生产环境命名空间
  annotations:
    # 添加监控注解
    prometheus.io/scrape: "true"          # Prometheus 抓取启用
    prometheus.io/port: "8080"            # Prometheus 抓取端口
    prometheus.io/path: "/metrics"        # Prometheus 抓取路径
spec:
  parentRefs:
  - name: production-gateway              # Gateway名称,生产环境Gateway
    namespace: gateway-system             # Gateway所在命名空间
  rules:
  - matches:
    - queryParams:
      - name: version                     # 参数名称,版本参数
        value: v1                         # 参数值,版本号v1
    backendRefs:
    - name: api-v1-service                # 后端服务名称,v1服务
      port: 80                            # 后端服务端口,服务的端口号
  - matches:
    - queryParams:
      - name: version                     # 参数名称,版本参数
        value: v2                         # 参数值,版本号v2
    backendRefs:
    - name: api-v2-service                # 后端服务名称,v2服务
      port: 80                            # 后端服务端口,服务的端口号

配置要点

  • 添加监控注解,便于 Prometheus 等监控系统采集指标
  • 为不同版本的服务分别配置路由,便于单独监控

配置管理最佳实践

  • 使用 Helm 管理配置:通过 Helm Chart 管理 HTTPRoute 配置,便于版本控制和环境切换
  • 配置分离:将查询参数匹配规则与其他配置分离,提高可维护性
  • 环境变量注入:使用 Kubernetes Secrets 或 ConfigMaps 管理敏感参数值
  • 自动化测试:在部署前测试路由规则的正确性
  • 文档化:为每个路由规则添加详细注释,说明其用途和匹配条件

总结

HTTP 查询参数匹配是 Gateway API 中一个强大的功能,让我们可以根据请求的查询参数实现更精细化的路由控制。通过本文介绍的方法和最佳实践,您可以在实际项目中灵活运用这一功能,为应用提供更智能、更可靠的路由服务。

无论是版本控制、多条件搜索还是调试模式,查询参数匹配都能帮助我们构建更灵活的服务架构。在生产环境中,结合高可用性、安全性和性能优化配置,我们可以充分发挥这一功能的价值,为用户提供更好的服务体验。


关注微信公众号 Linux容器运维 并回复关键字 “视频资料”,即可获取我们整理的 Kubernetes、Docker 容器、Python 编程、Linux 运维等教学视频合集(总计 548GB)。本资源仅面向学习交流使用,请遵守版权和使用规范,严禁商用、转售或违规传播。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐