Skip to main content

Working with EnvoyFilter

1. Understanding EnvoyFilter CRD

Field Description Values
metadata.name Name of the EnvoyFilter resource string
metadata.namespace Namespace where the EnvoyFilter is applied string
spec.workloadSelector Selects the workload(s) to apply this filter to object
spec.filters List of filters to apply to the Envoy configuration array

Example: Basic EnvoyFilter

apiVersion: networking.istio.io/v1beta1
kind: EnvoyFilter
metadata:
  name: custom-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      app: frontend
  filters:
  - filterName: envoy.filters.http.router
    filterType: HTTP
    listenerMatch:
      listenerType: SIDECAR_INBOUND

2. Creating EnvoyFilter Resources

EnvoyFilter resources are used to customize the configuration of Envoy proxies in a service mesh. They allow you to modify various aspects of the proxy's behavior, such as listeners, clusters, and filters.

Field Description Example
metadata.name Name of the EnvoyFilter resource custom-filter
metadata.namespace Namespace where the EnvoyFilter is applied istio-system
spec.workloadSelector.labels Labels to select the workload(s) to which the filter applies {app: frontend}
spec.filters List of filters to apply to the proxy configuration [{name: router, type: HTTP_FILTER}]

Example: Basic EnvoyFilter Definition

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      app: frontend
  filters:
  - filterName: router
    filterType: HTTP_FILTER
    filterConfig:
      statPrefix: custom-router
Note: The workloadSelector is used to target specific workloads. If not specified, the filter will apply to all workloads in the namespace.

3. Configuring HTTP Connection Manager Filters

Property Description Values Notes
http_connection_manager HTTP connection manager configuration object Core configuration for HTTP handling in Envoy
http_filters List of HTTP filters to apply array Each filter is an object with name and config
access_log Access log configuration object Defines how and where to log HTTP traffic
stat_prefix Prefix for statistics generated by the filter string Used to namespace statistics in metrics

Example: Basic HTTP Connection Manager Configuration

http_connection_manager:
  stat_prefix: ingress_http
  access_log:
    - name: envoy.access_loggers.file
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
        path: "/dev/stdout"
  http_filters:
    - name: envoy.filters.http.router
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

Example: Adding a Custom HTTP Filter

http_connection_manager:
  stat_prefix: ingress_http
  http_filters:
    - name: envoy.filters.http.router
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
    - name: custom.http.filter
      typed_config:
        "@type": type.googleapis.com/custom.HttpFilterConfig
        custom_param: "value"

4. Configuring Network Filters

Filter Description Configuration Notes
envoy.filters.listener.http_connection_manager Manages HTTP connections and routing { "http_filters": [...] } Core filter for HTTP traffic
envoy.filters.listener.tcp_proxy Handles TCP traffic proxying { "cluster": "tcp-cluster" } Used for TCP-based services
envoy.filters.listener.tls_inspector Inspects TLS handshake for SNI and ALPN {} Required for TLS-based routing
envoy.filters.listener.http_inspector Inspects HTTP traffic for protocol detection {} Used to detect HTTP/1.1 vs HTTP/2

Example: Configuring HTTP Connection Manager

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: http-connection-manager-filter
spec:
  workloadSelector:
    labels:
      app: frontend
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 80
    patch:
      operation: MERGE
      value:
        listener_filters:
        - name: envoy.filters.listener.http_connection_manager
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.http_connection_manager.v3.HttpConnectionManager
            http_filters:
            - name: envoy.filters.http.router
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

Example: Adding TCP Proxy Filter

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: tcp-proxy-filter
spec:
  workloadSelector:
    labels:
      app: backend
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 9000
    patch:
      operation: MERGE
      value:
        listener_filters:
        - name: envoy.filters.listener.tcp_proxy
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.listener.tcp_proxy.v3.TcpProxy
            cluster: tcp-cluster

5. Implementing Filter Patches

Field Description Values Notes
name Name of the filter patch string Unique identifier within the EnvoyFilter
match Match criteria for applying the patch object Defines where and when to apply the patch
patch Configuration changes to apply object Contains the actual patch operation details

Example: Adding a Custom Filter

name: custom-filter-patch
match:
  context: SIDECAR_INBOUND
  listener:
    portNumber: 8080
    filterChain:
      name: "envoy.http_connection_manager"
patch:
  operation: INSERT_BEFORE
  value:
    name: custom-filter
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.custom.v3.CustomFilter
      config:
        custom_setting: "value"

Example: Modifying Existing Filter Configuration

name: modify-filter-config
match:
  context: SIDECAR_OUTBOUND
  routeConfiguration:
    name: "route-config"
patch:
  operation: MERGE
  value:
    virtual_hosts:
      - name: "modified-host"
        domains:
          - "example.com"
Note: The operation field supports ADD, REPLACE, REMOVE, INSERT_BEFORE, and INSERT_AFTER.
Warning: Incorrect patch operations can break service mesh functionality. Always test in a staging environment.

6. Managing Filter Priority

Priority Level Description Usage
0 Lowest priority, applied last For non-critical filters that should not interfere with core functionality
100 Standard priority, applied after low-priority filters Default for most custom filters
500 High priority, applied before core filters For filters that must run early in the filter chain
1000 Highest priority, applied first For critical filters that must run before any other

Example: Setting Filter Priority in EnvoyFilter

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-filter
spec:
  filters:
  - filterName: envoy.filters.http.router
    filterType: HTTP
    priority: 500
Note: Priority levels are relative to other filters in the same EnvoyFilter and can be overridden by filterChain settings.

7. Configuring Listener Filters

Property Description Values Notes
listener_filters List of listener filters to apply ["tcp_proxy", "http_connection_manager"] Filters applied to the listener in order of definition
name Name of the listener filter "tcp_proxy" Must match a known filter name in Envoy
typed_config Configuration for the listener filter {...} JSON configuration object for the filter

