I've got linkerd running locally per this getting started page, and the basic proxy example works. My use case requires me to proxy web requests to one of several .NET WebApi services, so I made a little sample WebApi project running locally that has two routes:
hello world
["value1", "value2"]
If I leave my linkerd.yaml
file like it comes out-of-the-box:
routers:
- protocol: http
dtab: |
/svc => /#/io.l5d.fs
then mapping routes directly works:
curl -H "Host: web" http://localhost:4140/
--> hello world
curl -H "Host: web" http://localhost:4140/api/values
--> ["value1", "value2"]
Now, I would like to map localhost:4140/tacos
--> localhost:58371/api/values
. So, I update my .yaml file to:
routers:
- protocol: http
dtab: |
/svc => /#/io.l5d.fs;
/tacos => /api/values;
and restart linkerd.
However, http://localhost:4140/
always seems to resolve to http://localhost:58371/tacos
, not http://localhost:58371/api/values
. What am I not understanding?
I've read through a bunch of example dtab transformations on linkerd's site, and I've played around with a bunch of different configurations in my yaml file. Surely it's just something silly that I'm missing because this seems like a really simple use case.
By default, linkerd uses the value of the HTTP Host header associated with the request to route traffic. In your example, you're setting Host: web
, so all traffic is going to the "web" service that's found in service discovery, regardless of the request URI's path.
So rather than sending your request to localhost:4140/tacos
, you should send it to -H 'Host: tacos' localhost:4140/api/values
. You would also need to adjust your dtab as follows:
/svc => /#/io.l5d.fs;
/svc/tacos => /svc/web;
That will route all traffic with Host: tacos
to the "web" service that's found in service discovery. This is just the default configuration, however.
If you're interested in routing based on the URI path instead of the HTTP Host header, you can use linkerd's path identifier. Something like:
routers:
- protocol: http
identifier:
kind: io.l5d.path
segments: 1
dtab: |
/svc => /#/io.l5d.fs;
With that configuration, a request to localhost:4140/api/values
would be routed to the "api" service in service discovery, and a request to localhost:4140/tacos
would be routed to the "tacos" service, and both of those routing decisions can be changed by modifying your dtab.
I should note that linkerd does not do arbitrary HTTP URI path rewriting based on dtab rules. Since it's a proxy, it expects to proxy the request without modification, with a few exceptions (such as the consume
option on the path identifier). You could always write a linkerd plugin though that would fit your specific use case.