You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes中基于HTTP方法路由同路径微服务请求?

基于K8S实现CQRS模式下的HTTP方法路由

场景

为销售业务的REST服务采用CQRS模式,在K8S集群中部署了两个微服务:

  • 一个Pod专门处理GET请求(查询操作)
  • 另一个Pod专门处理POST、PUT请求(命令操作)

两个服务操作同一销售资源,期望实现以下路由规则:

  • 发往mydomain.com/api/sales/*的GET请求路由至查询服务Pod
  • 发往mydomain.com/api/sales/*的POST、PUT请求路由至命令服务Pod

当前Ingress配置问题

现有Ingress配置将同一路径/api/sales同时映射到两个不同Service,导致路由结果不确定。此外,K8S原生Ingress规范并不支持直接指定HTTP方法的配置项,ChatGPT建议的httpMethods参数属于不存在的伪配置。

原配置代码:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - host: mydomain.com
      http:
        paths:
          - path: /api/sales
            pathType: Prefix
            backend:
              service:
                name: sales-queries-service
                port:
                  name: 80
          - path: /api/sales
            pathType: Prefix
            backend:
              service:
                name: sales-commands-service
                port:
                  name: 80     
  ingressClassName: ingress-nginx

解决方案(无需额外API网关)

由于你使用的是ingress-nginx控制器,可以利用其自定义注解实现基于HTTP方法的路由,无需额外安装第三方API网关。以下是具体实现方式:

方案1:拆分Ingress资源(推荐)

分别为查询服务和命令服务创建独立的Ingress资源,通过ingress-nginx专属注解限制允许的HTTP方法:

查询服务Ingress(仅处理GET请求)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sales-queries-ingress
  annotations:
    # 指定允许的HTTP方法
    nginx.ingress.kubernetes.io/allow-methods: "GET"
    # 添加Nginx片段,对非GET请求返回405
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($request_method !~ ^(GET)$) {
        return 405;
      }
spec:
  ingressClassName: ingress-nginx
  rules:
    - host: mydomain.com
      http:
        paths:
          - path: /api/sales
            pathType: Prefix
            backend:
              service:
                name: sales-queries-service
                port:
                  number: 80

命令服务Ingress(仅处理POST、PUT请求)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sales-commands-ingress
  annotations:
    nginx.ingress.kubernetes.io/allow-methods: "POST,PUT"
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($request_method !~ ^(POST|PUT)$) {
        return 405;
      }
spec:
  ingressClassName: ingress-nginx
  rules:
    - host: mydomain.com
      http:
        paths:
          - path: /api/sales
            pathType: Prefix
            backend:
              service:
                name: sales-commands-service
                port:
                  number: 80

方案2:单个Ingress资源内配置(进阶)

若希望在同一个Ingress中实现规则,可以通过configuration-snippet结合Nginx变量判断请求方法:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sales-combined-ingress
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      # 将GET请求路由到查询服务,其余路由到命令服务
      set $service_name "sales-commands-service";
      if ($request_method = GET) {
        set $service_name "sales-queries-service";
      }
spec:
  ingressClassName: ingress-nginx
  rules:
    - host: mydomain.com
      http:
        paths:
          - path: /api/sales
            pathType: Prefix
            backend:
              service:
                name: $service_name
                port:
                  number: 80

关键注解说明

  • nginx.ingress.kubernetes.io/allow-methods:明确指定该Ingress允许的HTTP方法,多个方法用逗号分隔
  • server-snippet/configuration-snippet:注入自定义Nginx配置片段,实现请求方法的校验和路由逻辑

注意事项

  • 确保集群已正确部署ingress-nginx控制器,上述注解为该控制器专属,不属于K8S原生Ingress规范
  • 拆分Ingress资源的方式更易于维护和排查问题,推荐优先使用

内容的提问来源于stack exchange,提问作者Paulo Merson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:45:09