Example: Configuring TCP Proxy Listener Filter

listener_filters:
- name: tcp_proxy
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.listener.tcp_proxy.v3.TcpProxy
    cluster: "tcp-cluster"
    idle_timeout: "30s"
Note: Listener filters are applied to the listener before any connection is established. They can modify or inspect traffic at the listener level.

8. Setting EnvoyFilter Scope

Scope Description Applicable Resources Notes
cluster Applies filter to a specific cluster Cluster Used for modifying traffic behavior to a specific destination
listener Applies filter to a listener Listener Can modify how traffic is received or forwarded at the listener level
route Applies filter to a specific route within a VirtualHost Route Allows fine-grained control over routing decisions and headers
virtualHost Applies filter to a VirtualHost VirtualHost Useful for applying filters to all routes within a host
gateway Applies filter to a gateway Gateway Applies to traffic entering or exiting a gateway

Example: Setting EnvoyFilter Scope to Listener

apiVersion: networking.istio.io/v1beta1
kind: EnvoyFilter
metadata:
  name: listener-filter
spec:
  configPatches:
  - applyTo: LISTENER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 8080
        name: "inbound|8080"
    patch:
      operation: MERGE
      value:
        listener_filters:
        - name: envoy.listener.http_inspector

9. Implementing Rate Limit Filters

Property Description Values Notes
rateLimit Rate limit configuration {} Defines rate limiting rules for traffic
rateLimit.requestsPerUnit Number of requests allowed per time unit 10 Default is 10 requests per unit
rateLimit.unit Time unit for rate limiting MINUTE, HOUR, DAY Valid values are MINUTE, HOUR, DAY
rateLimit.duration Duration of rate limit period 60 Duration in seconds (default 60)

Example: Rate Limit Configuration

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: rate-limit-filter
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        filterChain:
          name: "inbound|8080"
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.http.local_ratelimit
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
          stat_prefix: "http_local_rate_limit"
          token_bucket:
            max_tokens: 100
            tokens_per_fill: 50
            fill_interval: 60s
Note: Rate limiting can be applied to inbound or outbound traffic depending on the context.
Warning: Ensure that rate limits do not block legitimate traffic or cause service degradation.
Rate Limit Type Description Use Case Notes
Local Rate Limit Rate limiting within a single Envoy instance Per-pod or per-instance limits Does not scale across multiple instances
Global Rate Limit Rate limiting across multiple Envoy instances Cluster-wide or service-wide limits Requires external rate limiting service (e.g., Redis, Google Cloud)

10. Troubleshooting EnvoyFilter Issues

Example: Checking EnvoyFilter Application Status

apiVersion: networking.istio.io/v1beta1
kind: EnvoyFilter
metadata:
  name: example-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      app: example-app
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 15006
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.http.router
Issue Description Solution
Filter Not Applied EnvoyFilter not applied to the target workload Verify workloadSelector matches workload labels
Incorrect Patch Operation Using wrong operation (e.g., ADD instead of REPLACE) Use correct operation for desired modification
Port Mismatch Specified port does not match actual listener port Check listener.portNumber matches the target port
Context Mismatch Applying filter to wrong context (e.g., SIDECAR_INBOUND when it should be GATEWAY) Ensure context matches the intended proxy type
Note: Use istioctl proxy-config to inspect the actual configuration applied to a proxy.

Example: Inspecting Proxy Configuration

istioctl proxy-config listener <pod-name> -n <namespace>

Workflow: Debugging EnvoyFilter Application

  1. Verify workloadSelector matches labels of target pods
  2. Check that portNumber in listener matches actual port used by the proxy
  3. Confirm context is appropriate for the proxy type (inbound, outbound, gateway)
  4. Use istioctl proxy-config to inspect actual configuration applied
  5. Review logs from istiod for EnvoyFilter application errors

11. Implementing Custom Header Filters

Property Description Example
header.name Name of the header to filter X-Custom-Header
header.value Value to match or set for the header custom-value
header.operation Operation to perform on the header (add, remove, replace) add

Example: Adding a Custom Header

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-header-filter
spec:
  filters:
  - filterChain:
    - listenerName: "http"
      filterName: "envoy.http_connection_manager"
      filterType: "HTTP"
      insert:
        - name: "envoy.filters.http.header_to_metadata"
          typedConfig:
            "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config"
            requestHeadersToAdd:
            - header:
                name: "X-Custom-Header"
                value: "custom-value"

Example: Removing a Header

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: remove-header-filter
spec:
  filters:
  - filterChain:
    - listenerName: "http"
      filterName: "envoy.http_connection_manager"
      filterType: "HTTP"
      insert:
        - name: "envoy.filters.http.router"
          typedConfig:
            "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
            dynamicStats: "true"

12. Managing EnvoyFilter Versioning

Version Changes Notes
v1alpha3 EnvoyFilter in istio.io/api Initial stable version with full support for Envoy configuration
v1beta1 Updated schema with listener_filters, network_filters Enhanced filter support; backward compatible with v1alpha3
v1 NEW filter_chains, http_filters Major update with improved configuration structure and new filter types

Example: Applying EnvoyFilter v1

apiVersion: networking.istio.io/v1
kind: EnvoyFilter
metadata:
  name: custom-filter
spec:
  workloadSelector:
    labels:
      app: frontend
  config:
    http_filters:
    - name: custom-filter
      typed_config:
        &#34;@type&#34;: type.googleapis.com/envoy.extensions.filters.http.custom.v1.CustomFilter
        config:
          param1: value1
Note: Ensure all EnvoyFilter resources are validated against the target Istio version to avoid runtime errors.

Was this article helpful?