Rich
Rich

Reputation: 678

Traefik 'PathPrefix' not working as expected

I have a kube service that has a /customers resource that will return all customers. It can also return a specific customer at /customers/1. I've configured Traefik ingress as follows:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    traefik.frontend.rule.type: PathPrefix
  name: customerd
  namespace: video
spec:
  rules:
  - host: custd.kube
    http:
      paths:
      - backend:
          serviceName: customerd
          servicePort: http
        path: /customers
      - backend:
          serviceName: customerd
          servicePort: http
        path: /custdhealth
      - backend:
          serviceName: customerd
          servicePort: http
        path: /metrics
      - backend:
          serviceName: customerd
          servicePort: http
        path: /sleeper

Note that the following annotation is present: traefik.frontend.rule.type: PathPrefix. From the Traefik documentation:

Use a * Prefix * matcher if your backend 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 backend is expected to listen on /products.

The issue is that when I submit a request to /customers/1 the response is a 404. I've confirmed that the request doesn't reach the service. If I change PathPrefix to PathPrefixStrip requests to /customers return a 404, as expected, since the service isn't listening on /. So it seems like I'm using the annotation correctly.

Any ideas what I'm doing wrong or further troubleshooting steps?

Upvotes: 0

Views: 2955

Answers (1)

Rich
Rich

Reputation: 678

After more debugging I figured out the problem. It wasn’t with how I was using Traefik, it was a misunderstanding on my part about how Golang HTTP routing works. My route was coded as “/customers”. Turns out this route will never satisfy “/customers/{id}”. “/customers/“ however will route both “/customers” and “/customers/{id}”. So after a simple code change it all worked.

One factor complicating my debugging efforts was this behavior isn’t visible by inspecting the (non-Golang library) code or putting in debug log messages.

Upvotes: 4

Related Questions