CoreDNS源码分析

栏目: 编程工具 · 发布时间: 5年前

内容简介:CoreDNS架构基于Caddy框架实现,整个项目大量使用了Caddy的插件功能,整体代码结构比较清晰,读起来也特别的舒服。首先看CoreDNS的Makefile部分代码:是配置的插件列表,默认插件如下:

CoreDNS架构基于Caddy框架实现,整个项目大量使用了Caddy的插件功能,整体代码结构比较清晰,读起来也特别的舒服。

Makefile

首先看CoreDNS的Makefile部分代码:

CoreDNS源码分析
如图,可以看到, core/plugin/zplugin.gocore/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

CoreDNS源码分析
代码很简单,就是一个 Run 方法,但是加载了 github.com/coredns/coredns/core/plugin 包下的所有init方法。 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"
)
复制代码

Makefile生成的另一文件 zdirectives.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",
}
复制代码

两个文件,一个是加载所有的插件模块,执行init方法;另一个就是配置了一个数组。

回到 zplugin.go 文件,以 github.com/coredns/coredns/plugin/auto 包为例,其相应的init方法如下:

CoreDNS源码分析

执行的主要动作就是将auto插件注册到caddy中去,然后添加一个setup方法,主要用来做一些初始化配置的操作。

所以,通过这种init的方式,将生成的插件依次注册到caddy中。

CoreDNS初始化

通过 Run 方法进入CoreDNS的初始化过程。 Run 方法主要就是对参数的验证,重点看其引入的包 github.com/coredns/coredns/core/dnsserver ,对应的init方法如下:

CoreDNS源码分析
通过caddy的 RegisterServerType 方法完成插件的最终注册,其中,插件列表 Directivescore/dnsserver/zdirectives.go 文件的内容,包含了一系列的插件信息(插件顺序是有严格要求的);而 newContext 就是 dnsContext

对象,实现了caddy的Context接口,

CoreDNS源码分析
通过 MakeServers

完成dnsServer的创建。

DNSServer创建

CoreDNS有多种Server的创建,

CoreDNS源码分析
分别有DNS、TLS、GRPC以及HTTPS几种方式。以DNS方式为例,进入 NewServer 方法,主要作用是添加 pluginChain 链,该链对应的就是相应插件的 plugin.Handler

方法,逆序遍历,

CoreDNS源码分析
假设加载的插件为errors、log、host,则逆序之后,由于从后往前添加插件 host-->log-->errors ,最终实际加载的顺序则是 errors-->log-->host

,和定义的顺序一致。

插件执行

所有的插件主要实现了 Handler 接口,

CoreDNS源码分析

Name 方法就是插件的名称,重点看 ServeDNS 方法。 ServeDNS 有三个参数, Context 表示整个上下文, ResponseWriter 表示返回给客户端的报文, dns.Msg 为客户端的请求。

每个插件在处理请求时,调用 NextOrFailure 方法调用下一个插件去处理相应的逻辑,即链式调用;调用 WriteMsg 方法完成结束调用,将消息传递给客户端。

如果需要自定义插件的话,基本上实现了 NameServeDNS 方法,并在 plugin.cfg

合适的位置添加插件的信息,即可完成自定义插件的实现,非常方便。

总结

CoreDNS代码的结构非常清晰,通过初始化时加载自定义的插件顺序,依次注入到caddy中去,并在执行的时候,按照定义的插件顺序依次执行,形成一个链式的调用结构。通过DNSServer的创建和多个插件的个性化实现构成整个统一的代码结构。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web 2.0 Architectures

Web 2.0 Architectures

Duane Nickull、Dion Hinchcliffe、James Governor / O'Reilly / 2009 / USD 34.99

The "Web 2.0" phenomena has become more pervasive than ever before. It is impacting the very fabric of our society and presents opportunities for those with knowledge. The individuals who understand t......一起来看看 《Web 2.0 Architectures》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具