SkyDNS version 1 was announced some time ago, since then it has seen some developments, which resulted in SkyDNS version 2. This new version uses Etcd as its backend. This blog post will walk you through the installation and shows how to use it.

What?!

SkyDNS(2) is a service discovery tool that utilizes the DNS to find hosts in a distributed environment. But using DNS means “legacy” clients can be used. Want to know if you MariaDB cluster is still up? ping mariadb.skydns.local can be used for that. By default SkyDNS will use skydns.local. as the domain to anchor all names.

Installation

If not already installed, install Go for your system, either via the package manager or from source. After that you will need Etcd and SkyDNS:

  • go get github.com/coreos/etcd
  • go get github.com/skynetservices/skydns

After the installation, start Etcd: ./etcd. This will run a lonely, non clusterized Etcd on port 4001 on your local machine. SkyDNS has the ability to use configuration stored in Etcd, but for now we use the command line flags to start SkyDNS:

% ./skydns -addr=127.0.0.1:1054 -machines=http://127.0.0.1:4001 \
    -nameservers=8.8.4.4:53
[skydns] Jun  8 08:30:19.761 INFO      | ready for queries

Let’s see if it works, by using dig:

% dig @127.0.0.1 -p 1054 +noall +answer +add SOA skydns.local
skydns.local. 3600 IN SOA ns1.dns.skydns.local. hostmaster.skydns.local. (
                1402210800 ; serial
                28800      ; refresh (8 hours)
                7200       ; retry (2 hours)
                604800     ; expire (1 week)
                60         ; minimum (1 minute)
                )

Somebody is answering! Note in the other examples, I will use the same command line for, but remove all the flags and options. If a query aimed at SkyDNS does not fall under skydns.local. it will forward it to 8.8.4.4 and returns the answer from that:

% dig a miek.nl
miek.nl.        19827 IN A 176.58.119.54

With this you can configure SkyDNS as your nameserver in /etc/resolv.conf.

Services

The original SkyDNS used a fix naming scheme, environment.service.version.region.skydns.local., SkyDNS2 does away with this, but still it makes sense to defines some scheme to be used in your environment. In this blog post I will use a very simple scheme that only uses a region, like “east”, “west”, etc.

Let register a service in Etcd, we want the register the name ‘web01.east.skydns.local’, which listens on port 80 and has an IP4 address of 10.0.1.3. All names used by SkyDNS in Etcd are stored under /skydns/ and we need to reverse the domain name. So to register the name we need to use the key: /v2/keys/skydns/local/skydns/east/web01, the payload of it must be JSON like so:

% curl -XPUT http://127.0.0.1:4001/v2/keys/skydns/local/skydns/east/web01 \
    -d value='{"Port":80,"Host": "10.0.1.3"}'

And retrieving it via DNS:

% dig A web01.east.skydns.local
web01.east.skydns.local. 3600 IN A 10.0.1.3

Now we also add another webservice in the east region, web02.east.skydns.local, with IP4 address of 10.0.1.4.

Now suppose you want to have a list of all webservers in the east region? Simple just query for east.skydns.local:

% dig A east.skydns.local
east.skydns.local.  3600 IN A 10.0.1.4
east.skydns.local.  3600 IN A 10.0.1.3

Of course IP6 is also supported. Using A and AAAA records allows for “legacy” support, however the port number must be know by the client connection, because that information is not in the returned records. To fix this you can also query for SRV records.

SRV Records

SRV records return much more information than A/AAAA records, it includes a port number, a priority a weight and a name (not an address record). As the service information for web01 only includes an address, SkyDNS will synthesise the SRV record and includes the actual IP address in the additional section:

% dig SRV web01.east.skydns.local
web01.east.skydns.local. 3600 IN SRV 10 100 80 web01.east.skydns.local.
web01.east.skydns.local. 3600 IN A 10.0.1.3

The numbers “10”, “100” and “80” in the SRV records are respectively:

  • 10: priority.
  • 20: weight (when multiple SRV records have the same priority, look at the weight). In SkyDNS weight is a percentage.
  • 80: the port number for the service, if the port is not given in the service, it defaults to 0.

