DNS and service discovery
In addition to mapping network names to IP addresses, DNS plays a role in service discovery, which is the process by which different resources on the network find out about each other.
By default, applications and servers don't usually know which other applications or servers exist on the network, unless they've been preconfigured with that information. Service discovery allows entities to poll the network, figure out what else is out there and determine its IP address.
It's kind of like walking down the street and yelling "HI THERE! WHAT'S YOUR NAME AND PHONE NUMBER?" at strangers as you pass them by, except in a less awkward and more systematic way.
DNS and large-scale environments
DNS is useful in any context, just as being able to save your friends' phone numbers is valuable no matter how many friends you have. But the importance of automatically mapping identities to numbers is especially critical when you’re dealing with lots of resources – or friends, as the case may be.
If you’re a loner with just three friends, you might be able to remember their phone numbers on your own, just as you could probably keep track of the IP addresses of just a handful of servers manually. But if you're super-duper cool with hundreds of friends, there's no way you can commit all of their numbers to memory. You need an automated system to track those numbers for you.
Kubernetes's need for DNS
A Kubernetes environment is like a person with lots of friends: There are dozens, hundreds or potentially even thousands of entities with unique network identities inside a Kubernetes cluster, and keeping track of the IP addresses of all of them by hand just doesn't work.
Think about it: A Kubernetes cluster is home to a large number of self-contained entities, which are constantly interacting with each other over a variety of internal networks. In addition, any cluster that hosts public-facing applications needs to manage requests from the Internet, which in most cases means it needs to know the IP addresses of even more endpoints.
If you wanted to hate your life, you could try to keep track of the IP addresses for the various resources inside Kubernetes manually. But that would be a nightmare because you'd not only have to spend hours and hours configuring IP addresses initially, but you'd also have to update your IP address lists constantly, since many IP addresses in Kubernetes are dynamically assigned and subject to constant change. The IP address of a Pod or node could change when the Pod or node restarts, for example.
By translating the service names of the various resources inside Kubernetes into IP addresses and keeping track of changes to IP addresses automatically, DNS services in Kubernetes make life much, much simpler for admins. They also help to ensure that the many moving parts inside Kubernetes can talk to each other smoothly – and that ingoing and outgoing requests associated with external networks are properly routed – even as the network configuration constantly changes.
To be clear, DNS is only one ingredient in a full-fledged Kubernetes networking stack. DNS doesn't handle other important network-related tasks, such as load-balancing or the enforcement of security rules via network policies. You'd need other tools (like service meshes and ingress controllers) to do that work. But DNS does handle one of the most important tasks required to operate a Kubernetes cluster at scale.
How Kubernetes DNS is implemented
Today, most Kubernetes clusters rely on CoreDNS, an open source DNS server written in Go, to provide DNS services across the environment. Earlier versions of Kubernetes used SkyDNS, but the Kubernetes developers switched to CoreDNS because the latter is designed specifically for cloud-native environments.
CoreDNS is deployed in a simple way: It runs as a cluster-level Pod and handles DNS queries within the cluster from there. By default, the service is named kube-dns.
Kubernetes external DNS
The CoreDNS DNS server is available in Kubernetes by default, so you don't need to do anything special to get it running. However, if you also need to resolve the names of external services, you might want to install an additional DNS server designed for external requests, such as the aptly named ExternalDNS.
Configuring and troubleshooting kube-DNS
Of course, just because Kubernetes provides an internal DNS server by default doesn't mean it always works the way it's supposed to. If you're experiencing issues like the failure of nodes, Pods or Services to communicate with each other, there's a chance it could be due to problems with your Kubernetes DNS server, so you should troubleshoot it and assess your DNS health.
The first step in doing so is making sure the kube-dns service is actually running. You can do this with kubectl:
Or, if you are GUI-inclined rather than CLI-inclined, you can search the groundcover UI under the Workloads tab to see if kube-dns is running.
Assuming kube-dns is running, your next step is to view the kube-dns logs and look for errors. You can pull these with kubectl:
Or, check the Logs tab in the groundcover UI to view the kube-dns logs.
You can also check whether you can manually resolve domain names from inside a Pod (you have to do this with kubectl, alas):
Advanced kube-dns features and customization options
Beyond basic configuration and troubleshooting, kube-dns also offers a number of advanced features and customization options, such as:
• The ability to add custom plugins and configurations.
• Support for custom resource records.
• Implementation of advanced network topologies.
We won't go into the details of these advanced Kubernetes DNS features here, but if you have special requirements or need fine-grained control over how DNS requests are managed, they're worth looking into. As with most components of Kubernetes, there is a nearly endless amount of flexibility and configurability that you can unlock with regard to DNS management, provided you have the time and will necessary to take advantage of them.
Best practices for using kube-dns in production environments
The ideal setup for your Kubernetes DNS configuration depends on your goals and priorities. But in general, practices like the following will help you get the most out of Kubernetes DNS:
• Ensure that DNS records are configured correctly: If your DNS records are inaccurate, they may as well not exist at all, because your DNS server will provide bad information. Properly configure DNS records for all services in the cluster to ensure that requests for services reach the desired endpoints.
• Monitor the health of kube-dns: Monitor the health of kube-dns by regularly checking its performance and functionality. The kube-dns troubleshooting strategies we outlined above can help with this purpose.
• Configure a separate DNS zone for each environment: By configuring separate DNS zones for each environment, such as production and staging, you can better protect critical services from malicious attacks.
• Use a resolver for external domains: For external domains, use a reliable DNS resolver to prevent potential outages. This can also help in some ways to keep the cluster secure by protecting it against malicious attacks.
Take advantage of kube-dns
Technically speaking, you don't need to use DNS with Kubernetes – just like you also don't need to save your friends' phone numbers in your address book. You could try to remember all of the service name-IP address mappings manually. But unless you’re Cam Jensen, that's not a good way to live your life.
Instead, take advantage of kube-dns. Whether you have just a few resources running in your cluster or several thousand, and whether you're just experimenting with Kubernetes or operating in production, understanding how to leverage kube-dns – and how to troubleshoot DNS health issues in Kubernetes – is a fundamental skill.