概述
EnvoyFilter提供了定制化修改服务网格数据面配置的能力,通过EnvoyFilter可以实现修改某个数据面配置字段、添加或修改过滤器、监听器、集群等配置,功能十分强大,所以在使用改功能时必须小心,确保对数据面配置有比较深入的理解;错误的配置可能影响网格数据面的稳定性。
对于任何数据面,允许存在多个EnvoyFilter匹配该数据面,位于根命名空间的EnvoyFilter优先级最高,其次是位于数据面所在的命名空间的EnvoyFilter。
注意
EnvoyFilter API和服务网格底层实现耦合较为紧密,在升级网格版本的时候需要关注已经定义的EnvoyFilter版本和新版本的网格是否存在兼容性问题
多个EnvoyFilter匹配同一个数据面时,生效的优先级为根命名空间下的EnvoyFilter优先级最高,其他的按照创建时间顺序生效;如果EnvoyFilter之间存在冲突,结果是未定义的
需要配置EnvoyFilter匹配不同的工作负载时(比如网关和sidecar),可以考虑在根命名空间下定义,且不配置workloadselector
配置示例
配置示例一
在根命名空间下创建全局生效的EnvoyFilter,在sidecar outbound方向9307端口的tcp proxy插件之前插入mongo的代理配置;为所有数据面(网关和sidecar)的HttpConnectionManager插件配置HTTP空闲连接时间为30秒。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: custom-protocol
namespace: istio-system # 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命名空间下匹配标签app: reviews的工作负载下发自定义配置,在sidecar入站方向HttpConnectionManager中的最后一个Router插件之前插入lua插件,在收到请求后会执行lua代码调用一个外部授权服务;这个外部授权服务通过一个外部域名标识,也通过配置下发到数据面
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"
defaultSourceCode:
inlineString: |
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: ingressgateway标签的网关下发自定义配置,当请求sni是app.example.com时给HttpConnectionManager配置HTTP空闲连接时间和XFF信任的跳数
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
配置说明
EnvoyFilter
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
workloadSelector | WorkloadSelector | N | 用于选择匹配的工作负载 |
configPatches | EnvoyConfigObjectPatch[] | N | 需要下发到数据面的配置 |
priority | int | N | 优先级定义,可用于处理个EnvoyFilter匹配同一个工作负载,且EnvoyFilter之间存在依赖关系的场景 1. 默认的生效顺序为根命名空间 > 工作负载命名空间,在一个EnvoyFilter内的多个patch按照定义的顺序生效 2. 如果优先级为负,则在默认生效规则之前生效,如果为正则在默认生效规则之后生效 3. 建议优先级定义时保留足够的间隔,用于插入新的补丁 |
EnvoyFilter.EnvoyConfigObjectPatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
applyTo | ApplyTo | N | 匹配的位置,可选值包括LISTENER, FILTER_CHAIN, NETWORK_FILTER, HTTP_FILTER, ROUTE_CONFIGURATION, VIRTUAL_HOST, HTTP_ROUTE, CLUSTER, EXTENSION_CONFIG, LISTENER_FILTER |
match | EnvoyConfigObjectMatch | N | 匹配条件 |
patch | Patch | N | 补丁定义 |
EnvoyFilter.EnvoyConfigObjectMatch
Envoy过滤器匹配条件
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
context | PatchContext | N | 匹配的上下文,支持取值包括 ANY:匹配所有流量场景 SIDECAR_INBOUND:匹配sidecar入站方向流量 SIDECAR_OUTBOUND:匹配sidecar出站方向流量 GATEWAY:匹配网关场景 |
proxy | ProxyMatch | N | 匹配数据面代理的版本、元数据等信息 |
listener | ListenerMatch (oneof) | N | 监听器匹配 |
routeConfiguration | RouteConfigurationMatch (oneof) | N | 路由匹配 |
cluster | ClusterMatch (oneof) | N | 集群匹配 |
EnvoyFilter.ProxyMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
proxyVersion | string | N | 基于正则表达式匹配数据面代理版本 |
metadata | map<string, string> | N | 匹配数据面代理的元数据 |
EnvoyFilter.ListenerMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
portNumber | uint32 | N | 匹配监听器的端口号,不指定的话匹配所有端口 |
filterChain | FilterChainMatch | N | 匹配特定filterchain |
listenerFilter | string | N | 基于名字匹配监听器过滤器 |
name | string | N | 基于名字匹配监听器 |
EnvoyFilter.ListenerMatch.FilterChainMatch
存在多个filter chain的情况下可以用于匹配特定filter chain
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
name | uint32 | N | filter chain名称 |
sni | string | N | 匹配sni名称 |
transportProtocol | string | N | 仅对SIDECAR_INBOUND生效,支持tls和raw_buffer |
applicationProtocols | string | N | 匹配的应用层协议,仅对sidecar生效,支持h2, http/1.1, http/1.0 |
filter | FilterMatch | N | filter匹配条件 |
destinationPort | uint32 | N | 匹配的目标端口 |
EnvoyFilter.ListenerMatch.FilterMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
name | string | N | 匹配过滤器名字 |
subFilter | SubFilterMatch | N | subfilter匹配 |
EnvoyFilter.ListenerMatch.SubFilterMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
name | string | N | 匹配subfilter名字 |
EnvoyFilter.RouteConfigurationMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
portNumber | uint32 | N | 匹配服务的端口号 |
portName | string | N | 进队GATEWAY场景生效,匹配端口名称 |
gateway | string | N | 匹配网关,namespace/gatewayName格式 |
vhost | VirtualHostMatch | N | 匹配虚拟服务 |
name | string | N | 匹配特地路由名称 |
EnvoyFilter.RouteConfigurationMatch.VirtualHostMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
name | string | N | 匹配的虚拟服务名称 |
route | RouteMatch | N | 匹配虚拟服务下特定的路由 |
EnvoyFilter.RouteConfigurationMatch.RouteMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
name | string | N | 匹配路由名称 |
action | Action | N | 匹配路由类型,支持 ANY:所有类型 ROUTE:普通路由 REDIRECT:重定向路由 DIRECT_RESPONSE:mock路由 |
EnvoyFilter.ClusterMatch
字段 | 类型 | 必选 | 说明 |
---|---|---|---|
portNumber | uint32 | N | 匹配服务的端口 |
service | string | N | 匹配服务FQDN名称 |
subset | string | N | 匹配服务分组名 |
name | string | N | 匹配服务cluster名称 |