概述
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名稱 |