Envoy过滤器(Envoy Filter)CRD说明

Envoy Filter用于自定义控制面生成的Envoy配置。您可以使用Envoy Filter修改配置中某些字段的值、添加特定的过滤器、添加全新的监听器、Cluster(Envoy中Cluster指一组接受来自Envoy的流量的上游主机)等。与其他Istio网络对象不同,Envoy Filters是叠加应用。对于特定命名空间中的给定工作负载,可以存在任意数量的Envoy Filters。本文介绍Envoy Filter的注意事项、配置示例和字段说明。

注意事项

  • 使用此功能需谨慎操作,不正确的配置可能会破坏整个网格的稳定性。

  • 此API的某些方面与Istio网络子系统的内部实现以及Envoy的XDS API紧密相连。虽然Envoy Filter API本身将保持向后兼容性,但在服务网格版本升级过程中,通过此机制提供的任何Envoy配置都应仔细检查,以确保已删除和适当替换已弃用字段。

  • 当多个Envoy Filters绑定到给定命名空间中的同一工作负载时,所有补丁将按创建时间的顺序依次处理。如果多个Envoy Filters配置之间存在冲突,将会导致未定义的行为。

  • 若要将Envoy Filter资源应用于系统中的所有工作负载(Sidecar和Gateway),请在istio-system命名空间中定义资源,资源中不要添加workloadSelector字段。

配置示例

示例一:为所有Sidecar的出站端口9307添加自定义协议过滤器

在名为istio-config的istio-system命名空间中声明一个全局默认EnvoyFilter资源,为系统中所有Sidecar的出站端口9307添加自定义协议过滤器。该过滤器声明在tcp_proxy过滤器执行之前生效。同时,它还为网关和Sidecar中的所有HTTP连接设置了30秒的空闲超时时间。

展开查看EnvoyFilter YAML

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-protocol
  namespace: istio-config # as defined in meshConfig resource.
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: SIDECAR_OUTBOUND # will match outbound listeners in all sidecars
      listener:
        portNumber: 9307
        filterChain:
          filter:
            name: "envoy.filters.network.tcp_proxy"
    patch:
      operation: INSERT_BEFORE
      value:
        # This is the full filter config including the name and typed_config section.
        name: "envoy.extensions.filters.network.mongo_proxy"
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.mongo_proxy.v3.MongoProxy"
          ...
  - applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
    match:
      # context omitted so that this applies to both sidecars and gateways
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: MERGE
      value:
        name: "envoy.filters.network.http_connection_manager"
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
          common_http_protocol_options:
            idle_timeout: 30s

示例二:为发往bookinfo命名空间中的reviews服务8080端口的所有入站HTTP调用开启Envoy的Lua过滤器

以下示例为发往bookinfo命名空间中的reviews服务8080端口的所有入站HTTP调用开启Envoy的Lua过滤器。Lua过滤器调用一个外部服务internal.org.net:8888,它需要在Envoy中有一个特殊的cluster定义。作为配置的一部分,此cluster信息也将被添加到Sidecar。

展开查看EnvoyFilter YAML

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: reviews-lua
  namespace: bookinfo
spec:
  workloadSelector:
    labels:
      app: reviews
  configPatches:
    # The first patch adds the lua filter to the listener/http connection manager
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 8080
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.filters.http.router"
    patch:
      operation: INSERT_BEFORE
      value: # lua filter specification
       name: envoy.filters.http.lua
       typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          inlineCode: |
            function envoy_on_request(request_handle)
              -- Make an HTTP call to an upstream host with the following headers, body, and timeout.
              local headers, body = request_handle:httpCall(
               "lua_cluster",
               {
                [":method"] = "POST",
                [":path"] = "/acl",
                [":authority"] = "internal.org.net"
               },
              "authorize call",
              5000)
            end
  # The second patch adds the cluster that is referenced by the lua code
  # cds match is omitted as a new cluster is being added
  - applyTo: CLUSTER
    match:
      context: SIDECAR_OUTBOUND
    patch:
      operation: ADD
      value: # cluster specification
        name: "lua_cluster"
        type: STRICT_DNS
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: lua_cluster
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    protocol: TCP
                    address: "internal.org.net"
                    port_value: 8888

示例三:覆写位于istio-system命名空间下的入口网关监听器中的过滤器