Of course this all works when you query for east.skydns.local as well.

Wildcards

The DNS standards supports wildcards, but SkyDNS extends this usage to allow wildcards within a domainname. To show how this we add another service, this time web01.west.skydns.local. Suppose we want to target all web01 servers? With plain DNS you will need to do two queries (and know about west and east!), with SkyDNS only one is needed:

% dig web01.*.skydns.local
web01.*.skydns.local.   3600    IN  SRV 10 50 80 web01.east.skydns.local.
web01.*.skydns.local.   3600    IN  SRV 10 50 80 web01.west.skydns.local.
web01.east.skydns.local. 3600   IN  A   10.0.1.3
web01.west.skydns.local. 3600   IN  A   10.0.2.1

DNSSEC

Signed responses are also supported, although authenticated denial of existence based on NSEC3 is a work in progress. A quick primer on how to enable it, as there are a few steps.

  1. Generate a DNSSEC keypair for SkyDNS:

     % dnssec-keygen skydns.local
     Generating key pair........................................++++++ .....++++++ 
     Kskydns.local.+005+04821
    
  2. Use the basename of the generated key pair as an argument to SkyDNS:

     % ./skydns -addr=127.0.0.1:1054 -machines=http://127.0.0.1:4001 \
         -nameservers=8.8.4.4:53 -dnssec Kskydns.local.+005+04821
     [skydns] Jun  8 12:28:37.981 INFO      | ready for queries, signing with Kskydns.local.+005+04821
    

When you know query with the DO bit on (+dnssec in dig) you will get signed responses:

% dig +dnssec web01.*.skydns.local
web01.*.skydns.local.   3600 IN SRV 10 50 80 web01.east.skydns.local.
web01.*.skydns.local.   3600 IN SRV 10 50 80 web01.west.skydns.local.
web01.*.skydns.local.   3600 IN RRSIG SRV 5 4 3600 (
                     20140615113057 20140608083057 4821 skydns.local.
                     DWNzcR9DqNHrITZPN/sfGUH42Ur+GQXSQu95O4eouY0a
                     8uupN8pa75IA/inJ6tnN7cTW5XGbe6AKLB90GrxEIiHt
                     dxogqzCNaCt/Z4bj8BY8ZMLC5IXX2+L6hnLYlCv6Q/jJ
                     4ixafFhbJSD+Rc4eK764Rberhik/zUtuXDe8kXM= )
web01.east.skydns.local. 3600 IN A 10.0.1.3
web01.west.skydns.local. 3600 IN A 10.0.2.1
web01.east.skydns.local. 3600 IN RRSIG A 5 4 3600 (
                     20140615113057 20140608083057 4821 skydns.local.
                     X9uu3yw2aPUJaJu0q0I0cEyJHAcvpqd1bDhAFEM0uHkr
                     yWQzm+i0VK6HEawK+hgtenfkJb1DtqIUdsEQ7+Kz1elV
                     EC+w/W7p+bXL29BTuJOu722H8tXo21I9lr+SoIoIDsKG
                     BfPkVwACwBAWaPJWrxy90v43NXdSunl55eUVoP4= )
web01.west.skydns.local. 3600 IN RRSIG A 5 4 3600 (
                     20140615113057 20140608083057 4821 skydns.local.
                     RNacRPSW6hxhtze6sV6LafcOIuqMex1TBVo6FbI1pkXV
                     ZVz3Bm+xWuo7QUP74I8r7j5y8cPUpRNRMOO6StAr73Wy
                     GGgb7HExUSHTKU03xHAwnAvKbcTlXkJcSHmxBrY+/yE+
                     HkbwFHe4Y9qNTF4ygvU0BtObbJ3+e0hW8wr6YIU= )

The signatures are cached, so this does not turn into an easy DDoS at once.

Other responses you expect from a DNS server are supported, like SOA, NS, TXT, etc.