coredns源码分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了coredns源码分析相关的知识,希望对你有一定的参考价值。
参考技术ACoreDNS是使用go语言编写的快速灵活的DNS服务,采用链式插件模式,每个插件实现独立的功能,底层协议可以是tcp/udp,也可以是TLS,gRPC等。默认监听所有ip地址,可使用bind插件指定监听指定地址。
格式如下
SCHEME是可选的,默认值为dns://,也可以指定为tls://,grpc://或者https://。
ZONE是可选的,指定了此dnsserver可以服务的域名前缀,如果不指定,则默认为root,表示可以接收所有的dns请求。
PORT是选项的,指定了监听端口号,默认为53,如果这里指定了端口号,则不能通过参数-dns.port覆盖。
一块上面格式的配置表示一个dnsserver,称为serverblock,可以配置多个serverblock表示多个dnsserver。
下面通过一个例子说明,如下配置文件指定了4个serverblock,即4个dnsserver,第一个监听端口5300,后面三个监听同一个端口53,每个dnsserver指定了特定的插件。
下图为配置的简略图
a. 从图中可看到插件执行顺序不是配置文件中的顺序,这是因为插件执行顺序是在源码目录中的plugin.cfg指定的,一旦编译后,顺序就固定了。
b. .根serverblock虽然指定了health,但是图中却没有,这是因为health插件不参与dns请求的处理。能处理dns请求的插件必须提供如下两个接口函数。
dns请求处理流程
收到dns请求后,首先根据域名匹配zone找到对应的dnsserver(最长匹配优先),如果没有匹配到,则使用默认的root dnsserver。
找到dnsserver后,就要按照插件顺序执行其中配置的插件,当然并不是配置的插件都会被执行,如果某个插件成功找到记录,则返回成功,否则根据插件是否配置了fallthrough等来决定是否执行下一个插件。
plugin.cfg
源码目录下的plugin.cfg指定了插件执行顺序,如果想添加插件,可按格式添加到指定位置。
源码目录下的Makefile根据plugin.cfg生成了两个go文件:zplugin.go和zdirectives.go。
core/dnsserver/zdirectives.go将所有插件名字放在一个数组中。
codedns 主函数
codedns.go 首先导入了包"github.com/coredns/coredns/core/plugin",此包内只有一个文件zplugin.go,此文件为自动生成的,主要导入了所有的插件,执行每个插件的init函数。
接着执行 run.go Run
此文件又引入了包"github.com/coredns/coredns/core/dnsserver",其init函数在 dnsserver/register.go 文件中,如下所示,主要是注册了serverType
剩下的就是解析参数,解析配置文件后,执行caddy.Start。
这里就是根据配置文件中指定的serverblock,执行插件的setup进行初始化,创建对应的server,开始监听dns请求
tcp协议调用Serve,udp协议调用ServePacket
收到DNS请求后,调用ServeDNS,根据域名匹配dnsserver,如果没有匹配不到则使用根dnsserver,然后执行dnsserver中配置的插件
以k8s插件为例
参考
//如何写coredns插件
http://dockone.io/article/9620
//coredns源码分析
https://wenku.baidu.com/view/34cabc1e346baf1ffc4ffe4733687e21af45ff7c.html
https://blog.csdn.net/zhonglinzhang/article/details/99679323
https://www.codercto.com/a/89703.html
//NodeLocal DNSCache
https://www.cnblogs.com/sanduzxcvbnm/p/16013560.html
https://blog.csdn.net/xixihahalelehehe/article/details/118894971
kubernetes之coredns玩法
一、概述
新版本的kubernetes默认使用了coredns,这里就不赘述了。直达车:https://coredns.io/、https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns
二、coredns配置
在之前的博客里面介绍过使用dnsmasq作为coredns的上游dns的玩法,这里介绍直接修改coredns的配置,coredns的配置是Corefile,可以通过configmap控制修改。默认的配置如下:
# kubectl get cm coredns -n kube-system -o yaml
apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } prometheus :9153 proxy . /etc/resolv.conf cache 30 loop reload loadbalance }
errors、health等都是cordns的插件,更多插件参考:https://coredns.io/plugins/
kuberneets1.10开始,支持将kube-dns的配置转换成coredns的配置。kube-dns里面使用stubDomains来指定存根域,即
apiVersion: v1 kind: ConfigMap metadata: name: kube-dns namespace: kube-system data: stubDomains: | {"demo.local": ["10.0.0.1"]}
使用upstreamNameservers来指定非集群dns查找使用外部dns解析,如果设置default默认只会使用node节点dns解析。
apiVersion: v1 kind: ConfigMap metadata: name: kube-dns namespace: kube-system data: upstreamNameservers: | ["10.0.0.1"]
在coredns里面使用upstream和proxy实现kube-dns的stubDomains、upstreamNameservers的功能。
1、coredns使用consul作为dns查询
修改coredns的configmap:
# kubectl -n kube-system edit cm coredns
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
proxy . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
service.hq:53 {
errors
cache 30
proxy . 10.4.9.6
}
service.hq是在consul里面设置的domain,consul使用参考我可博客:https://www.cnblogs.com/cuishuai/p/8194345.html,我的consul设置的dns端口是53,默认是8600. 10.4.9.6是consul的监听地址。
重新调度pod使配置生效:
kubectl get pods -n kube-system | grep coredns | awk ‘{print $1}‘ | xargs kubectl -n kube-system delete pod
测试:
activity是我们在consul里面注册的服务,sleep是包含curl和ping的pod。
# kubectl exec -it -n istio-system sleep-754684654f-c6mct -- ping activity.service.hq
附录:
sleep的yaml:
apiVersion: v1 kind: ServiceAccount metadata: name: sleep --- apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: sleep spec: replicas: 1 template: metadata: labels: app: sleep spec: serviceAccountName: sleep containers: - name: sleep image: pstauffer/curl command: ["/bin/sleep", "3650d"] imagePullPolicy: IfNotPresent ---
以上是关于coredns源码分析的主要内容,如果未能解决你的问题,请参考以下文章