以下示例针对SNI主机名app.example.com,覆写位于istio-system命名空间下的入口网关监听器中的过滤器http_connection_manager中的部分字段(HTTP idle timeout和X-Forward-For trusted hops)。

展开查看EnvoyFilter YAML

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: hcm-tweaks
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
    match:
      context: GATEWAY
      listener:
        filterChain:
          sni: app.example.com
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
          xff_num_trusted_hops: 5
          common_http_protocol_options:
            idle_timeout: 30s

示例四:在myns命名空间中插入一个attributegen过滤器

以下示例插入了一个attributegen过滤器,用于生成istio_operationId属性,该属性由istio.stats过滤器消费。filterClass: STATS编码了这种依赖关系。

展开查看EnvoyFilter YAML

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: reviews-request-operation
  namespace: myns
spec:
  workloadSelector:
    labels:
      app: reviews
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      filterClass: STATS # This filter will run *before* the Istio stats filter.
      value:
        name: istio.request_operation
        typed_config:
         "@type": type.googleapis.com/udpa.type.v1.TypedStruct
         type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
         value:
           config:
             configuration: |
               {
                 "attributes": [
                   {
                     "output_attribute": "istio_operationId",
                     "match": [
                       {
                         "value": "ListReviews",
                         "condition": "request.url_path == '/reviews' && request.method == 'GET'"
                       }]
                   }]
               }
             vm_config:
               runtime: envoy.wasm.runtime.null
               code:
                 local: { inline_string: "envoy.wasm.attributegen" }

示例五:在myns命名空间中插入一个HTTP ext_authz过滤器

展开查看EnvoyFilter YAML

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: myns-ext-authz
  namespace: myns
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: ADD
      filterClass: AUTHZ # This filter will run *after* the Istio authz filter.
      value:
        name: envoy.filters.http.ext_authz
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
          grpc_service:
            envoy_grpc:
              cluster_name: acme-ext-authz
            initial_metadata:
            - key: foo
              value: myauth.acme # required by local ext auth server.

字段说明

EnvoyFilter

EnvoyFilter提供一种机制来自定义控制面生成的Envoy配置。EnvoyFilters按照生效优先级从高到低依次为:istio-system命名空间中的所有EnvoyFilters、工作负载命名空间中所有匹配的EnvoyFilters。

字段

类型

是否必选

说明

workloadSelector

WorkloadSelector

用于选择Pod的条件,被选中的Pod将应用此补丁配置。如果省略,则该配置中的补丁集将应用于同一命名空间中的所有工作负载实例。如果EnvoyFilter存在于istio-system命名空间中,则它将应用于任何命名空间中的所有适用工作负载。

configPatches

EnvoyConfigObjectPatch[]

具有匹配条件的一个或多个补丁。

priority

int32

优先级定义在上下文中应用补丁集的顺序。当一个补丁依赖于另一个补丁时,补丁应用的顺序较为重要。

API提供以下两种主要的补丁排序原则:

  • istio-system命名空间中的补丁集先于工作负载命名空间中的补丁集应用。

  • 补丁集中的补丁按照它们在configPatches列表中出现的顺序进行处理。

  • 若存在多个补丁集时,补丁集按升序关键字排序:优先级、创建时间、完全限定资源名称。

priority的默认值为0,取值范围为[min-int32,max-int32]。具有负优先级的补丁集在默认补丁集之前处理。具有正优先级的补丁集在默认补丁集之后处理。建议从10的倍数优先级值开始,以留有进一步插入的空间。

EnvoyFilter.ProxyMatch

要匹配的代理属性。

字段

类型

是否必选

说明

proxyVersion

string

Golang RE2格式的正则表达式,可以用它来选择使用特定版本的Istio代理。一个代理的Istio版本是从节点元数据字段ISTIO_VERSION中读取,该字段的值是Sidecar代理连接到控制面时,由Sidecar代理提供。该值作为环境变量(ISTIO_META_ISTIO_VERSION)嵌入到Istio代理Docker镜像中。自定义代理实现应提供此元数据变量以利用Istio版本检查选项。

metadata

map<string, string>

该选项用于匹配代理连接到控制面时提供的节点元数据。虽然Envoy的节点元数据类型为Struct,但Pilot只处理字符串键值对。元数据中指定的所有键必须与确切的值匹配。如果任何指定的键不存在或值不能匹配,则将匹配失败。

