Header based ingress routing

From a slack Question:

ok so I have a problem to solve… I need to do ingress-type routing for incoming requests which have a special X-ROUTE: header which tells me which sub-application to route to… I know I know… I have tried to get them to use Host: header or URL to separate them but this is not getting changed.

Traefik 1.7 as Ingress Controller doesn’t support routing on non-path options, as is not supported by the Kubernetes Ingress spec (Support query matcher for kubernetes ingress · Issue #3840 · traefik/traefik · GitHub).

But with Traefik 2.0, the new Custom Resource Definition from Traefik called IngressRoute extends the Ingress spec and adds support for Traefik features such as Header based routing.

In the following example, we have two services: one exposing an Nginx deployment and other one exposing an Apache deployment. With the IngressRoute CRD, the match for the router will be the header X-ROUTE:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: headers
spec:
  entrypoints:
    - web
    - websecure
  routes:
  - match: Headers(`X-ROUTE`,`Apache`)
    kind: Rule
    services:
    - name: apache
      port: 80
  - match: Headers(`X-ROUTE`,`nginx`)
    kind: Rule
    services:
    - name: nginx
      port: 80

Full example: https://github.com/raelga/kubernetes-talks/blob/master/traefik/labs/k8s/default/header-routing.yml

With the X-ROUTE: Apache header:

❯ curl http://46.101.68.190/ -H 'X-ROUTE: Apache'  
<html><body><h1>It works!</h1></body></html>

With the X-ROUTE: nginx header:

❯ curl http://46.101.68.190/ -H 'X-ROUTE: nginx' 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Traefik 2.0 is in alpha stages, so not suited for production environments at this point.

More information in:

Aside from Traefik, other Ingress controllers that support Header based routing are:

3 Likes

Thanks @rael for providing a sample. I tried header based routing with traefik 2.0 on my docker desktop. I see “work in progress” screen when accessing the dashboard, I was able to get the data from “http://localhost:30889/api/rawdata”. However, when I try to do curl on localhost by giving the X-ROUTE header, I’m getting the error " Could not resolve host: nginx". I see that both nginx and apache pods are up and running. Could you please suggest on how I get this working?

{“kubernetescrd”:{“HTTP”:{“routers”:{“default/headers-26d3385f527366bae985”:{“entryPoints”:null,“service”:“default/headers-26d3385f527366bae985”,“rule”:“Headers(X-ROUTE,Apache)”},“default/headers-86e05b7392768b133fae”:{“entryPoints”:null,“service”:“default/headers-86e05b7392768b133fae”,“rule”:“Headers(X-ROUTE,nginx)”}},“services”:{“default/headers-26d3385f527366bae985”:{“loadbalancer”:{“servers”:[{“url”:“http://10.1.0.219:80”,“weight”:1}],“method”:“wrr”,“passHostHeader”:true}},“default/headers-86e05b7392768b133fae”:{“loadbalancer”:{“servers”:[{“url”:“http://10.1.0.218:80”,“weight”:1}],“method”:“wrr”,“passHostHeader”:true}}}},“TCP”:{},“TLSOptions”:null,“TLSStores”:null}}