1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-coredns

Клонировать/Скачать
plugin.md 12 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 11.06.2025 08:22 1869dea

Плагины

Создание плагинов

Основной метод, который вызывается, это ServeDNS. У него три параметра:

  • context.Context;
  • dns.ResponseWriter, который, по сути, представляет соединение клиента;
  • *dns.Msg, запрос от клиента.

ServeDNS возвращает два значения: код ответа и ошибку. Если ошибка не равна nil, CoreDNS вернет код SERVFAIL клиенту. Код ответа сообщает CoreDNS, был ли ответ записан цепочкой плагинов или нет. В последнем случае CoreDNS сам позаботится об этом.

CoreDNS обрабатывает:

  • SERVFAIL (dns.RcodeServerFailure)
  • REFUSED (dns.RcodeRefused)
  • FORMERR (dns.RcodeFormatError)
  • NOTIMP (dns.RcodeNotImplemented)

как специальные коды и считает, что ничего не было записано клиенту. В остальных случаях предполагается, что что-то было записано клиенту (плагином).

Пример плагина example демонстрирует базовую реализацию, которую можно использовать в качестве отправной точки для вашего плагина. Этот плагин имеет тесты и подробные комментарии в коде.

Подключение

См. несколько блог-постов о том, как создавать и добавлять плагины в CoreDNS:

ЛогированиеЕсли ваш плагин должен выводить строку лога, вы должны использовать пакет plugin/pkg/log.

Этот пакет реализует уровни логирования. Стандартный способ вывода: log.Info для сообщений уровня info. Доступны уровни log.Info, log.Warning, log.Error, log.Debug. Каждый из этих уровней также имеет вариацию f. Имя плагина должно быть включено, используя пакет логирования следующим образом:~~~ go import clog "github.com/coredns/coredns/plugin/pkg/log"

var log = clog.NewWithPlugin("whoami")

log.Info("сообщение") // выводит: [INFO] plugin/whoami: сообщение


В общем, логирование должно оставаться на более высоких уровнях, возвращая ошибку. Однако, если
есть причина обрабатывать ошибку и уведомлять пользователя, то логирование в самом плагине может
быть допустимым. Функции `Debug*` выводят что-то только тогда, когда плагин `debug` загружен в
сервер.

## Метрики

При экспорте метрик пространство имен должно быть `plugin.Namespace` (="coredns"), а подпространство
должно быть именем плагина. В README.md для плагина должна быть секция *Metrics*, детализирующая
метрики.

## Готовность

Если плагин поддерживает сигнал о готовности, он должен иметь раздел *Готовность*, описывающий, как это работает, и реализовать интерфейс `ready.Readiness`.

## Открытие сокетов

См. плагин/pkg/reuseport для функций `Listen` и `ListenPacket`. Использование этих функций улучшает обработку событий перезагрузки плагином.

## Контекст

Каждый запрос получает контекст `context.Context`, который предварительно заполнен двумя значениями:

* `Key`: содержит указатель на текущий сервер, что может быть полезно для логирования или метрик. Это значение используется в плагине *metrics* для привязки запроса к конкретному (внутреннему) серверу.
* `LoopKey`: содержит целое число для обнаружения циклов в текущем контексте. Плагин *file* использует это для обнаружения циклов при разрешении CNAME.
## Документация

Каждый плагин должен иметь файл README.md, объясняющий, что делает плагин и как он настраивается. Файл должен иметь следующую структуру:

* Заголовок: используйте имя плагина
* Подраздел с заголовком: "Name"
    с *PLUGIN* - однострочной описательной строкой.
* Подраздел с заголовком: "Описание" содержит более подробное описание.
* Подраздел с заголовком: "Синтаксис", синтаксис и поддерживаемые директивы.
* Подраздел с заголовком: "Примеры"

Более разделов, конечно, возможны.

### Стиль

Мы используем стиль страницы Unix-руководства:

* Имя плагина в тексте должно быть курсивом: *plugin*.
* Все заглавные буквы: аргументы, предоставленные пользователем, в тексте ссылки на это используются жирным шрифтом: `**`: **EXAMPLE**.
* Необязательный текст: в блоках цитирования: `[необязательный]`.
* Используйте три точки для указания, что допускается несколько опций: `arg...`.
* Элементы используются в виде литерала: `литерал`.

### Пример доменных имен

Пожалуйста, убедитесь, что вы используете `example.org` или `example.net` в любых примерах и тестах, которые вы предоставляете. Эти доменные имена созданы для этой цели.

## Передача управленияВ идеальном мире следующее должно быть истинным для плагина: "Либо вы отвечаете за зону, либо нет". Если ответ "нет", плагин должен вызвать следующий плагин в цепочке. Если "да", он должен обрабатывать *все* имена, которые находятся в этой зоне и имена ниже — то есть он должен обрабатывать весь домен и все поддомены.~~~ txt
. {
    file example.org db.example
}

В этом примере плагин file обрабатывает все имена ниже (и включая) example.org. Если запрос приходит, который не является поддоменом (или равен) example.org, вызывается следующий плагин. Теперь мир не идеален, и могут быть причины для "перехода" к следующему плагину, что означает, что плагин отвечает только за подмножество имен в зоне.

Инструкция fallthrough должна по желанию принимать список зон. Только запросы на записи в одной из этих зон должны быть разрешены для перехода. См. plugin/pkg/fallthrough для реализации.

Мутация ответа

Используя пользовательский ResponseWriter, плагин может изменять ответ, когда другой плагин ниже по цепочке записывает ответ клиенту. Если плагин изменяет ответ, он должен сделать копию всего ответа перед тем, как это сделать. Ответ является указателем на dns.Msg, и таким образом вы будете манипулировать исходным ответом, который мог быть сгенерирован из хранилища данных. Например, плагин file создаёт ответ, который затем перезаписывается плагином rewrite; не копируя данные, означает, что также изменяется данные хранилища file. Ответ можно скопировать, используя метод Copy().

Общие рекомендации

Некоторые общие рекомендации:* время логирования должно быть выполнено в секундах (вызовите метод Seconds() для любого интервала времени).

  • ограничьте логирование до минимума.
  • назовите основную функцию парсинга конфигурации просто parse.
  • постарайтесь минимизировать количество настроек в конфигурации.
  • используйте plugin.Error() для обёртки ошибок, возвращаемых функцией setup.## Квалификация для основного репозитория

Плагины для CoreDNS могут существовать вне дерева, plugin.cfg по умолчанию указывает на репозиторий CoreDNS, но другие репозитории работают также хорошо. Так когда мы рассматриваем включение нового плагина в основной репозиторий?

  • Сначала, плагин должен быть полезен для других людей. "Полезность" — это субъективное понятие. Мы, вероятно, будем нуждаться в дальнейшем уточнении этого.
  • Он должен быть достаточно отличным от других плагинов, чтобы заслужить включение.
  • Текущие интернет-стандарты должны быть поддерживаемы: IPv4 и IPv6, так что записи A и AAAA должны быть обрабатываемы (если ваш плагин занимается обработкой адресных записей).
  • Он должен иметь тесты.
  • Он должен иметь README.md для документации.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-coredns.git
git@api.gitlife.ru:oschina-mirror/mirrors-coredns.git
oschina-mirror
mirrors-coredns
mirrors-coredns
master