Search code examples
kubernetesgoogle-kubernetes-enginekubernetes-helmistioamazon-eks

Client Pod identity in http request header while internal service call


I have deployed an application on Kubernetes and exposed with Istio service mesh. There is 2 components in the application, UI and API. I am trying to setup canary based setup to enable AB testing. So, for these 2 components, there is 2 versions (v1 and v2) has deployed, so (min) 4 pods are running.

Assume, v1 is stable and v2 is release version. Version v1 will serve real internet traffic and version v2 will serve the request from specific ip address to make sure promotion of version v2 will not impact real production environment. Refer the attached image for clarity of traffic flow within application.

enter image description here

Testing of UI V2 (release version) is quite easy by filter real client ip address of user using virtualService-

    - headers:
        x-forwarded-for:
          regex: .*1.2.3.4.*

Testing of API v2 (release version) is complex, because it is not exposed to internet and must serve traffic only from UI v2 (release version) internally but I am unable to do.

    url = "http://service-api"
    hdr = { 'CALLER_POD' : 'ui_v2_pod_hostname_with_release' }
    req = urllib.request.Request(url, headers=hdr)
    response = urllib.request.urlopen(req)

One hacky trick I have applied in application, added custom http request headers "CALLER_POD" while calling API from UI v2 pod, so that API virtualService can filter out request based on "CALLER_POD". But it looks more complex because it need code refactoring on a broader level and more human manageable in future if any changes come.

Is there any way to add UI v2 pod identity (preferable hostname) in http request header while calling API service internally on Kubernetes or Istio level.


Solution

  • Have you tried using sourceLabels based routing? For example:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: socks-com
    spec:
      hosts:
      - sock.com
      http:
      - match:
        - sourceLabels:
            UI: v2
        - route:
          - destination:
              host: API
              label: v2
      - route:
        - destination:
            host: API
            subset: v1
    

    It would also require DestinationRule update with two subsets.