EnvoyFilter.ClusterMatch

必须满足ClusterMatch中指定的条件才能将补丁应用到集群。

字段

类型

是否必选

说明

portNumber

uint32

Cluster的服务端口。如果省略,则适用于任何端口的Cluster。

说明

对于入站Cluster,此字段应是服务的目标端口。

service

string

此集群的完全限定服务名称。如果省略,则适用于任何服务的Cluster。对于通过集群外服务(Service Entry)定义的服务,服务名称与集群外服务中定义的主机相同。

说明

对于入站Cluster,此字段将被忽略。

subset

string

与服务关联的子集。如果省略,则适用于服务的任何子集的Cluster。

name

string

要匹配的Cluster的确切名称。要按名称匹配特定Cluster,例如内部生成的Passthrough集群,请将clusterMatch中除name外的所有字段留空。

EnvoyFilter.RouteConfigurationMatch

必须满足RouteConfigurationMatch中指定的条件,才能将补丁应用于路由配置对象或路由配置中的特定虚拟主机。

字段

类型

是否必选

说明

portNumber

uint32

生成此路由配置的服务端口号或网关服务器端口号。如果省略,则适用于所有端口的路由配置。

portName

string

仅适用于GATEWAY上下文。生成此路由配置的网关服务器端口名称。

gateway

string

生成此路由配置的Istio网关配置的命名空间/名称。仅适用于上下文为GATEWAY的情况。应采用命名空间/名称格式。结合portNumberportName使用此字段,可以准确地为网关配置对象中特定HTTPS服务器选择Envoy路由配置。

vhost

VirtualHostMatch

匹配路由配置中的特定虚拟主机并将补丁应用到虚拟主机。

name

string

要匹配的路由配置名称。可用于按名称匹配特定的路由配置,例如内部http_proxy为所有Sidecar生成的路由配置。

EnvoyFilter.ListenerMatch

必须满足ListenerMatch中指定的条件,才能将补丁应用到所有过滤器链中的特定监听器,或监听器内的特定过滤器链。

字段

类型

是否必选

说明

portNumber

uint32

向Pod发送或接收流量的服务端口或网关端口。如果未指定,则匹配所有监听器。即使是为Pod生成的入站监听器,也应该只使用服务端口(而不是Pod端口)来匹配监听器。

filterChain

FilterChainMatch

匹配监听器中的特定过滤器链。如果指定,补丁将应用于过滤器链(以及指定的特定过滤器)而不是监听器中的其他过滤器链。

listenerFilter

string

匹配特定的监听器过滤器。如果指定,补丁将应用于指定的监听器过滤器。

name

string

按名称匹配特定的监听器。Pilot生成的监听器通常命名为IP:Port

EnvoyFilter.Patch

Patch指定应如何修改所选对象。

字段

类型

是否必选

说明

operation

Operation

指定应如何应用补丁。

value

Struct

正在修补的对象的JSON配置。这将使用Proto合并语义与路径中的现有Proto合并。

filterClass

FilterClass

确定过滤器插入顺序。

EnvoyFilter.EnvoyConfigObjectMatch

将补丁应用于给定代理的生成配置之前需满足的匹配条件。

字段

类型

是否必选

说明

context

PatchContext

要匹配的特定配置生成上下文。控制面会在网关、流量进入Sidecar和流量离开Sidecar的上下文中生成Envoy配置。

proxy

ProxyMatch

匹配与代理关联的属性。

listener

ListenerMatch (oneof)

匹配Envoy的监听器属性。

routeConfiguration

RouteConfigurationMatch (oneof)

匹配Envoy HTTP路由配置属性。

cluster

ClusterMatch (oneof)

匹配Envoy Cluster属性。

EnvoyFilter.EnvoyConfigObjectPatch

对Envoy配置对象进行的更改。

字段

类型

是否必选

说明

applyTo

ApplyTo

指定应在Envoy配置中的哪个位置应用补丁。match应该基于applyTo去选择适当的对象。

  • 对于HTTP_FILTERapplyTo,应该在监听器上设置匹配条件,选择envoy.filters.network.http_connection_manager上的网络过滤器,并选中与插入的位置相关的HTTP过滤器的子过滤器。

  • 对于CLUSTERapplyTo,如果提供了匹配条件,应该在Cluster上匹配,而不是在监听器上。

