Traefik path based routing in kubernetes ingress not working as expected
Asked Answered
J

4

9

I am trying to use the path based routing mechanism provided by Traefik ingress controller in Kubernetes but I have some issues with the url rewriting.

My [UPDATED] configuration is as follow

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/auth-type: "basic"
    traefik.ingress.kubernetes.io/auth-tls-insecure: "true"
    traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"
    traefik.ingress.kubernetes.io/app-root: "/"
    traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
    traefik.ingress.kubernetes.io/rewrite-target: "/"
  name: webapp-ingress
  namespace: my-company
spec:
  rules:
   - host: local-ubuntu
   - http:
      paths:
      - path: /
        backend:
          serviceName: webapp
          servicePort: 80
      - path: /db
        backend:
          serviceName: db-manager
          servicePort: 8081

The traffic is routed to the right services but the url is still prefixed with /db when I look at the log for the db-manager (kubernetes) service. What I would have expected with the PathPrefixStrip is that the traffic will be routed without the /db prefix to the container running the db-manager micro-service which is listening on / (http://db-manager:8081) on the backend side.

Am I missing something ? Is it supported by traefik or only nginx ? Thank you by advance for your feedback.

[EDIT]

To be more specific I observe the following with the current annotations discussed below

  • traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
  • traefik.ingress.kubernetes.io/rewrite-target: "/"

URL: http://local-ubuntu/db [OK] -> 200

Then other resources are loading but are pointing on the wrong base url

Example:

Resource URL is : http://local-ubuntu/public/css/bootstrap.min.css

But this should be : http://local-ubuntu/db/public/css/bootstrap.min.css (which works when I've tried manually)

I am not sure what I am missing here in the current configuration.

Jamarjamb answered 29/1, 2019 at 1:51 Comment(0)
A
2

Regarding the static contents not being served, the documentation states the following:

Use a *Strip matcher if your backend listens on the root path (/) but should be routeable on a specific prefix. For instance, PathPrefixStrip: /products would match /products but also /products/shoes and /products/shirts. Since the path is stripped prior to forwarding, your backend is expected to listen on /. If your backend is serving assets (e.g., images or Javascript files), chances are it must return properly constructed relative URLs. Continuing on the example, the backend should return /products/shoes/image.png (and not /images.png which Traefik would likely not be able to associate with the same backend). The X-Forwarded-Prefix header (available since Traefik 1.3) can be queried to build such URLs dynamically.

Alcorn answered 1/2, 2019 at 13:37 Comment(3)
Unfortunately even if it seems to be the right approach I cannot test it properly in the ingress definition. For example something like traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip:/db" will generate error when I look at the logs of the traefik ingress pod.Jamarjamb
Thank you very much I misunderstood about it, by modifying the server side (micro-service backend) I needed to check the X-Forwarded-Prefix header before returning the static files with the correct path.Jamarjamb
Could you answer this please ? - #73001582Guffey
J
1

Thank you very much for your help in this matter.

First of all I had to fix an issue regarding the formatting of the annotations in the yaml file.

All the instructions with traefik as a prefix need to be double quoted

Example :

  • traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip [Not
    correct]
  • traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
    [correct]

In the first case none of the annotations were reflected in the ingress.

But I still cannot route properly the traffic. With the current configuration only the resource served on / is returned. None of the js, css or other resources are loaded. So I wonder if I need to use the traefik.frontend.redirect.regex instruction.

Jamarjamb answered 4/2, 2019 at 9:57 Comment(0)
W
1

Try with one of the following:

traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"

traefik.ingress.kubernetes.io/rewrite-target: "/

They both achieve similar results, but they are different, and they have slightly different behavior.

I would read more on our documentation for the differences: (https://docs.traefik.io/v1.7/configuration/backends/kubernetes/#general-annotations)

As for your second issue:

Resource URL is : local-ubuntu/public/css/bootstrap.min.css

But this should be : local-ubuntu/db/public/css/bootstrap.min.css (which works when I've tried

You stripped that path from the request...your DB service never sees the DB prefix...How is it supposed to know to add them back in?

You need to set a root URL in your web application to handle the stripped path.

Once you do that, you may not even need to strip the path at all, and just leave it as is. If you cannot set a base URL for your application, you may not be able to use directories for routing, and may have to use subdomains instead.

Wherein answered 9/8, 2019 at 20:33 Comment(0)
W
0

use only traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
Bellow what I used to send only subpath to my k8s pods

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: global-ingress  
  namespace: app  
  annotations:  
    kubernetes.io/ingress.class: "traefik"  
    traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
Whine answered 29/9, 2021 at 9:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.