EnvoyFilter
EnvoyFilter
提供了一种机制,来自定义 Istio Pilot 生成的 Envoy 配置。使用 EnvoyFilter
可以 修改某些字段的值,添加特定的过滤器,甚至添加全新的监听器、集群等。必须谨慎使用此功能,因为不正确的配置可能会破坏整个网格的稳定性。与其他 Istio 网络对象不同,EnvoyFilters
是附加应用的。对于特定命名空间中的给定工作负载,可以有任意数量的 EnvoyFilters
。这些 EnvoyFilters
的应用顺序如下:配置根命名空间中的所有 EnvoyFilters
,然后是工作负载命名空间中的所有匹配的 EnvoyFilters
。
注意1:由于这是“碎玻璃”配置,不同 Istio 版本之间不会有任何向后兼容性。即 此配置会根据 Istio 网络子系统的内部实现而发生变化。
注意2:在 Istio 代理版本升级中,应仔细检查通过此机制提供的 Envoy 配置,以确保废弃字段被删除并合适地替换。
注意3:当多个 EnvoyFilters
绑定到给定命名空间中的同一个工作负载时,将按创建时间的顺序顺序处理所有补丁。如果多个 EnvoyFilters
配置相互冲突,则该行为是不确定的。
注释4:*_To
将 EnvoyFilter
资源应用于系统中的所有工作负载(sidecars
和 gateways
),在配置根命名空间中定义资源,而不需要工作负载选择器。
下面的示例中,在名为 istio-config
的根命名空间中声明了一个全局默认的 EnvoyFilter
资源,该资源在系统中的所有 sidecars
上添加了自定义协议过滤器,以使出站端口 9307 生效。应该在终止 tcp_proxy
过滤器生效之前添加该过滤器。此外,它为 sidecars
和 gateways
中的所有 HTTP 连接设置了 30s 的空闲超时。
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.tcp_proxy"
patch:
operation: INSERT_BEFORE
value:
name: "envoy.config.filter.network.custom_protocol"
config:
...
- 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.http_connection_manager"
patch:
operation: MERGE
value:
typed_config:
"@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
idle_timeout: 30s
下面的示例中,为 bookinfo
命名空间中到达带有标签为 app: reviews
的 reviews
服务 Pod
的服务端口 8080 的所有入站 HTTP 调用启用 Envoy 的 Lua 筛选器。Lua 过滤器调出到外部服务 internal.org.net:8888
,该服务在 Envoy 中需要特殊的集群定义,集群也作为此配置的一部分添加到 sidecar
中。
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.http_connection_manager"
subFilter:
name: "envoy.router"
patch:
operation: INSERT_BEFORE
value: # lua filter specification
name: envoy.lua
config:
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
hosts:
- socket_address:
protocol: TCP
address: "internal.org.net"
port_value: 8888
下面的示例中,覆盖了 HTTP 连接管理器中的某些字段(HTTP 空闲超时和 X-Forward-For
受信任的跃点),这些字段位于 SNI 主机 app.example.com
的 istio-system
命名空间的入口网关上的监听器中。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: hcm-tweaks
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingress-gateway
configPatches:
- applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
match:
context: GATEWAY
listener:
filterChain:
sni: app.example.com
filter:
name: "envoy.http_connection_manager"
patch:
operation: MERGE
value:
idle_timeout: 30s
xff_num_trusted_hops: 5
EnvoyFilter
EnvoyFilter
提供了一种机制,自定义 Istio Pilot 生成的 Envoy 配置。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
workloadSelector |
WorkloadSelector |
用于选择在其上应用此补丁配置的指定 Pods/VMs 组的条件。如果省略,EnvoyFilter 补丁将应用于同一命名空间中的所有工作负载。如果在配置根名称空间中存在 EnvoyFilter ,它将被应用于任何命名空间中的所有工作负载 |
否 |
configPatches |
EnvoyConfigObjectPatch[] |
具有匹配条件的一个或多个补丁 | 是 |
EnvoyFilter.ApplyTo
ApplyTo
指定在 Envoy
配置中的哪个位置应用给定的补丁。
名称 | 描述 |
---|---|
INVALID |
占位符 |
LISTENER |
将补丁应用到监听器 |
FILTER_CHAIN |
将补丁应用到过滤器链上 |
NETWORK_FILTER |
将补丁应用到网络过滤器链,可以修改现有的过滤器或添加新的过滤器 |
HTTP_FILTER |
将补丁应用于 HTTP 连接管理器中的 HTTP 过滤器链,以修改现有的过滤器或添加新的过滤器 |
ROUTE_CONFIGURATION |
将补丁应用于 HTTP 连接管理器中的 Route 配置(rds 输出)。这不适用于虚拟主机。当前,仅允许对路由配置对象进行 MERGE 操作 |
VIRTUAL_HOST |
将补丁应用到路由配置中的虚拟主机 |
HTTP_ROUTE |
在路由配置中将补丁应用于匹配的虚拟主机内部的路由对象上。当前,仅允许对路由对象进行 MERGE 操作 |
CLUSTER |
在 CDS 输出中将补丁应用于集群。也用于添加新的集群 |
EnvoyFilter.ClusterMatch
必须满足在 ClusterMatch
中指定的条件,该补丁才能应用于集群。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
portNumber |
uint32 |
为其生成集群的服务端口。如果省略,则应用于任何端口的集群 | 否 |
service |
string |
此集群的完全限定服务名。如果省略,则应用于任何服务的集群。对于通过 ServiceEntry 定义的服务,服务名称与在 ServiceEntry 中定义的主机相同 |
否 |
subset |
string |
与服务关联的子集。如果省略,则应用于服务的任何子集的集群 | 否 |
name |
string |
要匹配的集群的精确名称。要通过名称匹配特定的集群,例如内部生成的 Passthrough 集群,请将 ClusterMatch 中除 name 之外的所有字段保留为空 |
否 |
EnvoyFilter.DeprecatedListenerMatch.ListenerProtocol
名称 | 描述 |
---|---|
ALL |
所有协议 |
HTTP |
HTTP /HTTPS /HTTPS /gRPC |
TCP |
任何非 HTTP 监听器 |
EnvoyFilter.DeprecatedListenerMatch.ListenerType
名称 | 描述 |
---|---|
ALL |
所有监听器 |
SIDECAR_INBOUND |
sidecar 中的入站监听器 |
SIDECAR_OUTBOUND |
sidecar 中的出站监听器 |
GATEWAY |
网关监听器 |
EnvoyFilter.EnvoyConfigObjectMatch
在将补丁应用到为给定代理生成的配置之前,需要满足一个或多个匹配条件。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
context |
PatchContext |
匹配的特定配置生成的上下文。Istio Pilot 会在 Gateway 、到 sidecar 的入站流量和 sidecar 的出站流量的上下文中生成 Envoy 配置 |
否 |
proxy |
ProxyMatch |
匹配与代理关联的属性 | 否 |
listener |
ListenerMatch (oneof) |
匹配 Envoy 监听器属性 | 是 |
routeConfiguration |
RouteConfigurationMatch (oneof) |
匹配 Envoy HTTP 路由配置属性 | 是 |
cluster |
ClusterMatch (oneof) |
匹配 Envoy 集群属性 | 是 |
EnvoyFilter.EnvoyConfigObjectPatch
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
applyTo |
ApplyTo |
指定应在 Envoy 配置中的何处应用补丁。匹配将根据 applyTo 选择合适的对象。例如,带有 HTTPFILTER 的 applyTo 在监听器上具有一个匹配条件,在 envoy.http connection_manager 上具有一个网络过滤器选择,在应该执行插入的 HTTP 过滤器上具有一个子过滤器选择。同样,CLUSTER 上的 applyTo 应该在集群上而不是在监听器上具有匹配项(如果提供) |
否 |
match |
EnvoyConfigObjectMatch |
匹配 监听器或路由 的 配置或集群 | 否 |
patch |
Patch |
与操作一起应用的补丁 | 否 |
EnvoyFilter.Filter.FilterType
名称 | 描述 |
---|---|
INVALID |
占位符 |
HTTP |
HTTP 过滤器 |
NETWORK |
网络过滤器 |
EnvoyFilter.InsertPosition.Index
在过滤器链中的索引或位置。
名称 | 描述 |
---|---|
FIRST |
首位插入 |
LAST |
尾部插入 |
BEFORE |
在给定过滤器之前插入 |
AFTER |
在给定过滤器之后插入 |
EnvoyFilter.ListenerMatch
要将补丁应用到跨所有过滤链的指定监听器上,或者应用到监听器内部的指定过滤链上,必须满足监听器匹配中指定的条件。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
portNumber |
uint32 |
向其发送或接收流量的服务端口或网关端口。如果未指定,则匹配所有监听器。即使为实例端口或 Pod 端口生成了入站监听器,也应该只使用服务端口来匹配监听器 |
否 |
filterChain |
FilterChainMatch |
匹配监听器中的指定过滤器链。如果指定了,则补丁将应用于过滤器链(以及指定的过滤器,如果指定了),而不是应用于监听器中的其他过滤器链 | 否 |
name |
string |
通过名称匹配指定的监听器。Pilot 生成的监听器通常命名为 IP:Port |
否 |
EnvoyFilter.ListenerMatch.FilterChainMatch
对于有多个过滤器链的监听器(如 带有许可的 mTLS 的 sidecars
上的入站监听器,有多个 SNI 匹配的网关监听器),可以使用过滤器链匹配来选择要打补丁的指定过滤器链。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
name |
string |
过滤器链的名称 | 否 |
sni |
string |
过滤器链的匹配条件使用的 SNI 值。如果过滤器链没有 SNI 匹配,则此条件的值为 false | 否 |
transportProtocol |
string |
仅适用于 SIDECAR INBOUND 上下文。如果非空,则在决定过滤器链匹配时要考虑传输协议。当 tls inspector 监听器过滤器检测到该值时,会将其与新连接的传输协议进行比较。可接受的值包括:raw_buffer - 默认值,当没有检测到传输协议时使用;tls - 当 tls inspector 检测到 tls 协议时设置 |
否 |
applicationProtocols |
string |
仅适用于 sidecars 。如果非空,则在决定过滤器链匹配时要考虑一组逗号分隔的应用程序协议。当某个监听器过滤器(如 http_inspector )检测到该值时,会将其与新连接的应用程序协议进行比较。接受的值包括:h2 /http/1.1 /http/1.0 |
否 |
filter |
FilterMatch |
要应用补丁的指定过滤器的名称。将其设置为 envoy.httpconnectionmanager ,以添加过滤器或将补丁应用于 HTTP 连接管理器 |
否 |
EnvoyFilter.ListenerMatch.FilterMatch
匹配过滤器链中的特定过滤器的条件。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
name |
string |
要匹配的过滤器的名称 | 否 |
subFilter |
SubFilterMatch |
过滤器中要匹配的下一级过滤器。通常用于 HTTP 连接管理器过滤器和 Thrift 过滤器 | 否 |
EnvoyFilter.ListenerMatch.SubFilterMatch
匹配另一个过滤器中的特定过滤器的条件。此字段通常用于匹配 envoy.httpconnectionmanager
网络过滤器内的 HTTP 过滤器。也适用于 Thrift 过滤器。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
name |
string |
要匹配的过滤器的名称 | 否 |
EnvoyFilter.Patch
指定如何给选中的对象打补丁。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
operation |
Operation |
指定如何应用补丁 | 否 |
value |
Struct |
补丁对象的 json 配置。这将使用 json 合并语义与路径中现有的 proto 进行合并 | 否 |
EnvoyFilter.Patch.Operation
Operation
指定如何应用补丁到选定的配置。
名称 | 描述 |
---|---|
MERGE |
使用 json 合并语义将提供的配置与生成的配置合并 |
ADD |
将提供的配置添加到现有列表(监听器,集群,虚拟主机,网络过滤器 或 HTTP 过滤器)。当 applyTo 设置为 ROUTECONFIGURATION 或 HTTPROUTE 时,将忽略此操作 |
REMOVE |
从列表中删除选定的对象(监听器,集群,虚拟主机,网络过滤器 或 HTTP 过滤器)。不需要指定值。当 applyTo 设置为 ROUTECONFIGURATION 或 HTTPROUTE 时,将忽略此操作 |
INSERT_BEFORE |
在给定对象数组上执行插入操作。此操作仅在过滤器的上下文中才有用,因为过滤器的顺序很重要。对于集群和虚拟主机,数组中元素的顺序无关紧要。在选定的过滤器或子过滤器之前插入。如果没有选择任何过滤器,指定的过滤器将被插入到列表的开头 |
INSERT_AFTER |
在给定对象数组上执行插入操作。此操作仅在过滤器的上下文中才有用,因为过滤器的顺序很重要。对于集群和虚拟主机,数组中元素的顺序无关紧要。在选定的过滤器或子过滤器之后插入。如果没有选择任何过滤器,指定的过滤器将被插入到列表的末尾 |
EnvoyFilter.PatchContext
PatchContext
将根据流量流向和工作负载选择一类配置。
名称 | 描述 |
---|---|
ANY |
sidecars 和 gateways 中的所有监听器、路由、集群 |
SIDECAR_INBOUND |
sidecars 中入站的监听器、路由、集群 |
SIDECAR_OUTBOUND |
sidecars 中出站的监听器、路由、集群 |
GATEWAY |
gateways 监听器、路由、集群 |
EnvoyFilter.ProxyMatch
要匹配的代理的一个或多个属性。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
proxyVersion |
string |
golang regex 格式(RE2)的正则表达式,可以使用 Istio 代理的特定版本来选择代理。给定代理的 Istio 版本是在连接到 Pilot 时从代理提供的节点元数据字段 ISTIOVERSION 中获得的。此值作为环境变量 ISTIOMETAISTIOVERSION 嵌入在 Istio 代理的 docker 镜像中。自定义代理实现应该提供这个元数据变量,以利用 Istio 版本检查选项 |
否 |
metadata |
map<string, string> |
当连接到 Istio Pilot 时,匹配代理提供的节点元数据。注意,虽然 Envoy 的节点元数据的类型为 Struct ,但 Pilot 只处理字符串的键值对。元数据中指定的所有键都必须与精确值匹配。如果指定的任何键不存在或值不匹配,则匹配将失败 |
否 |
EnvoyFilter.RouteConfigurationMatch
当补丁应用到路由配置对象或路由配置中的指定虚拟主机时,必须满足 RouteConfigurationMatch
中指定的条件。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
portNumber |
uint32 |
生成此路由配置的服务端口号或网关服务器端口号。如果省略,则适用于所有端口的路由配置 | 否 |
portName |
string |
仅适用于 Gateway 上下文。生成此路由配置的网关服务器端口名称 |
否 |
gateway |
string |
生成此路由配置的 Istio 网关配置的 namespace/name 。仅在上下文为 Gateway 时适用,应该采用 namespace/name 格式。将此字段与 portNumber 和 portName 结合使用,可以为网关配置对象内的特定 HTTPS 服务器准确选择 Envoy 路由配置 |
否 |
vhost |
VirtualHostMatch |
在路由配置中匹配指定的虚拟主机,然后将补丁应用到该虚拟主机 | 否 |
name |
string |
用于匹配的路由配置名称,可用于按此名称匹配特定的路由配置。例如,为所有 sidecars 内部生成的 http_proxy 路由配置 |
否 |
EnvoyFilter.RouteConfigurationMatch.RouteMatch
在路由配置中匹配虚拟主机中的特定路由。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
name |
string |
默认情况下生成的路由对象命名为 default 。使用 VirtualService 生成的路由对象将携带 VirtualService 的 HTTP 路由中使用的名称 |
否 |
action |
Action |
将路由与特定操作类型匹配 | 否 |
EnvoyFilter.RouteConfigurationMatch.RouteMatch.Action
Action
是指 Envoy 在匹配 HTTP 路由时对路由采取的操作。
名称 | 描述 |
---|---|
ANY |
所有三个路由操作 |
ROUTE |
将流量路由到 cluster/weighted 集群 |
REDIRECT |
重定向请求 |
DIRECT_RESPONSE |
直接响应具有特定有效负载的请求 |
EnvoyFilter.RouteConfigurationMatch.VirtualHostMatch
在路由配置中匹配特定的虚拟主机。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
name |
string |
由 Istio 生成的虚拟主机对象被命名为 host:port ,其中主机通常对应 VirtualService 的 host 字段或注册表中某个服务的主机名 |
否 |
route |
RouteMatch |
匹配虚拟主机中的特定路由 | 否 |