无法使基于 lua 的 EnvoyFilter 工作

问题描述 投票:0回答:2

我正在尝试让 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-system 命名空间(istio 网关 pod 所在的位置)中创建 EnvoyFilter 对象
  • 指定 workloadSelector(我已经验证了 istio gateway pod 有
    istio: ingressgateway
    标签)
  • 将上下文从“GATEWAY”更改为“ANY”
  • 将 applyTo 更改为
    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 部署的请求/响应处理期间仅针对特定虚拟服务调用自定义逻辑

istio envoyproxy
2个回答
5
投票

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

2
投票

问题是你的待办事项

#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
只会覆盖现有的过滤器。

© www.soinside.com 2019 - 2024. All rights reserved.