#istio #envoyproxy
Вопрос:
Я пытаюсь заставить 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
На данный момент я не вижу сообщения журнала или заголовка теста в ответе.
Я уже пробовал:
- создайте объект EnvoyFilter как в приложении, так и в пространстве имен istio-system (где находятся модули шлюза istio)
- указание workloadSelector (я проверил, что модуль шлюза istio имеет
istio: ingressgateway
метку) - изменение контекста с «GATEWAY» на «ANY»
- изменение applyTo на
VIRTUAL_HOST
иHTTP_ROUTE
режимы - проверено, что имя маршрута на самом деле
https.443.https.geth-dedicated.default
используетistioctl proxy-config route <gateway_pod>
command. - добавление
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
Я был бы рад, если бы кто-нибудь мог посоветоваться со мной, что я делаю не так или как я могу лучше отладить, почему фильтр не применяется.
PS Моя цель — вызвать пользовательскую логику во время обработки запросов / ответов при развертывании ingressgateway istio только для конкретного виртуального сервиса
Ответ №1:
Ответ Криса был очень полезен, но, к сожалению, он не был неполным. 🙁
Вот что я нашел:
- Невозможно использовать
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
filter onHTTP_ROUTE
(но можно использовать LuaPerRoute) type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
сам по себе не позволяет определять новый фильтр lua, он позволяет только отключить существующий фильтр Lua или переопределить его исходный код envoy docs
Итак, чтобы создать пользовательскую логику lua, которая применяется только к одному http-маршруту, вам нужно определить «глобальный» Lua
фильтр и переопределить его код для определенного http-маршрута с помощью LuaPerRoute
filter.
Вот мои манифесты, которые позволили мне заставить его работать:
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
Комментарии:
1. Хорошая работа! На самом деле я никогда не использовал
LuaPerRoute
без «глобального» фильтра lua, поэтому я не знал, что это требуется. Если мой ответ был полезен, пожалуйста, рассмотрите возможность голосования. TY!2. Крис, да, я только что поддержал ваш ответ
Ответ №2:
Проблема в вашей задаче #TODO: Understand name compose logic
. Вам нужно установить это значение name в имя маршрута VirtualService
. Также вам нужно использовать a 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
что он будет перезаписывать только существующий.
Комментарии:
1. В поисках ответа попробовал следующее, все еще безуспешно — pastebin.com/78nRpPzs
2. На самом деле я обнаружил, что это отображается в выводе маршрута proxy-config, но все равно никакого эффекта. Вот результат после некоторых экспериментов: pastebin.com/tfAjh1j0 Уже пробовал то же самое, но с фильтром LuaPerRoute, тоже безрезультатно
3. ТАЙ, я наконец-то нашел то, чего мне не хватало