【Consul】dnsmasqで名前解決を行う方法を試してみた

【Consul】dnsmasqで名前解決を行う方法を試してみた はてなブックマーク - 【Consul】dnsmasqで名前解決を行う方法を試してみた


Twitter を眺めていると、Consul の名前解決に Dnsmasq を使う方法が紹介され、興味を。

Consul, DNS and Dnsmasq – Morethanseven
http://www.morethanseven.net/2014/04/25/consul/

対象記事は、Ubuntu 向けでしたので、ここは自分で、RHEL/CentOS6 の環境でも同様に動作するかどうか、確認してみました。

■ 作業の目的

Consul には DNS インターフェースが標準で提供されています。そのため、dig で Consul サーバのポート 8600 に対して名前解決を問い合わせると、指定したノード名やサービス名に該当する IP アドレスを返すことができます。

例えば、Consul サーバの IP アドレス’192.168.39.5′ に対し、’web’ という名前のサービスを問い合わせる場合は、次のようになります。

# dig @192.168.39.5 -p 8600 web.service.consul

結果として、A レコードが帰ってきます。

;; ANSWER SECTION:
web.service.consul.     0       IN      A       192.168.39.5

単純な名前解決を dig で行う場合であれば、このように DNS 問い合わせ先を明示することが出来ます。しかし、一般的なアプリケーションやプログラムでは、都度問い合わせを行うのは面倒です。そこで dnsmasq を使い、dig を使わなくても( curl や ping 等のプログラムが )名前解決を出来る方法を試みます。

なお、確認作業は CentOS 6 上で行っています。

また、条件として、次のような環境を想定しました。

  • Consul サーバ派、同一ネットワーク上の別サーバ ( 192.168.39.5 ) で動作している
  • Dnsmasq は、問い合わせを行うローカルのサーバ自身で設定する。
  • /etc/resolv.conf では、名前解決に外部の DNS ( 8.8.8.8 ) も使用する。

■ 検証

まずはじめに、Dnsmasq がセットアップされていない場合は、パッケージを入れます。

# yum install dnsmasq

次に、設定ファイルを編集します。ここでは、Consul の DNS サーバが「192.168.39.5」の「ポート 8600」としていますが、IP アドレスやポート番号は、環境に合わせて適時書き換えます。

# cp -p /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
# echo "server=/consul/192.168.39.5#8600" >> /etc/dnsmasq.conf

このとき、/etc/resolv.conf の名前解決をローカル (127.0.0.1) で行う場合でなく、外部の DNS サーバに設定している時は、/etc/resolf.conf の順番を書き直す必要があります。具体的には、127.0.0.1 のエントリの次に、外部サーバのエントリを記述します。

nameserver 127.0.0.1
nameserver 8.8.8.8

更に、/etc/dnsmasq.conf には、以下の行を追加します(あるいは、コメントを削除して有効化しても構いません)。

strict-order

この設定を行う事で、/etc/resolv.conf の参照は上から順番に行われます。まず、127.0.0.1 (自分自身)に問い合わせを行い、「consul.」ドメインの場合は、dnsmasq.conf で指定した 192.168.39.5 に問い合わせを行いますが、その他のドメインは 8.8.8.8 に問い合わせをします。

あとは、必要に応じてブート時の自動起動設定を有効にします。

# chkconfig dnsmasq on

最後に dnsmasq を起動します。

# service dnsmasq start
Starting dnsmasq:                                          [  OK  ]

これで準備は完了しました。

■ 動作確認

dig を使って、127.0.0.1 を明示した状態でテストします。

$ dig @127.0.0.1 web.service.consul

これで問題なく A レコードが帰ってくるようであれば、@ を外して dig を実行します。

$ dig web.service.consul

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.el6_5.1 <<>> web.service.consul
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43144
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;web.service.consul.            IN      A

;; ANSWER SECTION:
web.service.consul.     0       IN      A       192.168.39.5

このように、Consul サーバを意識することなく、普通に名前解決できることがわかります。

あとは、ping 等のツールで動作確認も可能です。

$ ping  web.service.consul
PING web.service.consul (192.168.39.5) 56(84) bytes of data.
64 bytes from web1.local (192.168.39.5): icmp_seq=1 ttl=64 time=0.371 ms
64 bytes from web1.local (192.168.39.5): icmp_seq=2 ttl=64 time=1.09 ms
64 bytes from web1.local (192.168.39.5): icmp_seq=3 ttl=64 time=0.277 ms
64 bytes from web1.local (192.168.39.5): icmp_seq=4 ttl=64 time=0.291 ms
64 bytes from web1.local (192.168.39.5): icmp_seq=5 ttl=64 time=0.269 ms

このように、dnsmasq を使えば、Consul と連携したアプリケーションやシステムでなくても、Consul ノードや Consul 上のサービスに関する名前解決が可能です。