Create a DNS in a cloud

The previous post, “Are meaningful server names just for tradition in a cloud?”, talked about how Enterprises want to use server naming conventions. What happens, however, when a cloud service provider uses its own scheme, typically hard-to-remember unique? This post will talk about one possible solution, creating an alternative DNS-in-a-cloud.

Let us assume that we want a naming convention with hostnames like:

zeus.cloud.mydomain.com

but our cloud provider uses a scheme like this:

zeus.longuniquetag.compute.cloud.mydomain.com

If we create a DNS-in-a-cloud, which names servers using a scheme that we choose, cloud instances can be redirected to use it. This post will discuss how to create a DNS in a cloud.

Note that the solution in this post is for OpenStack clouds. OpenStack does the heavy lifting when it comes to managing and keeping track of all instances. The DNS in the cloud only needs to poll the OpenStack management APIs and provide hostnames for each instance. The general principles in this post should be able to be leveraged in other types of clouds.

OpenStack’s Designate Project

In the future, OpenStack clouds will likely solve the server name problem using Designate, a DNS-as-a-service project that is still in incubation stage. Designate seems to be a rather critical project. One good quote I’ve seen is in a blog titled “OpenStack Designate Brings DNS as a Service Into Incubation” by Sean Michael Kerner. Sean writes “DNS is a critical network service and without it, I really don’t understand how OpenStack service providers could possibly properly scale a business. If DNS isn’t inside OpenStack it’s outside of it, with a more manual and more painful, less ‘cloudy’ approach.” While we wait for Designate to bring more cloudy DNS services to private clouds, one can implement a DNS-in-a-cloud like in this post.

Overview of a DNS-in-a-Cloud

To show it is possible to have cloud instances a desired naming convention even when the cloud service provider uses a different one, I created a basic DNS-in-a-Cloud. My example solution is posted on github at https://github.com/douglin/cloud_ddns. The coding portion is mostly in Python, which I chose because OpenStack is coded in Python. Note that I only program as a hobby now and am new to Python. So if you have any coding tips, feel free to let me know.

What is posted on GitHub could be used without knowing all of the details about how it works. Just follow the instructions in the readme. After deploying an instance for the DNS and installing all the pre-requiste packages, there are just a few steps to setup the DNS-in-a-cloud.

  1. Edit ddns_config.yaml, a configuration file and enter in the desired DNS settings, including domain name of your choice, e.g. cloud.myuniverse.org
  2. Run setup_ddns.sh
  3. Run ddns.sh

Most of the work is to edit the ddns_config.yaml contents. If we wanted instances to resolve to something like zeus.cloud.myuniverse.org, we could edit the contents of ddns_config.yaml to look like:

Sample ddns_config.yaml

domain_name: cloud.myuniverse.org
dns_shortname: bigbang
dns_fixed_ip: 10.130.52.121
dns_floating_ip: 10.130.56.248
forwarders:
- 10.130.0.1
ip_ranges:
- 10.130.52.0/24
- 10.130.56.0/24

Note that this solution has been designed for Centos/RHEL 6.5.

How it Works

Some might want to understand how this solution works, perhaps to enhance or customize the solution. For example, instead of creating a DNS for instances in all OpenStack projects/tenants, perhaps one wants to just create an DNS for instances in one project. That would require changing the a line of code in ddns.py from

for server in nova.servers.list(search_opts={'all_tenants': 1}):

to

for server in nova.servers.list():

Many modifications can also be made by editing the template files like “template.named.conf.” This solution is built with BIND, a widely used DNS commonly used with Unix systems.

We can create a DNS in the cloud and transition from the scenario in Figure 1 to the one in Figure 2, where instances point to a new DNS. It is also possible to have subsets of instances point to different DNS servers.

Figure 1. All Instances Point to the Cloud Service Provider's Default DNS

Figure 1. All Instances Point to the Cloud Service Provider’s Default DNS

 

Figure 2. Instances Point to an Alternative DNS-in-the-Cloud

Figure 2. Instances Point to an Alternative DNS-in-the-Cloud

 

At a high level, the DNS-in-a-cloud has these main components.

  1. A instance in the cloud (based on Centos/RHEL 6.5)
  2. BIND DNS packages
  3. Scripts that integrate OpenStack with the DNS
Figure 4. Components of the DNS-in-a-Cloud

Figure 4. Components of the DNS-in-a-Cloud

 

The key tools we will use to integrate OpenStack with the BIND DNS are (1) OpenStack’s Nova API and (2) BIND’s nsupdate utility. Nova is OpenStack’s compute service. The nsupdate utility enables us to add or delete any type of DNS record.

Here is psuedo code that outlines, at a high level, the main logic in the scripts.

for servers in my_cloud:
    if server_deleted_from_the_cloud:
        add_nsupdate_delete_record
    if server_added_to_the_cloud:
        add_nsupdate_add_record

The actual logic in ddns.py creates multiple input files for nsupdate. A script, ddns.sh, calls both calls ddns.py and executes nsupdate. ddns.sh is generated during setup, e.g. running setup_ddns.sh.

Below are some of the core methods used in the solution, whose details can be read in github.

  • Dynamic creation of BIND files, e.g. named.conf and all forward and reverse zone files, using templates – see gen_bind_files.py
  • Check if a hostname is valid – see ddns_common.py
  • Given an instance’s IP address, get the associated reverse network and DNS – see ddns.py

Connecting and Instance

Once the DNS-in-the-Cloud is setup, one can point instances to it. To direct a Centos/Red Hat instance to it, edit the “/etc/resolv.conf” file with the desired search domain and IP address of the new DNS server. Creation of the new DNS server will be explained later.

search <domain_name>
nameserver <nameserver_ip>

To ensure that “etc/resolv.conf” is not overwritten during a reboot, add a line to the instance’s network configuration file, e.g. “/etc/sysconfig/network-scripts/ifcfg-eth0”. For example, type:

echo "PEERDNS=no" >> /etc/sysconfig/network-scripts/ifcfg-eth0

Test the DNS server using tools like ping, dig and/or nslookup. For example, assuming there is an instance called “chef”, one could do try something like the following to test that the desired server naming scheme is working.

[centos@ddns ~]$ ping chef
PING chef.cloud.myuniverse.org (10.130.56.191) 56(84) bytes of data.
64 bytes from chef.cloud.myuniverse.org (10.130.56.191): icmp_seq=1 ttl=62 time=1.47 ms
…
[centos@ddns ~]$ nslookup 10.130.56.191
Server:      10.130.52.121
Address:     10.130.52.121#53
191.56.130.10.in-addr.arpa name = chef.cloud.myuniverse.org.

Conclusion

Network technologist wield a lot of influence. After all, we need network connectivity to access a cloud. It is no surprise, then, that one of the most common requests enterprises have is that a private cloud solution match their existing hostname convention. I wrote this solution as an experiment to validate that one could use a server name convention even if when a cloud service provider defaults to a different one. As enterprises migrate existing IT to a cloud model, some may want to implement solutions like this DNS-in-a-cloud.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s