Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Архитектура плагинов
plugins_architecture

Архитектура плагинов

Система плагинов Kong: встроенные и кастомные плагины, жизненный цикл запроса

Архитектура плагинов Kong

Плагины — это расширяемая система Kong, которая позволяет добавлять кросс-сервисные функции (аутентификация, логирование, rate limiting) на разных этапах обработки запроса.

#1. Жизненный цикл запроса

Проблема: Нужно понимать, когда и какие плагины выполняются, чтобы правильно реализовать кастомную логику.

Решение: Kong выполняет плагины на определённых этапах жизненного цикла запроса.

┌─────────────────────────────────────────────────────────────┐
│                     Жизненный цикл запроса                   │
└─────────────────────────────────────────────────────────────┘

1. DNS Resolution
   └─ Выбор upstream, разрешение имён
   
2. Rewrite
   └─ Преобразование URL, SSL handshake
   
3. Access  ←─── Большинство плагинов (аутентификация, rate limiting)
   └─ Проверка credentials, принятие решений
   
4. Proxy
   └─ Отправка запроса на upstream
   
5. Response
   └─ Получение ответа от upstream
   
6. Body Filter
   └─ Трансформация тела ответа (чанки)
   
7. Header Filter
   └─ Трансформация заголовков ответа
   
8. Log  ←─── Асинхронное логирование, метрики
   └─ После отправки ответа клиенту

#1.1. Этапы и их назначение

ЭтапНазначениеПримеры плагинов
dnsРазрешение имён upstreamВнутренние механизмы Kong
rewriteПреобразование URL, SSLssl-handshake
accessАутентификация, авторизация, rate limitingkey-auth, jwt, rate-limiting, acl
proxyПроксирование на upstreamВнутренние механизмы Kong
responseОбработка ответа от upstreamresponse-transformer
body_filterПострочная обработка телаcors (добавление заголовков)
header_filterОбработка заголовковcors, response-transformer
logАсинхронное логированиеhttp-log, tcp-log, prometheus

#2. Встроенные плагины

Проблема: Нужно быстро добавить стандартные функции без написания кода.

Решение: Kong предоставляет множество встроенных плагинов.

#2.1. Категории плагинов

#Аутентификация

  • key-auth — аутентификация по API-ключу
  • jwt — JWT-токены
  • oauth2 — OAuth 2.0 авторизация
  • oidc — OpenID Connect
  • ldap-auth — LDAP аутентификация
  • hmac-auth — HMAC подписанные запросы
  • basic-auth — Basic Auth
  • acl — Access Control Lists (авторизация по группам)

#Безопасность и трафик

  • rate-limiting — ограничение запросов
  • request-size-limiting — ограничение размера запроса
  • response-ratelimiting — ограничение скорости ответа
  • ip-restriction — доступ по IP
  • bot-detection — обнаружение ботов
  • cors — Cross-Origin Resource Sharing
  • proxy-cache — кэширование ответов

#Наблюдаемость

  • prometheus — экспорт метрик
  • zipkin — distributed tracing
  • datadog — интеграция с Datadog
  • http-log — отправка логов на HTTP endpoint
  • tcp-log — отправка логов по TCP
  • udp-log — отправка логов по UDP

#Serverless

  • aws-lambda — вызов AWS Lambda
  • azure-functions — вызов Azure Functions
  • google-cloud-functions — вызов GCP Functions
  • openwhisk — вызов Apache OpenWhisk

#Трансформация

  • request-transformer — модификация запроса
  • response-transformer — модификация ответа
  • request-size-limiting — ограничение размера

#2.2. Применение плагинов

Проблема: Нужно применить плагин к разным уровням (глобально, Service, Route, Consumer).

Решение: Плагины можно применять на четырёх уровнях.

#Глобальный плагин (все запросы)

# Применяется ко всем запросам в Kong curl -X POST http://localhost:8001/plugins \ --data "name=prometheus"

#Плагин на Service (все запросы к сервису)

# Применяется ко всем запросам к users-api curl -X POST http://localhost:8001/services/users-api/plugins \ --data "name=rate-limiting" \ --data "config.minute=100"

#Плагин на Route (запросы к конкретному маршруту)

# Применяется только к запросам на /api/admin curl -X POST http://localhost:8001/routes/admin-route/plugins \ --data "name=ip-restriction" \ --data "config.allow=10.0.0.0/8"

#Плагин на Consumer (индивидуальные настройки)