match

EnvoyConfigObjectMatch

匹配监听器、路由配置或Cluster。

patch

Patch

操作应用的补丁。

EnvoyFilter.RouteConfigurationMatch.RouteMatch

在路由配置中匹配虚拟主机内的特定路由。

字段

类型

是否必选

说明

name

string

默认生成的Route对象被命名为default。虚拟服务生成的路由对象将具有虚拟服务的HTTP路由中使用的名称。

action

Action

匹配具有特定操作类型的路由。

EnvoyFilter.RouteConfigurationMatch.VirtualHostMatch

匹配路由配置中的特定虚拟主机。

字段

类型

是否必选

说明

name

string

Istio生成的VirtualHosts对象命名为host:port,其中host通常对应于VirtualService的host字段或注册表中服务的主机名。

route

RouteMatch

匹配虚拟主机中的特定路由。

EnvoyFilter.ListenerMatch.FilterChainMatch

对于具有多个过滤器链的侦听器(例如具有Permissive mTLS的Sidecar上的入站监听器、具有多个SNI匹配的网关监听器),可以使用过滤器链匹配来选择要修改的特定过滤器链。

字段

类型

是否必选

说明

name

string

分配给过滤器链的名称。

sni

string

过滤器链的匹配条件使用的SNI值。如果过滤器链没有sni匹配,则此条件将为false。

transportProtocol

string

仅适用于SIDECAR_INBOUND上下文。如果非空,则在确定过滤器链匹配时要考虑传输协议。当tls_inspector监听器过滤器检测到新连接时,将比较此值和新连接的传输协议。取值如下:

  • raw_buffer:默认,在未检测到传输协议时使用。

  • tls:当TLS检查器检测到TLS协议时设置。

applicationProtocols

string

仅适用于Sidecar。如果非空,则设置为一组由英文半角逗号(,)分隔的应用协议,用于确定过滤器链匹配。当由类似http_inspector的监听器过滤器检测到新连接时,将比较此值和新连接的应用协议。取值包括h2、http/1.1和http/1.0。

filter

FilterMatch

要应用补丁的特定过滤器的名称。将此字段设置为envoy.filters.network.http_connection_manager,可以添加过滤器或将补丁应用到HTTP Connection Manager。

destinationPort

uint32

过滤器链的匹配使用的destinationPort值。如果过滤器链没有destinationPort匹配,则此条件将为false。

EnvoyFilter.ListenerMatch.FilterMatch

匹配过滤器链中特定过滤器的条件。

字段

类型

是否必选

说明

name

string

要匹配的过滤器名称。对于标准的Envoy过滤器,应使用规范过滤器名称。更多信息,请参见规范过滤器

subFilter

SubFilterMatch

此过滤器中要匹配的下一级过滤器。通常用于HTTP Connection Manager和Thrift过滤器。

EnvoyFilter.ListenerMatch.SubFilterMatch

在过滤器中匹配特定子过滤器的条件。该字段通常用于匹配envoy.filters.network.http_connection_manager网络过滤器内的HTTP过滤器,也适用于Thrift过滤器。

字段

类型

是否必选

说明

name

string

要匹配的过滤器名称。

EnvoyFilter.RouteConfigurationMatch.RouteMatch.Action

Action指定Envoy在HTTP路由匹配时采取的路由动作。

字段

说明

ANY

以下三个动作全部执行。

ROUTE

将流量路由到Cluster或加权Cluster。

REDIRECT

重定向请求。

DIRECT_RESPONSE

直接返回包含特定负载的响应。

EnvoyFilter.Patch.Operation

Operation指定应如何将补丁应用于选中的配置。

字段

说明

MERGE

使用Proto合并语义将提供的配置与生成的配置合并。如果您要完整指定配置,请改用REPLACE

ADD

将提供的配置添加到现有列表(监听器、Cluster、虚拟主机、网络过滤器或HTTP过滤器)。当applyTo设置为ROUTE_CONFIGURATION或HTTP_ROUTE时,将忽略此操作。

REMOVE

