Little crazy
Little crazy

Reputation: 113

Add header with EnvoyFilter does not work

I am testing istio 1.10.3 to add headers with minikube but I am not able to do so.

Istio is installed in the istio-system namespaces. The namespace where the deployment is deployed is labeled with istio-injection=enabled.

In the config_dump I can see the LUA code only when the context is set to ANY. When I set it to SIDECAR_OUTBOUND the code is not listed:

"name": "envoy.lua",
"typed_config": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua",
"inline_code": "function envoy_on_request(request_handle)\n  request_handle:headers():add(\"request-body-size\", request_handle:body():length())\nend\n\nfunction envoy_on_response(response_handle)\n  response_handle:headers():add(\"response-body-size\", response_handle:body():length())\nend\n"
}

Someone can give me some tips?

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: headers-envoy-filter
  namespace: nginx-echo-headers
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_OUTBOUND
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
            subFilter:
              name: envoy.filters.http.router
    patch:
      operation: INSERT_BEFORE
      value:
       name: envoy.lua
       typed_config:
         '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
         inline_code: |
           function envoy_on_request(request_handle)
             request_handle:headers():add("request-body-size", request_handle:body():length())
           end

           function envoy_on_response(response_handle)
             response_handle:headers():add("response-body-size", response_handle:body():length())
           end
  workloadSelector:
    labels:
      app: nginx-echo-headers
      version: v1

Below is my deployment and Istio configs:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-echo-headers-v1
  namespace: nginx-echo-headers
  labels:
    version: v1
spec:
  selector:
    matchLabels:
      app: nginx-echo-headers
      version: v1
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx-echo-headers
        version: v1
    spec:
      containers:
      - name: nginx-echo-headers
        image: brndnmtthws/nginx-echo-headers:latest
        ports:
          - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-echo-headers-svc
  namespace: nginx-echo-headers
  labels:
    version: v1
    service: nginx-echo-headers-svc
spec:
  type: ClusterIP
  ports:
  - name: http
    port: 80
    targetPort: 8080
  selector:
    app: nginx-echo-headers
    version: v1
---
# ISTIO GATEWAY
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: nginx-echo-headers-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "api.decchi.com.ar"

# ISTIO VIRTUAL SERVICE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-echo-headers-virtual-service
  namespace: nginx-echo-headers
spec:
  hosts:
  - 'api.decchi.com.ar'
  gateways:
  - istio-system/nginx-echo-headers-gateway
  http:
  - route:
      - destination:
          # k8s service name
          host: nginx-echo-headers-svc
          port:
            # Services port
            number: 80
          # workload selector
          subset: v1

## ISTIO DESTINATION RULE
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nginx-echo-headers-dest
  namespace: nginx-echo-headers
spec:
  host: nginx-echo-headers-svc
  subsets:
    - name: "v1"
      labels:
        app: nginx-echo-headers
        version: v1

It is only working when I configure the context in GATEWAY. The envoyFilter is running in the istio-system namespace and the workloadSelector is configured like this:

workloadSelector:
    labels:
      istio: ingressgateway

But my idea is to configure it in SIDECAR_OUTBOUND.

Upvotes: 4

Views: 6184

Answers (2)

Dongfang Qu
Dongfang Qu

Reputation: 351

Here is an example I managed to come up with

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: add-x-cluster-client-ip-header
  namespace: istio-system
spec:
  configPatches:
  - applyTo: ROUTE_CONFIGURATION
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: MERGE
      value:
        request_headers_to_add:
          - header:
              key: 'x-cluster-client-ip'
              value: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
            append: false
        # the following is used to debug
        response_headers_to_add:
          - header:
              key: 'x-cluster-client-ip'
              value: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
            append: false

https://gist.github.com/qudongfang/75cf0230c0b2291006f72cd23d45f297

Upvotes: 1

Mikołaj Głodziak
Mikołaj Głodziak

Reputation: 5267

it is only working when I configure the context in GATEWAY, the envoyFilter is running in the istio-system namespace

That's correct! You should apply your EnvoyFilter in the config root namespace istio-system- in your case.

And the most important part, just omit context field, when matching your configPatches, so that this applies to both sidecars and gateways. You can see the examples of usage in this Istio Doc.

Upvotes: 2

Related Questions