# Индивидуальный rate limit для premium пользователя curl -X POST http://localhost:8001/consumers/premium-user/plugins \ --data "name=rate-limiting" \ --data "config.hour=10000"

#2.3. Порядок применения плагинов

Проблема: Плагин применён на нескольких уровнях. В каком порядке они выполняются?

Решение: Kong применяет плагины в определённом порядке.

1. Global plugins
       ↓
2. Route plugins
       ↓
3. Service plugins
       ↓
4. Consumer plugins

Пример:

# Глобальный prometheus (все запросы) curl -X POST http://localhost:8001/plugins --data "name=prometheus" # Rate limiting на Route curl -X POST http://localhost:8001/routes/api-route/plugins \ --data "name=rate-limiting" --data "config.minute=60" # Индивидуальный лимит для Consumer curl -X POST http://localhost:8001/consumers/premium/plugins \ --data "name=rate-limiting" --data "config.minute=600"

Для запроса от premium Consumer к api-route:

  1. Выполняется глобальный prometheus (log-этап)
  2. Выполняется rate-limiting с лимитом 600 (Consumer переопределяет Route)

#3. Конфигурация плагинов

#3.1. Базовая конфигурация

# Rate limiting с параметрами curl -X POST http://localhost:8001/routes/api-route/plugins \ --data "name=rate-limiting" \ --data "config.minute=100" \ --data "config.hour=1000" \ --data "config.policy=redis" \ --data "config.redis_host=redis" \ --data "config.fault_tolerant=true"

#3.2. Конфигурация с массивами

# CORS с несколькими разрешёнными origin curl -X POST http://localhost:8001/services/api/plugins \ --data "name=cors" \ --data "config.origins[]=https://app.example.com" \ --data "config.origins[]=https://admin.example.com" \ --data "config.methods[]=GET" \ --data "config.methods[]=POST" \ --data "config.headers[]=Accept" \ --data "config.headers[]=Content-Type" \ --data "config.exposed_headers[]=X-Total-Count" \ --data "config.credentials=true" \ --data "config.max_age=3600"

#3.3. Включение/выключение плагинов

# Временное отключение плагина curl -X POST http://localhost:8001/routes/api-route/plugins \ --data "name=rate-limiting" \ --data "config.enabled=false" # Включение обратно curl -X PATCH http://localhost:8001/routes/api-route/plugins/{plugin-id} \ --data "config.enabled=true"

#4. Кастомные плагины

Проблема: Встроенных плагинов недостаточно для специфических требований.

Решение: Написание кастомного плагина на Lua.

#4.1. Структура кастомного плагина

my-plugin/
├── kong/
│   └── plugins/
│       └── my-plugin/
│           ├── handler.lua    ← логика плагина
│           └── schema.lua     ← схема конфигурации

#4.2. Schema плагина

Проблема: Нужно определить конфигурацию плагина с валидацией.

Решение: Файл schema.lua определяет поля конфигурации.

-- kong/plugins/my-plugin/schema.lua local typedefs = require "kong.db.schema.typedefs" return { name = "my-plugin", fields = { { consumer = typedefs.no_consumer }, { protocols = typedefs.protocols_http }, { config = { type = "record", fields = { { header_name = { type = "string", required = true, default = "X-Custom-Header" }}, { header_value = { type = "string", required = true }}, { skip_for_paths = { type = "array", elements = { type = "string" }, required = false, default = {} }}, }, }, }, }, }

#4.3. Handler плагина

Проблема: Нужно реализовать логику плагина на разных этапах.

Решение: Файл handler.lua с методами для каждого этапа.

-- kong/plugins/my-plugin/handler.lua local Plugin = require "kong.plugins.base_plugin" local MyPlugin = Plugin:extend() function MyPlugin:new() MyPlugin.super.new(self, "my-plugin") end -- Этап access: проверка и модификация запроса function MyPlugin:access(config) MyPlugin.super.access(self) -- Пропуск для определённых paths local path = kong.request.get_path() for _, skip_path in ipairs(config.skip_for_paths) do if string.find(path, skip_path, 1, true) then return end end -- Добавление кастомного заголовка kong.request.set_header(config.header_name, config.header_value) -- Логирование kong.log.info("Added header ", config.header_name, ": ", config.header_value) end -- Этап response: обработка ответа function MyPlugin:response(config) MyPlugin.super.response(self) -- Добавление заголовка к ответу kong.response.set_header("X-Processed-By", "my-plugin") end -- Этап log: асинхронное логирование function MyPlugin:log(config) MyPlugin.super.log(self) -- Отправка метрик local status = kong.response.get_status() kong.log.info("Response status: ", status) end return MyPlugin

