dns
etcd
SkyDNS
CoreDNS
More than 1 year has passed since last update.

はじめに

この記事はMicroAd Advent Calendar 2017の6日目の記事です。

サービスディスカバリ兼内部DNSとしてCoreDNSの導入を検証しており、使い方について簡単に纏めてみました。

CoreDNSとは

CNCFのプロジェクトのひとつです。
設定を柔軟に管理できるDNSのソフトウェアになります。
SkyDNSと互換があり、etcdをバックエンドとしたDNSサーバとして動作します。
それ以外にもdnsmasqよろしくhostsファイルをベースに名前解決できたりもして、便利な全部のせDNSって感じです。
ちょうど2017/12/1にv1.0.0がリリースされました。

動かしてみる

では早速動かしてみます。バイナリDLして動かします。

githubのreleaseページにバイナリ置いてあるので適当にDLしてパスを通します。

パスが通っているか確認します。

$ coredns -version
CoreDNS-1.0.0
linux/amd64, go1.9.2, a04eeb9c

ポート1053で起動します。
また、Corefileという設定ファイルを引数で渡します。

$ coredns -conf Corefile -dns.port 1053
Corefile
. {
    whoami
    errors
    log
}

ちなみに、Corefileのファイル形式はMicroAdのアドベントカレンダーで昨日紹介していたCaddyと同じ形式になります。
というのも、CoreDNSの元々の出自がCadddyのDNSプラグインだったからだそうです。

設定ファイルの中身を解説すると、まず先頭のドットはDNSにおけるrootドメインを表しています。
なのでカッコ内部はrootドメイン配下のドメインについての名前解決における設定となります。

そしてwhoami,erros,logsといった設定の羅列ですが、これらはrootドメイン配下で有効化するプラグインのリストになります。
CoreDNSはプラグイン形式をとっており、各ドメインの配下の設定として、どのプラグインを有効化していくか記述していく設定方式をとります。

whoamiプラグインはCoreDNSが動いているローカルIPを返すCoreDNSの動作検証用プラグインです。
errorslogは名前の通りログを出力するプラグインです。

とりあえずこの状態でdigを使って問い合わせすると、何らか応答がかえってきます。

$ dig -p 1053 @localhost  AAAA .

 ~抜粋~
 ;; ADDITIONAL SECTION:
.           0   IN  AAAA    ::1
_udp.           0   IN  SRV 0 0 49745 .

;; Query time: 0 msec
;; SERVER: ::1#1053(::1)
;; WHEN: 火 12月 05 19:19:29 JST 2017
;; MSG SIZE  rcvd: 78

動いているっぽい事が分かります。

リゾルバとして利用する

とりあえず動きました。
とは言っても単にローカルIPだけを返すDNSなんて糞の約にも立たないので、まずはDNSリゾルバとして機能するように設定してみます。
Corefileを以下の内容に編集します。

Corefile
. {
    proxy . 8.8.8.8:53 {
        protocol https_google
    }
    errors
    log
}

Proxyプラグインを使ってDNSリバースプロキシとしての設定を追加しています。
CoreDNSはリバプロの問い合わせ先としてgoogleの提供する https://dns.google.com を設定することができます。

設定変更後はSIGUSR1を送れば設定をリロードしてくれます。

$ pkill -10 coredns

リロードが上手く言ってれば以下のようなログが出ます。

2017/12/05 19:41:11 [INFO] SIGUSR1: Reloading
2017/12/05 19:41:11 [INFO] Reloading
2017/12/05 19:41:12 [INFO] Bootstrapping A records "dns.google.com." found: [216.58.197.174:443]
2017/12/05 19:41:12 [INFO] Reloading complete

では名前解決が可能か確認してみます。

$ dig -p 1053 @localhost A qiita.com +noall +answer
qiita.com.      56  IN  A   54.248.73.175
qiita.com.      56  IN  A   46.51.250.143

リゾルバとして仕事してることが確認できました。

静的なエントリを追加する

dnsmasqっぽくhostsファイルから名前解決してみます。

適当なディレクトリ(例だと/tmp/hosts)に以下のhostsファイルを置きます。

hosts
192.168.1.1 hoge.example
192.168.1.2 hoge.sub.example
192.168.1.3 example.com

Corefileを書き換えます。

Corefile
. {
    proxy . 8.8.8.8:53 {
        protocol https_google
    }
    errors
    log
}


example {
    hosts /tmp/hosts example {
        192.168.1.4 hoge4.example
    }
    errors
    log
}

リロード後、digで確認すると.exampleドメインの名前はローカルのIPで解決できます。

$ dig -p 1053 @localhost A hoge.example +noall +answer
hoge.example.       3600    IN  A   192.168.1.1
$ dig -p 1053 @localhost A hoge.sub.example +noall +answer
hoge.sub.example.   3600    IN  A   192.168.1.2
$ dig -p 1053 @localhost A hoge4.example +noall +answer
hoge4.example.      3600    IN  A   192.168.1.4

hostsプラグインの対象ドメインでは無いexample.comについてはrootドメインの設定に合致してgoogleに名前解決に行き、グローバルに正しいIPが返却されます。

$ dig -p 1053 @localhost A hoge.example.com +noall +answer +autority
example.com.        3695    IN  A   93.184.216.34

動的なエントリを追加する

SkyDNSと互換があり、完全に同じ方法でetcdをバックエンドとした動的なエントリの追加ができます。

この辺はSkyDNSとほぼ同じなのでざっくり行きます。

バックエンドのetcdをコンテナで立てます。

$ docker run -p 2379:2379 -p 2380:2380 quay.io/coreos/etcd:latest /usr/local/bin/etcd \
    --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379

Corefileを書き換えてtestドメインをetcdで管理させます。

Corefile
. {
    proxy . 8.8.8.8:53 {
        protocol https_google
    }
    errors
    log
}

example {
    hosts /tmp/hosts example {
        192.168.1.4 hoge4.example
    }
    errors
    log
}

test {
    etcd test {
        path /skydns
        endpoint http://localhost:2379
    }
    errors
    log
}

etcdctlでデータを突っ込んでdigで確認します。

$ etcdctl set /skydns/test/hoge '{"host":"192.168.1.5","port":8080}'
{"host":"192.168.1.5","port":8080}
$ /tmp/etcd-download-test/etcdctl get /skydns/test/hoge
{"host":"192.168.1.5","port":8080}
$ dig -p 1053 @localhost A hoge.test +noall +answer
hoge.test.      300 IN  A   192.168.1.5

こんな感じで動的にDNSエントリを追加できます。便利!

終わりに

以上、ざっくりとしたCoreDNSの使い方でした。
他のも機能が色々あってもちろん普通のZoneファイルを元にした設定もできますし、Kubernetes連携、というよりkube-dnsの代わりにCoreDNSを使うといった事もできるようです。