Dynamic header based routing with fallback

865 Views Asked by At

I would like to route traffic to pods based on headers - with a fallback.

The desired result would be a k8s cluster where multiple versions of the same service could be deployed and routed to using header values.

svcA svcB svcC

each of these services (the main branch of git repo) would be deployed either to default namespace or labelled 'main'. any feature branch of each service can also be deployed, either into its own namespace or labelled with the branch name.

Ideally by setting a header X-svcA to a value matching a branch name, we would route any traffic to the in matching namespace or label. If there is no such name space or label, route the traffic to the default (main) pod.

if HEADERX && svcX:label 
    route->svcX:label
else
    route->svcX 

The first question - is this (or something like) even possible with istio or linkerd

2

There are 2 best solutions below

2
On

You can do that using Istio VirtualService

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

Read more here.

1
On

Yes you can rout the request based on a header with Istion & Linkerd

For istio there is nice article : https://dwdraju.medium.com/simplified-header-based-routing-with-istio-for-http-grpc-traffic-ff9be55f83ca

in istio's virtual service you can update the header like :

http:
  - match:
    - headers:
        x-svc-env:
          regex: v2

For linkerd :

Kind = "service-router"
Name = "service"
Routes = [
  {
    Match {
      HTTP {
        PathPrefix = "/api/service/com.example.com.PingService"
      }
    }
    Destination {
      Service       = "pinging"
    },
  },
  {
    Match {
      HTTP {
        PathPrefix = "/api/service/com.example.com.PingService"
        Header = [
          {
            Name  = "x-version"
            Exact = "2"
          },
        ]
      }
    }
    Destination {
      Service       = "pinging"
      ServiceSubset = "v2"
    },
  }