从列表(监听器、Cluster、虚拟主机、网络过滤器、路由或HTTP过滤器)中删除所选对象,不需要指定值。当applyTo设置为ROUTE_CONFIGURATION或HTTP_ROUTE时,将忽略此操作。

INSERT_BEFORE

对命名对象数组执行插入操作。此操作通常仅在过滤器或路由的上下文中有用,其中元素的顺序很重要。因为选择的是第一个匹配的元素,路由应基于最具体到最一般的匹配条件进行排序。对于Cluster和虚拟主机,数组中元素的顺序无关紧要。此操作将会在选定的过滤器或子过滤器之前插入。如果没有选择过滤器,指定的过滤器将被插入到列表的前面。

INSERT_AFTER

对命名对象数组上执行插入操作。此操作通常仅在过滤器或路由的上下文中有用,其中元素的顺序很重要。因为选择的是第一个匹配的元素,路由应基于最具体到最一般的匹配条件进行排序。对于Cluster和虚拟主机,数组中元素的顺序无关紧要。此操作将会在选定的过滤器或子过滤器之后插入。如果未选定过滤器,则指定的过滤器将插入到列表的最后面。

INSERT_FIRST

对命名对象数组上执行插入操作。此操作通常仅在过滤器或路由的上下文中有用,其中元素的顺序很重要。因为选择的是第一个匹配的元素,路由应基于最具体到最一般的匹配条件进行排序。对于Cluster和虚拟主机,数组中元素的顺序无关紧要。根据所选过滤器的存在与否在列表的首部插入。当您希望过滤器基于Match子句中指定的匹配条件在列表中排在第一位时,可以使用本字段。

REPLACE

用新内容替换命名过滤器的内容。REPLACE操作仅适用于HTTP_FILTERNETWORK_FILTER。如果未找到命名过滤器,则此操作无效。

EnvoyFilter.Patch.FilterClass

FilterClass用于确定过滤器链中过滤器的插入点,插入点相对于控制平面隐式插入的过滤器而言。此项应与ADD操作一起使用。这是添加过滤器的首选插入机制,而不是使用INSERT_*操作,因为那些操作依赖于潜在不稳定的过滤器名称。如果您的过滤器依赖于或影响过滤器链中的另一个过滤器的功能,则过滤器排序较为重要。在过滤器类中,过滤器按处理顺序插入。

字段

说明

UNSPECIFIED

控制平面决定在何处插入过滤器。如果过滤器是独立于其他过滤器,则不要指定FilterClass。

AUTHN

在Istio身份验证过滤器之后插入过滤器。

AUTHZ

在Istio授权过滤器之后插入过滤器。

STATS

在Istio统计过滤器之前插入过滤器。

EnvoyFilter.ApplyTo

ApplyTo指定应在Envoy配置中的哪个位置应用给定的补丁。

字段

说明

LISTENER

将补丁应用于监听器。

FILTER_CHAIN

将补丁应用于过滤器链。

NETWORK_FILTER

将补丁应用于网络过滤器链,以修改现有过滤器或添加新过滤器。

HTTP_FILTER

将补丁应用于HTTP连接管理器中的HTTP过滤器链,以修改现有过滤器或添加新过滤器。

ROUTE_CONFIGURATION

将补丁应用于HTTP Connection Manager内的路由配置(DRS输出)。该字段不适用于虚拟主机。路由配置对象上仅允许使用MERGE操作。

VIRTUAL_HOST

将补丁应用于路由配置内的虚拟主机。

HTTP_ROUTE

将补丁应用于路由配置中匹配的虚拟主机内的路由对象。

CLUSTER

将补丁应用于CDS输出中的Cluster,也可用于添加新Cluster。

EXTENSION_CONFIG

在ECDS输出中应用补丁或添加扩展配置。仅HTTP过滤器支持ECDS。

BOOTSTRAP

将补丁应用于引导程序配置。

LISTENER_FILTER

将补丁应用于监听器过滤器。

EnvoyFilter.PatchContext

PatchContext根据流量方向和工作负载类型选择一类配置。

字段

说明

ANY

Sidecar和网关中的所有监听器、路由或Cluster。

SIDECAR_INBOUND

Sidecar中的入站所有监听器、路由或Cluster。

SIDECAR_OUTBOUND

Sidecar中的出站监听器、路由或Cluster。

GATEWAY

网关监听器、路由或Cluster。