Analysis of the working mechanism of CoreDNS

CoreDNS is an open source Domain Name System (DNS) server used to resolve domain names into IP addresses for network communication. It is an extensible DNS server written in Go language, designed to replace traditional DNS servers and provide more flexible and configurable resolution solutions.

d9c4188e05c225ef7d228a8dfb770ffb.png

CoreDNS provides a modular plug-in system that allows users to select and combine plug-ins according to their needs to customize the functions and behaviors of the DNS server. By adding different plug-ins, users can implement functions such as caching, forwarding, rewriting, policy routing, and service discovery, so as to meet various complex domain name resolution requirements.

Plugins consist of Setup , Registration, and Handler sections.

  • The Setup program parses configuration and directives for plugins.

  • Handler is the code that handles the query and implements all the logic.

  • Registration is to register the plugin with CoreDNS - this is done when CoreDNS is compiled. Servers can use all registered plugins, and the decision of which plugins to configure in each server is made at runtime and is done in the CoreDNS configuration file Corefile.

install and run

Install CoreDNS on macOS:

brew install coredns

Execute  coredns -plugins to view installed plugins:

coredns -plugins

Server types:
  dns

Caddyfile loaders:
  flag
  default

Other plugins:
  dns.acl
  dns.any
  dns.auto
  dns.autopath
  dns.azure
  dns.bind
  dns.bufsize
  dns.cache
  dns.cancel
  dns.chaos
  dns.clouddns
  dns.debug
  dns.dns64
  dns.dnssec
  dns.dnstap
  dns.erratic
  dns.errors
  dns.etcd
  dns.file
  dns.forward
  dns.geoip
  dns.grpc
  dns.header
  dns.health
  dns.hosts
  dns.k8s_external
  dns.kubernetes
  dns.loadbalance
  dns.local
  dns.log
  dns.loop
  dns.metadata
  dns.minimal
  dns.nsid
  dns.pprof
  dns.prometheus
  dns.ready
  dns.reload
  dns.rewrite
  dns.root
  dns.route53
  dns.secondary
  dns.sign
  dns.template
  dns.tls
  dns.trace
  dns.transfer
  dns.tsig
  dns.view
  dns.whoami
  on

The operation of CoreDNS is very simple,  coredns just execute the command to start the server. In order to avoid port conflicts, you can specify other ports to start:

coredns -dns.port=1053
.:1053
CoreDNS-1.10.0
darwin/arm64, go1.19.1,

If you need to configure the DNS server, you need to  -conf specify a Corefile configuration file, and you can also enable plug-ins in the configuration file. If no configuration file is specified, CoreDNS will use the default configuration [1] and only enable `whoami` [2]  and `log` [3]  two plugins:

.:PORT {
   whoami
   log
}

For example, I execute a DNS resolution request from a virtual machine, 192.168.1.174 which is the macOS address running the CoreDNS server:

dig @192.168.1.174 -p 1053 example.com

; <<>> DiG 9.16.1-Ubuntu <<>> @192.168.1.174 -p 1053 example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1283
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: d73ad3e9df490541 (echoed)
;; QUESTION SECTION:
;example.com.   IN A

;; ADDITIONAL SECTION:
example.com.  0 IN A 192.168.1.11
_udp.example.com. 0 IN SRV 0 0 48788 .

;; Query time: 8 msec
;; SERVER: 192.168.1.174#1053(192.168.1.174)
;; WHEN: Sat Jul 15 02:38:11 UTC 2023
;; MSG SIZE  rcvd: 114

In the response,  ADDITIONAL you can see  example.com that it has been resolved  192.168.1.11, and this address is the IP address of the virtual machine that initiated the request. This is  whoami the logic of the plugin [4] :

whoami will return the requester's local IP address, port.

Source code analysis

start up

Coredns uses a fork  of Coredns Caddy [6 ] from Caddy [5]  to start the DNS server.

  1. Load the specified Corefile configuration file, such as  /etc/coredns/Corefile `coremain/run.go#L60` [7]

  2. Start Caddy Server coremain/run.go#L66 [8]

  3. Running the Plugin 980806dc5b36c25a694355156d36d911.png1. Check the configuration file for the plugin. Coredns has a list of supported plugins [9] , and the order of plugins in this list is important. 2. Create a controller for each plug-in. 3. Find the startup method for plug-in registration  , such as the `setup` [10] method setupof the Kubernetes plug-in .  Methods  for each plugin  can  be found in . 4. Start the plugin.setupcoredns/plugin/[PLUGIN NAME]/setup.go

  4. Create server core/dnsserver/register.go#L134 [11]

  5. start server github.com/coredns/[email protected]/caddy.go:542[12 ]

process request

  1. After the server is started, it starts to receive DNS resolution requests, see github.com/coredns/[email protected]/caddy.go:805 [13] .

  2. Process DNS resolution requests core/dnsserver/server.go#L173 [14] , here the method ServeDNS [15] will be called  to execute the configured plugins in order, and all plugins implement the plugin.Handler [16]  interface.

