内容简介:CoreDNS架构基于Caddy框架实现,整个项目大量使用了Caddy的插件功能,整体代码结构比较清晰,读起来也特别的舒服。首先看CoreDNS的Makefile部分代码:是配置的插件列表,默认插件如下:
CoreDNS架构基于Caddy框架实现,整个项目大量使用了Caddy的插件功能,整体代码结构比较清晰,读起来也特别的舒服。
Makefile
首先看CoreDNS的Makefile部分代码:
如图,可以看到,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
包下的所有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方法如下:
执行的主要动作就是将auto插件注册到caddy中去,然后添加一个setup方法,主要用来做一些初始化配置的操作。
所以,通过这种init的方式,将生成的插件依次注册到caddy中。
CoreDNS初始化
通过 Run
方法进入CoreDNS的初始化过程。 Run
方法主要就是对参数的验证,重点看其引入的包 github.com/coredns/coredns/core/dnsserver
,对应的init方法如下:
RegisterServerType
方法完成插件的最终注册,其中,插件列表
Directives
是
core/dnsserver/zdirectives.go
文件的内容,包含了一系列的插件信息(插件顺序是有严格要求的);而
newContext
就是
dnsContext
对象,实现了caddy的Context接口,
通过MakeServers
完成dnsServer的创建。
DNSServer创建
CoreDNS有多种Server的创建,
分别有DNS、TLS、GRPC以及HTTPS几种方式。以DNS方式为例,进入NewServer
方法,主要作用是添加
pluginChain
链,该链对应的就是相应插件的
plugin.Handler
方法,逆序遍历,
假设加载的插件为errors、log、host,则逆序之后,由于从后往前添加插件host-->log-->errors
,最终实际加载的顺序则是
errors-->log-->host
,和定义的顺序一致。
插件执行
所有的插件主要实现了 Handler
接口,
Name
方法就是插件的名称,重点看 ServeDNS
方法。 ServeDNS
有三个参数, Context
表示整个上下文, ResponseWriter
表示返回给客户端的报文, dns.Msg
为客户端的请求。
每个插件在处理请求时,调用 NextOrFailure
方法调用下一个插件去处理相应的逻辑,即链式调用;调用 WriteMsg
方法完成结束调用,将消息传递给客户端。
Name
和
ServeDNS
方法,并在
plugin.cfg
合适的位置添加插件的信息,即可完成自定义插件的实现,非常方便。
总结
CoreDNS代码的结构非常清晰,通过初始化时加载自定义的插件顺序,依次注入到caddy中去,并在执行的时候,按照定义的插件顺序依次执行,形成一个链式的调用结构。通过DNSServer的创建和多个插件的个性化实现构成整个统一的代码结构。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 以太坊源码分析(36)ethdb源码分析
- [源码分析] kubelet源码分析(一)之 NewKubeletCommand
- libmodbus源码分析(3)从机(服务端)功能源码分析
- [源码分析] nfs-client-provisioner源码分析
- [源码分析] kubelet源码分析(三)之 Pod的创建
- Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。