PowerDNS + BIND で DNS を構築する

スポンサーリンク

以前の記事で、master に PowerDNS、slave に NSD を用いた DNS クラスタを構築した。

その後4万ゾーン程突っ込んで検証したところ、この構成では master の PowerDNS に負荷がかかることがわかった。

そこで今回は slave に BIND を使ってみる。

スポンサーリンク

要件と構成

前回とほぼ同じ。NSD を BIND に置き換える。

構成図

構成図

構築

今回も OS は Ubuntu 12.04.4 を使う。master の PowerDNS の構築手順は前回と同じなので省略し、slave の BIND のみ記す。

必要なパッケージを入れる。

# apt-get install -y bind9 daemontools

設定ファイルを編集し、ゾーンの動的変更を有効にする。

# diff -u /etc/bind/named.conf.options.orig /etc/bind/named.conf.options
--- /etc/bind/named.conf.options.orig   2014-05-18 19:26:00.742308000 +0900
+++ /etc/bind/named.conf.options        2014-05-18 19:25:48.478308000 +0900
@@ -14,6 +14,9 @@
        //      0.0.0.0;
        // };

+       recursion no;
+       allow-new-zones yes;
+
        //========================================================================
        // If BIND logs error messages about the root key being expired,
        // you will need to update your keys.  See https://www.isc.org/bind-keys

リロードする。

# service bind9 reload

ゾーンファイルを生成するためのディレクトリを用意する。

# mkdir /var/cache/bind/slave
# chown bind /var/cache/bind/slave

同期スクリプトを作成する。名前は前回と同じ /root/zone_sync/zone_sync.sh とする。

#!/bin/sh

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

MASTER_HOST=(master の IP アドレス)
MASTER_USER=ubuntu

set -e

DIR=$(cd $(dirname $0); pwd)
cd $DIR

scp -p $MASTER_USER@$MASTER_HOST:zone_sync/master_zones.txt .
cat /var/cache/bind/3bf305731dd26307.nzf | awk '{print $2}' | sort > slave_zones.txt

for i in $(diff master_zones.txt slave_zones.txt | grep '^<' | awk '{print $2}'); do
    rndc addzone $i "{type slave; file \"slave/$i.db\"; masters {$MASTER_HOST;};};" || :
done

for i in $(diff master_zones.txt slave_zones.txt | grep '^>' | awk '{print $2}'); do
    rndc delzone $i || :
done

あとは前回の記事と同様に、slave の ssh の公開鍵を master に登録し、crontab にスクリプトを登録する。

気づいたこと

検証中に気づいたことや調べたことをまとめておく。

NOTIFY について

master の PowerDNS は、次の条件で slave に NOTIFY を送信する。

  • 当該ゾーンの domains.type"MASTER" のとき
  • NS レコードに列挙されている全てのホスト宛に

そして slave の BIND は、次の条件で master からの NOTIFY を受け入れる。

  • 自身が当該ゾーンの NS レコードに含まれているとき

そうでない場合、also-notify で設定する必要がある。

ゾーンの制約

NSD のときは問題なかったが、BIND では次のような制約があるようだ。

  • 名前に / が含まれるゾーンは動的追加できない
  • NS レコードを持たないゾーンは転送できない

前者は /24 未満の逆引きゾーンで使われることがあるので、困るかも知れない。後者のようなゾーンは存在しないはずなので、問題になることはないだろう。

おわりに

PowerDNS と BIND を用いて DNS クラスタを組み、4万レコード程を投入して動作を確認した。タイミングによっては slave 側に refresh のキューが溜まっており、NOTIFY を受け取ってから同期を開始するまでに十数分程度かかることがあった。この遅延が許容できない場合には、別の同期方法を考える必要があるだろう。

また、今後は master にゾーンを追加、削除した時に、rndc などを用いて slave にもリアルタイムに反映するような仕組みを検討したい。

(前者はレコードの変更の話で、後者はゾーンリストの変更の話)

参考ページ

コメント

タイトルとURLをコピーしました