Исходный код CoreDNS основан на версии 1.3.1.
Архитектура
Архитектура CoreDNS реализована на основе фреймворка Caddy, весь проект использует множество подключаемых функций Caddy, общая структура кода относительно понятна и очень удобна для чтения.
Makefile
Сначала взгляните на часть Makefile кода CoreDNS:
core/plugin/zplugin.goа такжеcore/dnsserver/zdirectives.goфайлы сделаныcoredns.goпройти черезplugin.cfgСгенерировано. в,coredns.goэто файл запуска,plugin.cfgпредставляет собой список настроенных плагинов, плагины по умолчанию следующие:
# Directives are registered in the order they should be
# executed.
#
# Ordering is VERY important. Every plugin will
# feel the effects of all other plugin below
# (after) them during a request, but they must not
# care what plugin above them are doing.
# How to rebuild with updated plugin configurations:
# Modify the list below and run `go gen && go build`
# The parser takes the input format of
# <plugin-name>:<package-name>
# Or
# <plugin-name>:<fully-qualified-package-name>
#
# External plugin example:
# log:github.com/coredns/coredns/plugin/log
# Local plugin example:
# log:log
metadata:metadata
tls:tls
reload:reload
nsid:nsid
root:root
bind:bind
debug:debug
trace:trace
health:health
pprof:pprof
prometheus:metrics
errors:errors
log:log
dnstap:dnstap
chaos:chaos
loadbalance:loadbalance
cache:cache
rewrite:rewrite
dnssec:dnssec
autopath:autopath
template:template
hosts:hosts
route53:route53
federation:federation
k8s_external:k8s_external
kubernetes:kubernetes
file:file
auto:auto
secondary:secondary
etcd:etcd
loop:loop
forward:forward
proxy:proxy
erratic:erratic
whoami:whoami
on:github.com/mholt/caddy/onevent
В код по умолчанию включены все существующие плагины, представленные в виде пары ключ-значение.
Посмотрите еще раз на файл запускаcoredns.go:
Runметод, но загруженныйgithub.com/coredns/coredns/core/pluginВсе методы инициализации в пакете.github.com/coredns/coredns/core/pluginТолько один в упаковкеzplugin.goфайл, и этот файл является файлом, сгенерированным Makefile, следующим образом:
// generated by directives_generate.go; DO NOT EDIT
package plugin
import (
// Include all plugins.
_ "github.com/coredns/coredns/plugin/auto"
_ "github.com/coredns/coredns/plugin/autopath"
_ "github.com/coredns/coredns/plugin/bind"
_ "github.com/coredns/coredns/plugin/cache"
_ "github.com/coredns/coredns/plugin/chaos"
_ "github.com/coredns/coredns/plugin/debug"
_ "github.com/coredns/coredns/plugin/dnssec"
_ "github.com/coredns/coredns/plugin/dnstap"
_ "github.com/coredns/coredns/plugin/erratic"
_ "github.com/coredns/coredns/plugin/errors"
_ "github.com/coredns/coredns/plugin/etcd"
_ "github.com/coredns/coredns/plugin/federation"
_ "github.com/coredns/coredns/plugin/file"
_ "github.com/coredns/coredns/plugin/forward"
_ "github.com/coredns/coredns/plugin/health"
_ "github.com/coredns/coredns/plugin/hosts"
_ "github.com/coredns/coredns/plugin/k8s_external"
_ "github.com/coredns/coredns/plugin/kubernetes"
_ "github.com/coredns/coredns/plugin/loadbalance"
_ "github.com/coredns/coredns/plugin/log"
_ "github.com/coredns/coredns/plugin/loop"
_ "github.com/coredns/coredns/plugin/metadata"
_ "github.com/coredns/coredns/plugin/metrics"
_ "github.com/coredns/coredns/plugin/nsid"
_ "github.com/coredns/coredns/plugin/pprof"
_ "github.com/coredns/coredns/plugin/proxy"
_ "github.com/coredns/coredns/plugin/reload"
_ "github.com/coredns/coredns/plugin/rewrite"
_ "github.com/coredns/coredns/plugin/root"
_ "github.com/coredns/coredns/plugin/route53"
_ "github.com/coredns/coredns/plugin/secondary"
_ "github.com/coredns/coredns/plugin/template"
_ "github.com/coredns/coredns/plugin/tls"
_ "github.com/coredns/coredns/plugin/trace"
_ "github.com/coredns/coredns/plugin/whoami"
_ "github.com/mholt/caddy/onevent"
)
Другой файл, сгенерированный Makefilezdirectives.goследующим образом:
// generated by directives_generate.go; DO NOT EDIT
package dnsserver
// Directives are registered in the order they should be
// executed.
//
// Ordering is VERY important. Every plugin will
// feel the effects of all other plugin below
// (after) them during a request, but they must not
// care what plugin above them are doing.
var Directives = []string{
"metadata",
"tls",
"reload",
"nsid",
"root",
"bind",
"debug",
"trace",
"health",
"pprof",
"prometheus",
"errors",
"log",
"dnstap",
"chaos",
"loadbalance",
"cache",
"rewrite",
"dnssec",
"autopath",
"template",
"hosts",
"route53",
"federation",
"k8s_external",
"kubernetes",
"file",
"auto",
"secondary",
"etcd",
"loop",
"forward",
"proxy",
"erratic",
"whoami",
"on",
}
Два файла, один для загрузки всех подключаемых модулей и выполнения метода инициализации, другой для настройки массива.
назадzplugin.goфайл вgithub.com/coredns/coredns/plugin/autoВзяв пакет в качестве примера, его соответствующий метод инициализации выглядит следующим образом:
Поэтому с помощью этого метода инициализации сгенерированные плагины по очереди регистрируются в caddy.
Инициализация CoreDNS
пройти черезRunМетод входит в процесс инициализации CoreDNS.RunЭтот метод в основном заключается в проверке параметров, уделяя особое внимание пакету, который он вводит.github.com/coredns/coredns/core/dnsserver, соответствующий метод инициализации выглядит следующим образом:
RegisterServerTypeМетод завершает окончательную регистрацию плагина, где список плагиновDirectivesдаcore/dnsserver/zdirectives.goСодержимое файла содержит ряд информации о подключаемых модулях (порядок подключаемых модулей строго обязателен); иnewContextто естьdnsContextобъект, который реализует интерфейс Caddy Context,MakeServersЗавершите создание dnsServer.
Создание DNS-сервера
CoreDNS имеет множество вариантов создания серверов,
NewServerметод, основная функция которого заключается в добавленииpluginChainЦепочка, которой соответствует соответствующий плагинplugin.Handlerметод обхода в обратном порядке,host-->log-->errors, окончательный фактический порядок загрузкиerrors-->log-->host, в том же порядке, как определено.
Выполнение плагина
Все плагины в основном реализуютHandlerинтерфейс,
NameМетод — это название плагина, сосредоточьтесь наServeDNSметод.ServeDNSЕсть три параметра,Contextпредставляет весь контекст,ResponseWriterУказывает, что сообщение возвращается клиенту,dns.Msgпо запросу клиента.Когда каждый плагин обрабатывает запрос, он вызывает
NextOrFailureМетод вызывает следующий плагин для обработки соответствующей логики, то есть цепочек вызовов; вызовWriteMsgМетод завершает вызов завершения, передавая сообщение клиенту.Если вам нужен пользовательский плагин, он в основном реализован
Nameа такжеServeDNSметод, а вplugin.cfgОчень удобно добавлять информацию о плагине в соответствующее место, чтобы завершить реализацию пользовательского плагина.
Плагин Kubernetes
Kubernetes также предоставляется в виде подключаемых модулей в CoreDNS, в основном предоставляя внутренние ресурсы в качестве источника разрешения доменных имен.
запускать
Как и другие подключаемые модули, Kubernetes также выполняет init для регистрации подключаемого модуля в caddy, а затем вызываетsetupспособ завершения работы по запуску. посмотриsetupГлавное что делать.
kubernetesParseРазберите соответствующую конфигурацию подключаемого модуля Kubernetes, затем вызовитеInitKubeCacheинициализацияkubeClient, во время вызоваnewdnsControllerИнициализируйте dnsController, взаимодействуйте с кластером Kubernetes через dnsController и получите соответствующие данные в кластере; наконец, вызовитеAddPluginДобавьте плагин в конфигурацию в виде связанного списка для завершения инициализации.
бегать
бежать, чтобы достичьServeDNSметод начинается. Главное — ввести разную логику обработки, разбирая разные типы запросов.
ServiceBackendЗавершите разрешение доменного имени.ServicesВ основном в соответствии с конкретным типом запроса, получить все соответствующие услуги;ReverseВ основном выполняют действия по обратному разрешению доменного имени, то есть получают соответствующее доменное имя через IP;LookupВ основном используется для поиска вышестоящего DNS-сервера;RecordsВ основном выполняют работу по разрешению доменных имен и возвращают определенные записи.Суммировать
Структура кода CoreDNS очень понятна: загрузив пользовательскую последовательность подключаемых модулей во время инициализации, они по очереди внедряются в caddy, а при выполнении выполняются последовательно в соответствии с определенной последовательностью подключаемых модулей, формируя Структура цепного вызова. Вся унифицированная структура кода формируется за счет создания DNSServer и персонализированной реализации нескольких подключаемых модулей.