Each plug-in configured will decide whether to perform DNS resolution, and the next step: return a response, report an error, return immediately, or call the next plug-in to continue execution. For details, refer to the official document [17] .

CoreDNS and Kubernetes

CoreDNS plays an important role in Kubernetes, providing services for DNS resolution within the cluster. Through tight integration with Kubernetes, CoreDNS can provide reliable service discovery and communication functions, enabling containers and services to access and communicate with each other through domain names, providing infrastructure support for the operation of Kubernetes clusters.

All functions are implemented in the kubernetes plug- in [18]  , which implements Kubernetes’ DNS-based service discovery specification [19] , and CoreDNS uses this to replace kube-dns.

CoreDNS configuration in Kubernetes (maintained in ConfigMap  coredns ):

.:53 {
   errors
   health {
      lameduck 5s
   }
   ready
   kubernetes cluster.local in-addr.arpa ip6.arpa {
      pods insecure
      fallthrough in-addr.arpa ip6.arpa
      ttl 30
   }
   prometheus :9153
   forward . /etc/resolv.conf {
      max_concurrent 1000
   }
   cache 30
   loop
   reload
   loadbalance
}

When CoreDNS processes resolution requests, it will execute each plugin in order.

fefbd8028c3023e8bd0e11be6b1575ee.png

plugin configuration

kubernetes cluster.local in-addr.arpa ip6.arpa { #1
    pods insecure #2
    fallthrough in-addr.arpa ip6.arpa #3
    ttl 30 #4
 }
  • #1 The kubernetes plugin will handle  cluster.local DNS resolution requests for domains, such as  foo.bar.svc.cluster.local; in-addr.arpa and  ip6.arpa for doing DNS reverse queries [20] , such as  4.4.8.8.in-addr.arpa.

  • #2  10-244-0-2.bar.pod.cluster.localSet the resolution mode of the POD domain name (such as ) to  insecuredisabled and  verified the other two modes are also supported.

  • #3 For the parsing request of the reverse query, it will be handed over to other plug-ins to continue the query.

  • #4 The validity period of the analysis result is 5s by default, and it is set to 30s here.

start up

When CoreDNS starts, it will delay providing DNS services for up to 5 seconds until it can connect to the Kubernetes API and synchronize all monitored objects, see document [21] .

The kubernetes plug-in will start up to 4 controllers [22] according to the configuration , and continuously monitor the Service, Pod (start verified when ), Endpoint, and Namespace resources respectively, and maintain the local cache.

process request

The kubernetes plugin implements the `plugin.ServiceBackend` interface [23] to look up records from the local cache when responding to requests.

Taking the query of A records as an example, call the plugin#A method [24]  to indirectly call the implementation of the `ServiceBackend#Services` method [25]  to retrieve and return the IP address.

nslookup -type=a foo.bar.svc.cluster.local
Server:  10.96.0.10
Address: 10.96.0.10:53

Name: foo.bar.svc.cluster.local
Address: 10.96.60.147

References

[1] 

Default configuration:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/register.go#L25

[2] 

whoamihttps://coredns.io/plugins/whoami/

[3] 

loghttps://coredns.io/plugins/log/

[4] 

Logic:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/whoami/whoami.go#L22

[5] 

Caddy: https://github.com/caddyserver/caddy

[6] 

Coredns Caddy: https://github.com/coredns/caddy

[7] 

coremain/run.go#L60https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/coremain/run.go#L60

[8] 

coremain/run.go#L66: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/coremain/run.go#L66

[9] 

Plugin list:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/zdirectives.go#L12

[10] 

setuphttps://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/kubernetes/setup.go#L31

[11] 

core/dnsserver/register.go#L134: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/register.go#L134

[12] 

github.com/coredns/[email protected]/caddy.go:542: https://github.com/coredns/caddy/blob/v1.1.1/caddy.go#L542

[13] 

github.com/coredns/[email protected]/caddy.go:805: https://github.com/coredns/caddy/blob/v1.1.1/caddy.go#L805

[14] 

core/dnsserver/server.go#L173: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/server.go#L173

[15] 

Method ServeDNS:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/server.go#L252

[16] 

plugin.Handler:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/plugin.go#L50

[17] 

Official documentation:  https://coredns.io/manual/plugins/#plugins

[18] 

kubernetes plugin:  https://coredns.io/plugins/kubernetes/

[19] 

DNS-based service discovery specification for Kubernetes:  https://github.com/kubernetes/dns/blob/master/docs/specification.md

[20] 

DNS reverse lookup:  https://en.wikipedia.org/wiki/Reverse_DNS_lookup

[21] 

Documentation:  https://coredns.io/plugins/kubernetes/#startup

[22] 

Start up to 4 controllers:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/kubernetes/controller.go#L105

[23] 

plugin.ServiceBackend Interface:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/backend.go#L13

[24] 

plugin#A method:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/backend_lookup.go#L17

[25] 

ServiceBackend#Services Method implementation:  https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/kubernetes/kubernetes.go#L92

Guess you like

Origin blog.csdn.net/g6U8W7p06dCO99fQ3/article/details/131777743