为什么 traefik 与路径不匹配 url

why the traefik did not match the url by the path

我正在使用 traefik 2.2.1 作为我的 kubernetes 入口控制器。现在我有一个 url 需要转发,这是我现在的 traefik 配置:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  creationTimestamp: '2021-09-26T09:10:02Z'
  generation: 4
  name: uat-zhuolian-manage-route
  namespace: dabai-uat
  resourceVersion: '106700291'
  selfLink: >-
    /apis/traefik.containo.us/v1alpha1/namespaces/dabai-uat/ingressroutes/uat-zhuolian-manage-route
  uid: d0b82fab-cd6a-49f0-96dc-f6c0f381bcc5
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`zhuolian-pro-manage.example.com`)
      services:
        - name: be-zhuolian-frontend
          port: 80
    - kind: Rule
      match: Host(`zhuolian-pro-manage.example.com`) && Path(`/service`)
      services:
        - name: soa-zhuolian-service
          port: 11032

我想让 traefik 做的是默认将 example.com 转发到 be-zhuolian-frontend。如果请求 url 包含 service,例如 url xxx.example.com/service/foo/bar,则转发到后端服务 soa-zhuolian-service。但是现在当我从远程云主机请求 url 时:

curl --header 'Host:zhuolian-pro-manage.example.com' http://172.19.104.230/service/zhuolian/report/user/captcha -L

显示错误:

[root@fat001 ~]# curl --header 'Host:zhuolian-pro-manage.example.com' http://172.19.104.230/service/zhuolian/report/user/captcha -L
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.19.0</center>
</body>
</html>

好像url和service关键字仍然路由到前端服务,我应该怎么做才能解决这个问题并使service成功匹配到后端服务?

使用PathPrefix而不是path,来自官方文档:

Use Path if your service listens on the exact path only. For instance, Path: /products would match /products but not /products/shoes.

Use a Prefix matcher if your service listens on a particular base path but also serves requests on sub-paths. For instance, PathPrefix: /products would match /products but also /products/shoes and /products/shirts. Since the path is forwarded as-is, your service is expected to listen on /products.

所以像这样调整配置:

spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`zhuolian-pro-manage.example.com`) && PathPrefix(`/service`)
      middlewares:
        - name: service-stripprefix
      services:
        - name: soa-zhuolian-service
          port: 11032
    - kind: Rule
      match: Host(`zhuolian-pro-manage.example.com`)
      services:
        - name: be-zhuolian-frontend
          port: 80