Skip to content

Instantly share code, notes, and snippets.

@shpwrck
Last active April 20, 2021 22:16
Show Gist options
  • Save shpwrck/4f80aa2a4094d0d515eb8a6254ecca32 to your computer and use it in GitHub Desktop.
Save shpwrck/4f80aa2a4094d0d515eb8a6254ecca32 to your computer and use it in GitHub Desktop.
envoyfilters.networking.istio.io

Basics

What are envoy filters?

Istio Doc

Envoy Doc

  • Use filters with caution as they could destabilize the mesh!
  • Filters are additive. There will be implicit dependencies and interactions among them.
  • Rootnamespace filters are applied before workload namespace filters.
  • Upgrades are non trivial, as the filter specifications may change.

When should I use envoy filters?

Envoy filters are leveraged when the other Istio primitives are insufficient.

How are they structured?

Level One: What am I applying and to whom am I applying it?

  • Workload Selector
    • If absent, then it will apply to all elements of the mesh.
    • If present and deployed in the root namespace, then it will apply to all namespaces in mesh.
    • If present and deployed in a non-root namespace, then it will apply to the non-root namespace.
    • Leverages basic label syntax: foo: bar
  • ConfigPatches
    • A list of patches to apply, that will be done sequentially.
    • Should be restricted to a single function. (i.e. Create a filter for each "task")

Level Two: What type of envoy resource am I updating, which of those resources am I updating, and what am I applying?

  • ApplyTo
  • Match
    • Allows you to select from gateway, sidecar_in, sidecar_out, and between proxy versions, listeners, filter chains, route configs, and clusters.
    • Rule of Thumb:
      • Proxy & Listener -> Mesh Configuration
      • Clusters -> Kubernetes Services
      • Route Configs -> Headers
      • Network Filters -> Proxy Protocols
      • HTTP Filters -> External Services
      • HTTP Routes -> Headers, Redirects, Responses
  • Patch
    • No validation for patch!

Level Three: What configuration am I changing?

  • Operation (Patch Logic)

    • Add, Remove, Replace, Insert, Insert_Before, Insert_After
    • Before or After should be used with caution, names are unstable
    • You can only replace filters
    • You cannot add or remove route-configs or http-routes.
  • Value

    • Specific to resource being patched.
    • Filters generally include:
     name: "given name"
     typed_config:
       "@type": "type.googleapis.com/envoy.extensions.filters..."
    
  • FilterClass

    • Authn -> after authentication
    • Authz -> after authorization
    • Stats -> before stats

The following list is sorted from general to specific.

(i.e. A listener contains a filter_chain which has either network filters or http filters...etc)

LISTENER:

What is a listener?

proto

Applies the patch to the listener.

FILTER_CHAIN:

What is a filter chain?

proto

Applies the patch to the filter chain.

NETWORK_FILTER:

What is a network filter?

proto

Applies the patch to the network filter chain, to modify an existing filter or add a new filter.

HTTP_FILTER:

What is an http filter?

proto

Applies the patch to the HTTP filter chain in the http connection manager, to modify an existing filter or add a new filter.

ROUTE_CONFIGURATION:

These corelate to the port and protocol of the gateway resource.

proto

Applies the patch to the Route configuration (rds output) inside a HTTP connection manager. This does not apply to the virtual host. Currently, only MERGE operation is allowed on the route configuration objects.

VIRTUAL_HOST:

These corelate to the host of the gateway resource.

proto

Applies the patch to a virtual host inside a route configuration.

HTTP_ROUTE:

proto

These corelate to the match rules in a virtual service.

Applies the patch to a route object inside the matched virtual host in a route configuration.

CLUSTER:

proto

A cluster is comprised of the following elements:

|direction(in/out)|port|subset(v1,v2,...)|uri|

Applies the patch to a cluster in a CDS output. Also used to add new clusters.

BlackHoleCluster and PassthroughCluster allow a use to terminate or pass through traffic external to the mesh (respectively).

EXTENSION_CONFIG:

Applies the patch to or adds an extension config in ECDS output. Note that ECDS is only supported by HTTP filters. (i.e. Anything that isn't a http filter will require a redeploy)

Frequently Asked Questions

What's the difference between an extension config and an http filter?

The extension config will control how all filters of a given type in a given scope will behave. (e.g. If you have an external authorization service with a specific grpc endpoint, then you would create an extension config. Whereas if you had a single service or route that required a legacy version of the grpc_service you would modify the http filter.)

What's the general intention of an envoy filter?

In general an envoy filter should not be used to direct traffic, but to enhance or modify traffic through various filter chains.

When would I want to use an Envoy Filter?

Some common use cases are external auth, advanced routing configuration beyond istio basics, caching, wasm.

What are some standard examples from other Open Source solutions?

# Use Route Configuration to modify the response and request headers.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: add-header
namespace: istio-system
spec:
configPatches:
- applyTo: ROUTE_CONFIGURATION
match:
routeConfiguration:
name: http.80
patch:
operation: MERGE
value:
response_headers_to_add:
- append: true
header:
key: x-gunna
value: give-it-to-ya
# Requires the following annotation per deployment:
# sidecar.istio.io/userVolume: '[{"emptyDir":{},"name":"tmp"}]'
# sidecar.istio.io/userVolumeMount: '[{"mountPath":"/tmp","name":"tmp"}]'
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: tap
namespace: istio-system
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.tap
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.tap.v3.Tap
common_config:
static_config:
match_config:
http_request_headers_match:
headers:
- name: "trigger-sample-capture"
exact_match: "true"
output_config:
sinks:
- format: JSON_BODY_AS_STRING
file_per_tap:
path_prefix: /tmp/tap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment