Envoy и Apache APISIX: Другой способ реализации Envoy Filter
API7.ai
December 16, 2020
Способы реализации фильтра Envoy
Фильтр Envoy
Envoy — это L7-прокси и коммуникационная шина, разработанная для крупных современных сервисно-ориентированных архитектур. Механизм цепочки подключаемых фильтров позволяет писать фильтры для выполнения различных задач и вставлять их в основной сервер.

Методы расширения
Существующие фильтры могут не соответствовать пользовательским требованиям. В этом случае Envoy необходимо расширить. Создайте новые фильтры на основе существующей цепочки фильтров для удовлетворения пользовательских требований.
Разработчики могут расширять Envoy тремя способами:
| Сложность начального освоения | Стабильность | Эффективность разработки | Развертывание и компиляция | |
|---|---|---|---|---|
| C++ | высокая | стабильная | низкая | долгое время компиляции |
| Lua | низкая | стабильная | высокая | не требует компиляции, развертывание напрямую |
| WASM | средняя-высокая | неопределенная | зависит от языка | время компиляции зависит от языка |
- Расширение с использованием C++
В этом способе код на C++ пишется непосредственно на основе Envoy для улучшения функциональности. После реализации пользовательского фильтра новый бинарный файл перекомпилируется для завершения обновления. У этого способа есть две проблемы:
- Ограничения языка C++, сложность начального освоения, недостаток разработчиков.
- Увеличение сложности развертывания, эксплуатации и обновлений. Envoy становится все тяжелее, и каждое изменение требует перекомпиляции бинарного файла, что не способствует итерациям и управлению.
- Расширение с использованием Lua
Lua изначально предназначен для встраивания в приложения, чтобы предоставлять гибкие возможности расширения и настройки, и широко используется.
Фильтр Lua позволяет запускать скрипты Lua в процессе запроса и ответа. Основные поддерживаемые функции включают: проверку заголовков, тела и трейлеров во время потоковой передачи в процессе запроса или ответа; изменение заголовков и трейлеров; блокировку и буферизацию всего тела запроса/ответа для проверки; выполнение асинхронного HTTP-вызова к вышестоящему хосту; выполнение прямого ответа и пропуск дальнейшей итерации фильтра и т.д.
В настоящее время многие люди напрямую распространяют код Lua в конфигурации, что не способствует организации и управлению кодом, а также затрудняет его совместное использование с другими для формирования экосистемы.
- Расширение с использованием WASM
Разработчики могут писать фильтры на своем языке программирования, компилировать их в формат WASM с помощью инструментов и встраивать в Envoy для выполнения.
В настоящее время поддерживается мало языков, и использование этих языков для расширения все еще не так просто. С другой стороны, многие люди все еще сомневаются в WASM и могут не использовать его напрямую.
Решение Apache APISIX
На основе вышеизложенного анализа можно увидеть, что Lua очень подходит для расширения Envoy, его легко изучить, а эффективность разработки чрезвычайно высока. Поскольку он встроен в Envoy, нет дополнительных сетевых накладных расходов, и производительность хорошая.
Сообщество Apache APISIX предлагает свое решение на основе Lua, которое заключается в предоставлении мощной и гибкой базовой библиотеки для реализации всех плагинов Apache APISIX и плагинов, которые будут разработаны в будущем, для работы на Envoy. Разработчики также могут разрабатывать свои собственные пользовательские плагины на основе этой базовой библиотеки.
Apache APISIX — это динамический, реального времени, высокопроизводительный API-шлюз, основанный на библиотеке Nginx и Lua. Apache APISIX предоставляет богатые функции управления трафиком, такие как балансировка нагрузки, динамический вышестоящий сервер, канареечное развертывание, прерывание цепи, аутентификация, наблюдаемость и многое другое.
Пример
Пожалуйста, ознакомьтесь с репозиторием для получения конкретного кода и инструкций по запуску: https://github.com/api7/envoy-apisix.
Соответствующая конфигурация Envoy выглядит следующим образом:
Определение фильтра:
http_filters: - name: entry.lua typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua source_codes: entry.lua: filename: /apisix/entry.lua
Включение фильтра для маршрута и его настройка с помощью метаданных:
routes: - match: prefix: "/foo" route: cluster: web_service typed_per_filter_config: envoy.filters.http.lua: "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute name: entry.lua metadata: filter_metadata: envoy.filters.http.lua: plugins: - name: uri-blocker conf: rejected_code: 403 block_rules: - root.exe - root.m+
Как это работает
Нам не нужно вносить серьезные изменения в Envoy, только некоторые оптимизации, подходящие для общих потребностей.
Мы скрываем различия платформ для уровня плагинов. Все интерфейсы, которые необходимо использовать, абстрагированы в базовой структуре, которую мы называем apisix.core, чтобы все плагины могли работать как на Envoy, так и на Apache APISIX одновременно.

Мы используем предыдущий пример, чтобы показать, как работает плагин:

Первый шаг, чтение конфигурации
Мы настраиваем через метаданные, чтобы определить, какие плагины должны работать на каждом маршруте и какая конфигурация для каждого плагина. В примере мы настроили плагин uri-blocker для маршрута с префиксом /foo, а также правило блокировки плагина и статус ответа при необходимости блокировки.
Второй шаг, разбор запроса
Мы инкапсулировали данные клиентского запроса в ctx, чтобы их можно было использовать напрямую во всем процессе.
Третий шаг, запуск плагина
Мы определяем, нужно ли блокировать этот запрос, сопоставляя настроенные правила и полученный uri. Если блокировка необходима, мы вызываем respond для прямого ответа, в противном случае пропускаем запрос.
Перспективы на будущее
Все больше плагинов APISIX становятся доступными для работы на Envoy, и в конечном итоге все плагины APISIX (даже те, которые будут разработаны в будущем) будут доступны для работы на Envoy.
В то же время мы надеемся, что сможем сотрудничать с сообществом Envoy в направлении Lua Filter, оптимизировать и улучшать Lua Filter, расширять возможности Envoy и снижать сложность расширения Envoy.