Caching in CoreDNS

April 20, 2016


In the last couple of evenings I’ve implemented a caching middleware in CoreDNS. It has a only a few knobs and should be simple to use.

Take a simple Corefile and add caching, via the cache directive.

.:1053 {
    proxy .
    cache 10
    log stdout
    errors stdout

Which defines CoreDNS to be a proxy, and only cache responses for the zone. This cache only caches for up to 10 seconds. Lets send some queries and looks at the logs:

::1 - [19/Apr/2016:10:41:08 +0000] "MX IN udp false 4096" NOERROR 148 14.057126ms
::1 - [19/Apr/2016:10:41:13 +0000] "MX IN udp false 4096" NOERROR 148 11.705738ms
::1 - [19/Apr/2016:10:41:17 +0000] "MX IN udp false 4096" NOERROR 170 33.744613ms
::1 - [19/Apr/2016:10:41:18 +0000] "MX IN udp false 4096" NOERROR 170 377.881µs

The 33.74ms is the upstream query duration for the first query, after that it craters to a low value. This does not happen for as that domain is exempt from caching.

In the response the TTL is lowered as well:

;; ANSWER SECTION:		9	IN	MX	5		9	IN	MX	10		9	IN	MX	10		9	IN	MX	5		9	IN	MX	1

With caching the last missing piece of SkyDNS has been implemented (only online DNSSEC signing is remaining). I believe (haven’t run CoreDNS in production yet), that CoreDNS has more features (notable multiple domain support) and is more standard compliant than SkyDNS. Having said that, SkyDNS allows its config to be stored in etcd and it can get config from environment variables. CoreDNS can receive a Corefile via stdin though.

The following Corefile should mimic SkyDNS completely:

.:53 {
    etcd skydns.local {
        path /skydns
        endpoint http://localhost:2379
    cache 60 skydns.local
    proxy .
Caching  CoreDNS  DNS