4

I have an containerized application/service deployed in openshift container platform with istio service mesh. In istio virtual service yaml, i wanted to validate if the http request is having a header(for ex: version) and with value v1. i have added below config in virtual service yaml which validates header. But i am looking for available options to inject this header in HTTP request using loadbalancer/ingress/openshif route etc. As my istio-ingressgateway service is deployed with ClusterIp. i have used openshift route to send the external traffic to ingressgateway. please share the possible ways to add headers to http request

  http:
    - match:
        - headers: # Match header
            version: # header that we decided for dark release
              exact: v1 # exact match


 
Nagendra Vummadi
  • 457
  • 1
  • 5
  • 12

3 Answers3

1

You can use envoy filter to do that.

Below envoy filter add request header called customer-id with alice value to all request going though istio ingress gateway. I also commented code for response headers if someone would like to use it.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: lua-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
            subFilter:
              name: "envoy.router"
    patch:
      operation: INSERT_BEFORE
      value:
       name: envoy.lua
       typed_config:
         "@type": "type.googleapis.com/envoy.config.filter.http.lua.v2.Lua"
         inlineCode: |
            function envoy_on_request(request_handle)
                request_handle:headers():add("customer-id", "alice")
            end
           # function envoy_on_response(response_handle)
           #     response_handle:headers():add("customer-id", "alice")
           # end

There are yamls I've used to test that, it might be useful for testing above filter.

  • If you use above filter with alice header then all requests goes to nginx-v1
  • If you use above filter with bob header then all requests goes to nginx-v2
  • If you delete this filter then it's 50/50 between nginx-v1 and nginx-v2

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v1
spec:
  selector:
    matchLabels:
      run: nginx1
  replicas: 1
  template:
    metadata:
      labels:
        run: nginx1
        app: frontend
    spec:
      containers:
      - name: nginx1
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v2
spec:
  selector:
    matchLabels:
      run: nginx2
  replicas: 1
  template:
    metadata:
      labels:
        run: nginx2
        app: frontend
    spec:
      containers:
      - name: nginx2
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo Hello nginx2 > /usr/share/nginx/html/index.html"]



---

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: frontend
spec:
  ports:
  - name: http-front
    port: 80
    protocol: TCP
  selector:
    app: frontend

---

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gatewayx
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

---

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginxvirt
spec:
  hosts:
  - '*'
  gateways:
  - gatewayx
  http:
  - name: "route-1"
    match:
    - headers:
        customer-id:
          exact: alice
    route:
    - destination:
        host: nginx
        subset: v1
  - name: "route-2"
    match:
    - headers:
        customer-id:
          exact: bob
    route:
    - destination:
        host: nginx
        subset: v2
  - route:
    - destination:
        host: nginx

---

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nginxdest
spec:
  host: nginx
  subsets:
  - name: v1
    labels:
      run: nginx1
  - name: v2
    labels:
      run: nginx2
Jakub
  • 8,189
  • 1
  • 17
  • 31
1

Pretty late to answer this but hope it helps someone.

We can use istio virtual service for adding custom headers to request as well as response.

I am using bookinfo-gateway provided by Istio as an example here:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    route:
    - destination:
        host: productpage
        port:
          number: 9080
      headers:
        request:
          set:
            X-Frame-Options: deny # if request header has X-Frame-Options, it will be overwritten
        response:
          add:
            hello: world # add "hello" with value world in response header
          remove:
            - "foo" # remove foo from response header

I have tested this locally using Minikube v1.25.2, and Istio v1.13, it is working as per expectations.

0

It should be possible to use virtualService like

spec:  
  hosts:  
  - "example.com"  
  gateways:  
  - your-gateway  
  http:  
  -   
    name: remove-headers  
    headers:  
      request:  
        remove:  
        - yourHeader  

But I can't make it works. Please share if you can :)

terrasson marc
  • 97
  • 1
  • 10