Isn’t DNS the address book for IP addresses? Sure but it has some super powers too! If you start thinking about DNS as a delegation system you can unlock its powers and create abstraction layers to simplify service management and more.
In fact everybody uses DNS delegation for email:
Let’s try it:
$ dig mx tesla.com
tesla.com. 300 IN MX 10 tesla-com.mail.protection.outlook.com.
The MX record is used to point to the system that handles the emails for this domain. This is a delegation: it doesn’t point directly to an IP address. Instead it points to another DNS name and it may be a name from completely different domain, managed by completely different organization. Why to do that? In this case administrator of outlook services is free to manage and change the actual IP address of mail service without Tesla ever noticing. Outlook just provides their customers an opaque name they should use. From the MX record it’s obvious that the mail service was delegated to Outlook without going into details. That’s why it can be considered as an abstraction layer.
Now imagine that Outlook migrates their service to some other IP address. They may have a record which they provide to all of their customers. They now need to perform the change in just one place to apply the it for all of them.
But what about anything other than mail? Still possible, with CNAME.
Let’s see how Google uses CNAMEs and how that may be useful:
$ dig www.youtube.com
www.youtube.com. 234 IN CNAME youtube-ui.l.google.com.
youtube-ui.l.google.com. 266 IN A 216.58.215.78
youtube-ui.l.google.com. 266 IN A 216.58.215.110
youtube-ui.l.google.com. 266 IN A 216.58.209.14
youtube-ui.l.google.com. 266 IN A 142.250.203.206
youtube-ui.l.google.com. 266 IN A 216.58.208.206
youtube-ui.l.google.com. 266 IN A 142.250.186.206
youtube-ui.l.google.com. 266 IN A 142.250.203.142
youtube-ui.l.google.com. 266 IN A 172.217.16.14
What happens here? There is this youtube-ui.l.google.com name you will never type in your browser but when
going to www.youtube.com your DNS resolver is directed to this name and, as another step, the actual IP addresses
are resolved.
To understand the usefulness of this see how many addresses Youtube has. There are many country-specific addresses
like www.youtube.ee that also point to youtube-ui.l.google.com. There are some advantages of this pattern
instead of pointing them directly to IP addresses.
When using such pattern you are thinking about the addresses this way:
www.youtube.com, www.youtube.ee are addresses I provide to the public. This is the address users of
Youtube should use to access the site.youtube-ui.l.google.com is an address of a service providing HTTP responses for YouTube and maybe other
auxiliary sites. It’s supposed to be set up by the team responsible for HTTP layer providing public HTTP
services.If the set of IP addresses for all Youtube domains needs to be changed (like a new server is added), you need
to change it just in one place. If there is a separate team responsible for load balancing they may administer
the domain l.google.com for this purpose and not need to contact the teams responsible for public facing
domains.
www.youtube.com. may point to some load balancers but imagine there is urgent need to put a CDN in front of
that. What is the simplest way to do it? Change youtube-ui.l.google.com to point to the CDN service.
My favorite use of CNAME is actually not for public facing names but for addresses of internal services like databases, caches, APIs etc.
Let’s assume a service that uses a database. Its address may be service-db1.company.local. Using this DNS name
instead of 192.168.45.11 is already better because when looking at the service’s configuration it’s way more
readable and obvious what the address points to. But we can do better.
Let’s not use the address of the virtual machine as a database address. Let’s create an address for the
database service that currently happens to be provided by service-db1 host:
service-db.company.local -> service-db1.company.local
What’s the benefit? If you ever need to migrate from service-db1 to a newer, faster service-db2 you don’t
need to change the configuration. If that address is provided in multiple places, the greater is the benefit.
If you can’t remember all the configurations and applications the database address was specified, you are saved
now.
service-db-write.company.local -> service-db1.company.local
service-db-read.company.local -> service-db1.company.local
That will actually require some support from the application. The idea is that if the application needs to
modify the database or needs absolutely up-to-date data, it connects to service-db-write.company.local. If
it only needs to read something and it’s OK that the data is slightly outdated, it connects to service-db-read.company.local.
What’s the benefit? In case you ever need to scale the database by adding a replica, you just point
service-db-read.company.local to this replica. If you need to replace the replica with something faster or
multiple servers - just change on DNS record. Avoid application reconfiguration and restarts.
The most significant benefit is where the team managing the application is not the team managing the databases or even it’s an externally managed service. In such case the DB team can perform changes without even telling the application team about them.
This way of using DNS paid multiple times for me. For example we scaled and evolved MySQL environment in a way transparent to the application first by going from a pair of master and read-only servers to master and set of replicas accessed using ProxySQL (a load balancer for MySQL) and then when ProxySQL became a bottleneck we’ve pointed the replica address to two ProxySQL servers. It was later rewritten to add DNS-based routing with active health checks.The DNS abstraction layer simplified evolution and scaling of our MySQL setup without service interruption and avoided coordination with the software development team.
Once the delegation concept is embraced set of new possibilities is opening such as: DNS based load balancers like Amazon Route 53 or Cloudflare Traffic Manager, service discovery using software like Consul or simple DNS “views” (like in BIND) that allows to vary the response based on who is asking - for example to direct client to the nearest data center.
Probably the best think about implementing rules and logic at DNS level is possibility to have zero latency and infinite scalability thanks to DNS caching close the client but that’s a topic for another article.