#4.4. Регистрация плагина

Проблема: Kong должен знать о кастомном плагине.

Решение: Добавление плагина в конфигурацию.

#Для Docker

# docker-compose.yml services: kong: image: kong:3.5 environment: KONG_PLUGINS: bundled,my-plugin volumes: - ./my-plugin:/usr/local/share/lua/5.1/kong/plugins/my-plugin

#Для bare-metal

# /etc/kong/kong.conf plugins = bundled,my-plugin lua_package_path = /path/to/plugins/?.lua;;

#Перезапуск Kong

# Проверка конфигурации kong check /etc/kong/kong.conf # Перезапуск kong restart

#4.5. Использование PDK (Plugin Development Kit)

Проблема: Нужно взаимодействовать с запросом, ответом, конфигурацией.

Решение: PDK предоставляет API для работы с Kong.

-- Работа с запросом local path = kong.request.get_path() -- /api/users local method = kong.request.get_method() -- GET local headers = kong.request.get_headers() -- таблица заголовков local query = kong.request.get_query() -- таблица query-параметров local body = kong.request.get_raw_body() -- тело запроса -- Работа с ответом local status = kong.response.get_status() -- 200 local headers = kong.response.get_headers() -- таблица заголовков -- Отправка ответа (прекращает обработку) kong.response.exit(401, "Unauthorized", {["WWW-Authenticate"] = "Bearer"}) -- Работа с Consumer local consumer = kong.client.get_consumer() -- таблица Consumer local credential = kong.client.get_credential() -- данные аутентификации -- Сетевые операции local ip = kong.client.get_ip() -- IP клиента local forward_ip = kong.client.get_forwarded_ip() -- Логирование kong.log.info("Info message") kong.log.warn("Warning message") kong.log.err("Error message") kong.log.debug("Debug message (если включён debug log)") -- Кэширование local cache = kong.cache local data, err = cache:get("key", function() -- Функция для получения данных (вызывается при cache miss) return fetch_from_db() end) -- Shared dict (между worker'ами) local shared = kong.shared shared:set("counter", 42) local value = shared:get("counter")

#4.6. Тестирование кастомного плагина

Проблема: Нужно протестировать плагин перед production.

Решение: Использование kong-plugin-tester или интеграционные тесты.

-- spec/my-plugin_spec.lua (используя busted) local helper = require "kong.spec.helper" describe("my-plugin", function() local client setup(function() client = helper.test_client() end) it("adds custom header", function() local response = client:GET("/api/users", { headers = { ["Host"] = "example.com" } }) assert.equals(200, response.status) assert.equals("my-value", response.headers["x-custom-header"]) end) end)

Запуск тестов:

busted spec/my-plugin_spec.lua

#5. Best Practices для кастомных плагинов

#5.1. Производительность

Проблема: Плагин может замедлить обработку запросов.

Решение:

-- ✅ Хорошо: кэширование результатов local data, err = kong.cache:get("key", function() return expensive_operation() end) -- ❌ Плохо: вызов на каждый запрос local data = expensive_operation() -- ✅ Хорошо: ранний выход if not should_process() then return end -- ❌ Плохо: лишние проверки if should_process() then -- обработка end

#5.2. Обработка ошибок

Проблема: Ошибка в плагине не должна ломать весь запрос.

Решение:

function MyPlugin:access(config) MyPlugin.super.access(self) local ok, err = pcall(function() -- рискованная операция process_request() end) if not ok then kong.log.err("Plugin error: ", err) -- Не прерываем запрос, продолжаем обработку end end

#5.3. Конфигурация

Проблема: Хардкод значений в плагине.

Решение:

-- ✅ Хорошо: значения из конфигурации local timeout = config.timeout or 5000 -- ❌ Плохо: хардкод local timeout = 5000

#6. Отладка плагинов

#6.1. Включение debug логов

# /etc/kong/kong.conf log_level = debug

#6.2. Просмотр логов

# Docker docker logs kong # Bare-metal tail -f /var/log/kong/error.log

#6.3. Проверка загруженных плагинов

curl http://localhost:8001/plugins/enabled

Далее: Аутентификация и авторизация