Расширение Envoy Proxy — фильтра WASM с помощью Golang

Envoy — это сервисный прокси с открытым исходным кодом, специально разработанный для облачных приложений. Он обладает широким набором функций, таких как пул соединений, механизм повторных попыток, управление TLS, сжатие, проверка работоспособности, устранение ошибок, ограничение скорости, авторизация и т.д.. Они достигаются с помощью встроенных http-фильтров. И сегодня я расскажу о специальном фильтре, который называется WASM Filter.

Эта статья не предназначена для объяснения того, что такое WASM, поэтому я пропущу объяснение WASM и добавлю ресурсы для этого в конце статьи.


Почему мы используем WASM-фильтр

В Trendyol Tech. Мы используем Istio в качестве сетки сервисов. В обязанности нашей команды (DevX) входит улучшение опыта разработчиков путем разработки приложений, отвечающих общим требованиям микросервисов, таким как кэширование, авторизация, ограничение скорости, межкластерное обнаружение сервисов и т. д.

Поскольку мы уже используем Istio, почему бы не воспользоваться преимуществами расширяемости Envoy Proxy.

Наш сценарий использования — получение JWT-токена для микросервиса, который идентифицирует приложение микросервиса. Когда мы хотим избежать того, чтобы каждая команда писала один и тот же код на разных языках, мы можем создать WASM Filter и внедрить его в Envoy Proxy.

Преимущества фильтров WASM:

  • Позволяют писать код на любом языке, который поддерживает WASM.
  • Динамическая загрузка кода в Envoy
  • Код WASM изолирован от Envoy, поэтому сбои в WASM не влияют на Envoy.

В Envoy Proxy есть рабочие потоки, которые обрабатывают входящие запросы. Каждый рабочий поток имеет свою собственную виртуальную машину WASM. Поэтому если вы пишете операционный код, основанный на времени, он работает отдельно для каждого потока.

В Envoy Proxy каждый рабочий поток изолирован друг от друга и имеет одну или несколько WASM VM. Существует также концепция под названием WASM Service для межпотоковых коммуникаций и обмена данными (мы не будем ее рассматривать).


Написание WASM в Go

Мы будем использовать tetratelabs/proxy-wasm-go-sdk для написания WASM в Go. Нам также понадобится TinyGo, чтобы собрать наш Go-код как WASM.

Наш сценарий использования очень прост, поэтому мы напишем код, который отправляет запрос на JWT Api каждые 15 секунд. Он извлекает заголовок авторизации, устанавливает его значение в глобальную переменную и помещает это значение в заголовок ответа каждого входящего запроса. Мы также устанавливаем значение «hello from wasm» в другой заголовок под названием «x-wasm-filter».

В функции OnTick мы выполняем http-вызов к службе, известной в Envoy как кластер.

Давайте соберем наш go-код как WASM:

tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь нам нужно настроить Envoy Proxy на использование WASM Filter для входящих запросов. Мы определим правило маршрутизации и WASM-фильтр для нашего WASM-кода, а также определим кластер, который представляет наш сервис.

Я поместил все файлы в одну директорию. Теперь давайте запустим Envoy Proxy в Docker:

docker run -it — rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0
Войти в полноэкранный режим Выход из полноэкранного режима

Как мы видим из логов, наш WASM-фильтр начал работать и отправлять запрос на JWT Api каждые 15 секунд.

Теперь давайте отправим запрос на Envoy Proxy. Мы настроим Envoy на прослушивание входящих запросов с 1000 порта и запустим наш контейнер с отображением портов. Таким образом, мы можем отправить запрос на localhost:10000:

В заголовках ответа мы видим значения «x-wasm-filter: hello from wasm» и «x-auth».


Спасибо, что дочитали до этого момента. Надеюсь, это даст вам представление о том, как и зачем использовать WASM в Envoy Proxy.

Полный пример вы можете посмотреть на github:

mstrYoda / envoy-proxy-wasm-filter-golang

Фильтр WASM для Envoy Proxy, написанный на языке Golang

envoy-proxy-wasm-filter-golang

WASM-фильтр для Envoy Proxy, написанный на языке Golang

Сборка

tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go

Запуск Envoy Proxy в Docker с помощью WASM-фильтра

docker run -it --rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0

Посмотреть на GitHub

Ресурсы

webassembly.org

WebAssembly | MDN

WebAssembly — это новый тип кода, который может быть запущен в современных веб-браузерах. Это низкоуровневый ассемблероподобный язык с компактным двоичным форматом, который работает с производительностью, близкой к нативной, и предоставляет таким языкам, как C/C++, C# и Rust, возможность компиляции, чтобы они могли работать в Интернете. Он также разработан для работы вместе с JavaScript, позволяя обоим работать вместе.

developer.mozilla.org

Модули Wasm и расширяемость Envoy, часть 1 — Новый стек

Если вы когда-либо задавались вопросом, что такое WebAssembly (Wasm) и как он вписывается в экосистему сервисной сетки, то вам стоит прочитать именно эту статью.

thenewstack.io

tetratelabs / proxy-wasm-go-sdk

WebAssembly для прокси (Go SDK)

Этот проект находится на ранней стадии, и API, скорее всего, будет меняться и не будет стабильным.

WebAssembly для прокси (Go SDK)

Go SDK дляProxy-Wasm, позволяющий разработчикам писать плагины Proxy-Wasm в GoЭтот SDK работает на TinyGo и не поддерживает официальный компилятор Go.

Начало работы

  • каталог examples содержит коды примеров поверх этого SDK.
  • OVERVIEW.md обзор Proxy-Wasm, API этого SDK, и вещи, которые вы должны знать при написании плагинов.

Требования

  • Go 1.17 или выше.
  • TinyGo — Этот SDK зависит от TinyGo и использует его WASI (WebAssembly System Interface) цель. Пожалуйста, следуйте официальной инструкции здесь для установки TinyGo.
  • Envoy — Для запуска скомпилированных примеров вам необходимо иметь бинарный файл Envoy. Мы рекомендуем использовать func-e как самый простой способ начать работу с Envoy. Также вы можете следовать официальной инструкции.

Установка

go get не может быть использован…

Посмотреть на GitHub

Вы можете следить за мной на:
Twitter
Linkedin
Github

Оцените статью
devanswers.ru
Добавить комментарий