Skip to content

proposal: Enhance Envoy's Lua filter #13307

@nic-chen

Description

@nic-chen

Background

Envoy is a great open source project. Developers can use c++, WASM and Lua to implement plugins.

I come from the Apache APISIX community and am a PMC member of APISIX. Apache APISIX is an API gateway based on Nginx and Lua. We are very willing to join the Envoy community to participate in the development of Envoy Lua to make Envoy even more powerful.

Goals

Apache APISIX plugins run directly in Envoy Lua filter without modify Envoy

Design

We don't need to modify Envoy, just some optimizations, which we believe have been taken into account by the Envoy community based on what is in the Lua filter documentation (https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter#overview True global support may be added via an API in the future. ).

We mask platform differences at the plugin layer, and all interfaces that need to be used are abstracted in the underlying framework, which we call apisix.core, so that all plugins can run both on Envoy and Apache APISIX.

The specific architecture is as follows:

image

image

Plan

We can do this in four steps.

  1. Simulate APISIX.core for Envoy and run a simple plugin. Apisix has a redirect plugin, which can redirect client request URI. We have implemented it to run on Envoy without modifying the code of redirect. We could run it as follows:

    git clone https://github.com/api7/envoy-apisix.git
    cd envoy/compose
    docker-compose up -d

    And test it by:

    curl 127.0.0.1:8000/ -i
    
    HTTP/1.1 302 Found
    location: /redirected/path
    server: envoy
    content-length: 4
    date: Tue, 29 Sep 2020 09:25:24 GMT

    We could see it had redirect to the specified path with status 302.

  2. The Lua script can read the plugin configuration written in envoy.yaml. We think reading plugin configuration from metadata should be a feasible solution(to be determined).

  3. The Lua filter of Envoy supports context throughout its lifecycle so that envoy_on_request and envoy_on_response can work well together and synchronize data. For example:

    function envoy_on_request(request_handle, context)
        -- Do something.
    end
    -- Called on the response path.
    function envoy_on_response(response_handle, context)
        -- Do something.
    end

    The context in envoy_on_request and envoy_on_response are the same table object.

  4. When Envoy initializes the Luajit VM, it can load and execute the specified Lua script for initializing Lua global variables and so on.

In 3 and 4, the parts of Envoy that need to be changed, it would be great if the Envoy community could help with this so we can do it simultaneously.

Follow-up optimizations

  • The Lua filter of Envoy supports context (currently implemented using global variables).

  • When initialize the Luajit VM, it can load and execute the specified Lua script to initialize Lua global variables and so on.

Example

filter

name: envoy.filters.http.lua.redirect
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
  source_codes:
    apisix_init.lua:
      filename: /apisix/init.lua

config

metadata:
  filter_metadata:
    envoy.filters.http.lua.redirect:
      plugins: 
      - name: redirect
        conf:
          ret_code: 302
          uri: /redirected/path

Envoy community, what do you think of the proposal?
Hope to hear your feedback, thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/luastalestalebot believes this issue/PR has not been touched recently

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions