我正在尝试让 EnvoyFilters 在我的安装中工作。 出于测试目的,我正在尝试设置 lua 过滤器来记录哑消息并将标头添加到响应中。
这是我的配置:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: dumb-filter
namespace: istio-system
spec:
# workloadSelector:
# labels:
# istio: ingressgateway
configPatches:
# - applyTo: VIRTUAL_HOST
- applyTo: HTTP_ROUTE
match:
context: GATEWAY
# context: ANY
routeConfiguration:
vhost:
# name: "<domain>:443"
route:
#TODO: Understand name compose logic
name: https.443.https.geth-dedicated.default
patch:
operation: MERGE
value:
name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_response(response_handle)
response_handle:headers():add("dm3ch-test", "dm3ch")
response_handle:logErr("Bye Bye.")
end
现在我没有看到响应的日志消息或测试标头。 我已经试过了:
istio: ingressgateway
标签)VIRTUAL_HOST
和 HTTP_ROUTE
模式https.443.https.geth-dedicated.default
命令验证路由名称实际上是 istioctl proxy-config route <gateway_pod>
。vhost.name
设置和评论vhost.route.name
Istio 版本信息:
❯ istioctl version
client version: 1.11.4
control plane version: 1.12.0-alpha.1
data plane version: 1.12.0-alpha.1 (1 proxies)
路由配置json:
❯ istioctl proxy-config route istio-ingress-675cb54bc9-5r8cs.istio-system --name https.443.https.geth-dedicated.default -o json
[
{
"name": "https.443.https.geth-dedicated.default",
"virtualHosts": [
{
"name": "<domain>:443",
"domains": [
"<domain>",
"<domain>:*"
],
"routes": [
{
"match": {
"prefix": "/",
"caseSensitive": true
},
"route": {
"cluster": "outbound|8545||geth-dedicated.default.svc.cluster.local",
"timeout": "0s",
"retryPolicy": {
"retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
"numRetries": 2,
"retryHostPredicate": [
{
"name": "envoy.retry_host_predicates.previous_hosts"
}
],
"hostSelectionRetryMaxAttempts": "5",
"retriableStatusCodes": [
503
]
},
"hashPolicy": [
{
"connectionProperties": {
"sourceIp": true
}
}
],
"maxGrpcTimeout": "0s"
},
"metadata": {
"filterMetadata": {
"istio": {
"config": "/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/geth-dedicated"
}
}
},
"decorator": {
"operation": "geth-dedicated.default.svc.cluster.local:8545/*"
}
}
],
"includeRequestAttemptCount": true
}
],
"validateClusters": false
如果有人能咨询我我做错了什么或者我怎样才能更好地调试为什么没有应用过滤器,我会很高兴。
附言我的目标是在 ingressgateway istio 部署的请求/响应处理期间仅针对特定虚拟服务调用自定义逻辑
Chris 的回答非常有用,但不幸的是它不是完整的。 :(
这是我发现的:
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
上使用HTTP_ROUTE
过滤器(但可以使用LuaPerRoute
)type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
本身不允许定义新的 lua 过滤器,它只允许禁用现有的 Lua 过滤器或覆盖它的源代码envoy docs因此,要使 lua 自定义逻辑仅应用于一个 http 路由,您需要定义“全局”
Lua
过滤器并使用 LuaPerRoute
过滤器覆盖它的特定 http 路由代码。
这是我的清单,使我能够让它发挥作用:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: geth-dedicated
namespace: default
spec:
gateways:
- geth-dedicated # I'm ommiting gateway creation in this snippet
hosts:
- <domain>
http:
- match:
- uri:
prefix: /
name: geth-public
route:
- destination:
host: geth-dedicated
port:
number: 8545
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: dumb-filter
namespace: istio-system # Namespace where istio gateway pods are actually running
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
# Patch that creates "global" lua filter that does nothing useful
- applyTo: HTTP_FILTER
match:
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
-- Empty lua function
end
# Filter for http route that overrides "global" filter lua source code
- applyTo: HTTP_ROUTE
match:
context: GATEWAY
routeConfiguration:
vhost:
route:
name: geth-public # Corresponds to http[0].name in VirtualService
patch:
operation: MERGE
value:
name: envoy.lua
typed_per_filter_config:
envoy.filters.http.lua:
'@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
source_code:
inline_string: |
function envoy_on_response(response_handle)
response_handle:logErr("Goodbye my brain.")
response_handle:headers():add("dm3ch-test", "dm3ch wins")
end
问题是你的待办事项
#TODO: Understand name compose logic
。您需要将此名称值设置为VirtualService
的路由名称。您还需要使用类型为typed_per_filter_config
.的
LuaPerRoute
如果你的
VirtualService
看起来像这样:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http:
- name: "reviews-v2-routes"
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v2
- name: "reviews-v1-route"
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
比你的
EnvoyFilter
需要这样设置:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: dumb-filter
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: HTTP_ROUTE
match:
routeConfiguration:
vhost:
route:
# name from virtual service route that the filter should apply to
name: reviews-v1-route
patch:
operation: MERGE
value:
# 'custom' as prefix, can be anything
name: custom.dumb-filter
# set lua per route filter
typed_per_filter_config:
envoy.filters.http.lua:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
source_code:
inline_string: |
function envoy_on_response(response_handle)
response_handle:headers():add("dm3ch-test", "dm3ch")
response_handle:logErr("Bye Bye.")
end
注:
这需要一个已经应用的 lua 过滤器,因为
LuaPerRoute
只会覆盖现有的过滤器。