Chapter 1. Introduction

This book is about CoreDNS, a new DNS server that’s been designed to work well with containers, such as Linux and Docker containers, and especially well in environments managed by Kubernetes, the popular container orchestration system.

This first chapter explains CoreDNS’s raison d'être, and how it differs from other DNS servers, including its limitations. The chapter also covers a little of the history of CoreDNS, such as its relationship to the Cloud Native Computing Foundation.

What Is CoreDNS?

CoreDNS is DNS server software that’s often used to support the service discovery function in containerized environments, particularly those managed by Kubernetes. Miek Gieben wrote the original version of CoreDNS in 2016. He’d previously written a DNS server called SkyDNS and a popular library of DNS functions in the Go language called Go DNS. Like its successor, CoreDNS, SkyDNS’s main purpose was to support service discovery.  But Miek admired the architecture of a Go-based web server called Caddy, so he forked Caddy to create CoreDNS. CoreDNS thus inherited the major advantages of Caddy: its simple configuration syntax, its powerful plug-in-based architecture, and its foundation in Go.

Compared to the syntax of, say, BIND’s configuration file, CoreDNS’s Corefile, as it’s called, is refreshingly simple. The Corefile for a basic CoreDNS-based DNS server is often just a few lines long and—relatively speaking—easy to read.

CoreDNS uses plug-ins to provide DNS functionality. So there’s a plug-in for caching and a plug-in for forwarding, a plug-in for configuring a primary DNS server that reads zone data from a file and a plug-in for configuring a secondary DNS server. Not only is configuring each plug-in straightforward (see the previous paragraph), but if you don’t need a plug-in, you don’t configure it and its code isn’t executed. That makes CoreDNS faster and more secure.

Plug-ins are also fairly easy to develop. That’s important for two reasons. First, if you want to extend CoreDNS’s functionality, you can write your own plug-in; we cover that in Chapter 9. Second, because writing new plug-ins isn’t rocket science, many have been developed, and more are being written all the time. You might find one that provides functionality you need.

The Go language is “memory-safe,” which means that it’s protected from “memory access errors” such as buffer overflows and dangling pointers. That’s particularly important for a DNS server such as CoreDNS, which anyone on the internet could conceivably access. A malicious actor might exploit a buffer overflow to crash a DNS server or even to gain control of the underlying operating system (OS). In fact, over the decades of its history, a substantial number of the serious vulnerabilities in BIND have been caused by memory access errors. With CoreDNS, you don’t need to worry about those.

Probably the most significant advantage CoreDNS offers, though, is its ability to communicate with container infrastructure and orchestration systems such as etcd and Kubernetes. We discuss this in much more detail later in the book, but let’s take a quick look at this functionality here.

CoreDNS, Containers, and Microservices

If you’re in the tiny subset of humanity to whom this book appeals, you’ve probably heard of containers. If you haven’t, think of a container as a very lightweight, efficient virtual machine (VM). Whereas VMs can share a single hardware platform, courtesy of a hypervisor, containers provide execution environments that run under the same OS kernel but provide a similar level of isolation as VMs. Containers are much smaller than VMs and can be started and stopped much more quickly.

Containers are often used in software based on a microservices architecture. With microservices, an application, often a complex one, is decomposed into many microservices. Each microservice is responsible for providing a small but useful and clearly defined set of functionality. For example, one microservice might handle authentication of users, whereas another manages authorization of those users. An application, in total, might comprise dozens or hundreds of microservices, communicating with one another over a network.

In practice, each microservice might be provided by one or more containers. The authentication service, for example, might be implemented as a container. It’s so quick and easy to start and stop containers that the application—or a higher-level container orchestrator—might start and stop additional authentication containers dynamically as demand for authentication waxes and wanes.

In such an environment, though, tracking where a particular service is running can be challenging. Say a container supporting the database service needs to communicate with the authorization service to determine whether a given user should be allowed to conduct a particular search. If the containers that implement the authorization service are being started and stopped dynamically to accommodate load, how do we get a list of all running authorization containers?

The answer is most often DNS, the Domain Name System. Since the communications between containers is almost always based on IP, the Internet Protocol, and because developers have been using DNS to find the IP addresses of resources for literally decades, using DNS to identify containers that offer a given service is natural.

It’s in this capacity that CoreDNS really shines. Not only is CoreDNS a flexible, secure DNS server, but it integrates directly with many container orchestration systems, including Kubernetes. This means that it’s easy for the administrators of containerized applications to set up a DNS server to mediate and facilitate communications between containers.

CoreDNS Limitations

CoreDNS does currently have some significant limitations, though, and it won’t be suitable for every conceivable DNS server. Chief among these is that CoreDNS, at least in the latest version as of this writing, doesn’t support full recursion. In other words, CoreDNS can’t process a query by starting at the root of a DNS namespace, querying a root DNS server and following referrals until it gets an answer from one of the authoritative DNS servers. Instead, it relies on other DNS servers—usually called forwarders—for that. In Chapter 2, we talk more about recursion and forwarders.

If you’re still on the fence about whether CoreDNS is the right choice for your particular needs, Table 1-1 might help; it summarizes the key differences between CoreDNS’s functionality and BIND’s.

Table 1-1. Key functional differences between CoreDNS and BIND
  CoreDNS BIND
Full recursion No Yes
Dynamic updates No Yes
Integration with Kubernetes Yes No
Integration with Amazon Route 53 Yes No
Domain Name System Security Extensions (DNSSEC) support Limited Full
Support for DNS over Transport Layer Security (DoT) Yes No

If you’re unsure about what some of these terms mean, don’t worry, we cover them later in the book. Before we do, though, let’s talk briefly about the formal relationship between CoreDNS, Kubernetes, and something called the Cloud Native Computing Foundation.

CoreDNS, Kubernetes, and the Cloud Native Computing Foundation

Kubernetes, the container orchestration system with which CoreDNS integrates so nicely, was originally written at Google and then converted to an open source project in 2015. To manage the newly open sourced Kubernetes, Google partnered with The Linux Foundation to create the Cloud Native Computing Foundation, or CNCF for short.

The CNCF has become the home for many technologies important to building cloud-based applications, including Prometheus, which supports collecting metrics and alerting, and Envoy, a service proxy. Projects managed by the CNCF move through various “maturity levels,” from “sandbox,” for early-stage projects; to “incubating,” for projects gaining acceptance; to “graduated,” for mature projects suitable for broad adoption.

CoreDNS was submitted to the CNCF in 2017 and moved to “graduated” status in January 2019. As testament to CoreDNS’s criticality to Kubernetes environments, CoreDNS became the default DNS server shipped with Kubernetes with Kubernetes version 1.13, which was released in December 2018. Given that CoreDNS is now installed with almost every new Kubernetes implementation, and Kubernetes is a juggernaut in the world of containers (and containers themselves seem to be taking the world by storm), we expect the installed base of CoreDNS to explode.

Enough of singing CoreDNS’s praises. We’ve talked about what CoreDNS is good for and what it isn’t, and how it’s had its fate lashed to Kubernetes. Next, we give you a whirlwind refresher on DNS theory so that we can begin talking about how to configure CoreDNS to do useful work!

Get Learning CoreDNS now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.