【问题标题】:envoy filter to intercept upstream response特使过滤器拦截上游响应
【发布时间】:2021-05-01 14:44:37
【问题描述】:

我已经为 envoy 编写了 ext_authz 过滤器,并且对 envoy 过滤器是如何完成的有基本的了解。但现在我想过滤从上游返回的响应。具体来说,我想处理两件事:

  1. 拦截来自上游的data/jsonBody,在envoy发回下游之前根据一些业务规则过滤/修改responseJsonBody。

  2. 如果上游关闭(当 http 响应代码 408-Timeout 时),我想将 post-request 保存到 async-msg-que 并将 202-Accepted 发送回下游。这样,当上游返回时,它将处理来自它的 async-msg-que 的未决后请求。

是否有一个现有的过滤器可以用于这些目的,或者使用 envoy-proxy sidecar 的正确方法是什么。

谢谢。

【问题讨论】:

    标签: istio envoyproxy istio-sidecar


    【解决方案1】:

    你需要自己使用lua编写过滤器:

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: custom-filter
      namespace: some-namespace
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      configPatches:
      - applyTo: HTTP_FILTER
        match:
          context: GATEWAY
          listener:
            filterChain:
              filter:
                name: "envoy.filters.network.http_connection_manager"
                subFilter:
                  name: "envoy.extAuthz" # name of your ext_authz filter
        patch:
          operation: INSERT_AFTER
          value: 
           name: envoy.custom-resp
           typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
              inlineCode: |
                function envoy_on_response(response_handle) 
                  if response_handle:headers():get(":status") == "408" then
                    -- send message depending on your queue, eg via httpCall()
                    -- Overwrite status and body
                    response_handle:headers():replace(":status", "202")
                  else 
                    -- get response body as jsonString
                    local body = response_handle:body()
                    local jsonString = tostring(body:getBytes(0, body:length()))
                    -- do something, eg replace secret by regex 
                    jsonString = jsonString:gsub("(foo|bar)", "")
                    response_handle:body():set(jsonString)
                  end
                end
    

    请注意,您需要以某种方式处理队列超时。

    Envoy With Lua

    httpCall

    Lua Docs

    【讨论】:

    • 谢谢克里斯,我知道如何解决这个问题。在我的案例中,数据过滤逻辑和排队逻辑很大,直接在 lua 中使用它们并不是最优的。但是使用 lua + httpCall(),我可以将繁重的工作外包给另一个用 golang 编写的 sidecar。这种方法应该有效。但是如果可以避免 lua 并直接从 envoy 转到 golang sidecar(如 ext_auth 过滤器),那将是更优化的。我注意到另一个过滤器“envoy.filters.http.ext_proc”看起来非常相似,但文档说它正在进行中。是否有任何替代 lua 方法的方法?。
    • 为什么不尝试使用网络程序集?
    • 我的印象是 envoy+webassembly 即将推出...还没有作为原生过滤器...还是我弄错了?
    • 如果您的业务逻辑如此重要/复杂,我宁愿创建另一个服务来调用您的服务,处理停机时间和响应操作,而不是尝试将该逻辑拉入 istio sidecar/另一个 sidecar .它更容易开发、调试和维护。
    • @ChristophRaab,是的,克里斯,我正计划做类似的事情。在 golang rest-service 中编写复杂的响应操作,并将该服务作为 sidecar 部署在同一个 pod 中,并从上面的 lua 过滤器 on_reponse 函数调用它。我有一个类似的边车,可以直接作为 ext_authz 安装到特使。我正在寻找类似于直接过滤器的东西,而不是通过 lua 进行一轮。从 lua 调用外部服务目前还不错,想知道是否还有其他选择。
    猜你喜欢
    • 2014-06-16
    • 2011-04-24
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 2012-02-15
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多