内容简介: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使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
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》 这本书的介绍吧!