はじめまして、IT基盤部所属の林です。
Unbound とは
Unbound とは DNSキャッシュサーバの1つです。あくまでDNSキャッシュサーバですのでDNSコンテンツサーバとしての利用はできません。
公式サイト: http://unbound.net/
日本語サイト: http://unbound.jp/
Unbound 導入による狙い
DNS名前解決自体あまり意識してすることはないと思いますが、外部APIを叩いたりする際には必ずといっていいほど外部APIのDNS名前解決が行われていると思います。
よくあるDNSサーバ構成としては以下のものが多いのではないでしょうか。
上記の構成の場合だと「Web Server」から「Internal DNS Server」へ問い合わせを行いDNSレコードがあればそれを「Web Server」に返します。なければ「Internal DNS Server」が「External DNS Server」へ問い合わせを行う形になると思います。
この構成でも十分サービス運用を行うことは可能ですが「Internal DNS Server」で障害が発生した場合、複数台ある「Web Server」 がDNS名前解決を行う事ができなくなってしまい外部APIへのアクセスなどができなくなってしまいます。
それでも多くの場合「Internal DNS Server」を冗長化していると思いますが「Web Server」の台数に比例してアクセスが集中することに変わりはありません。
アクセスが集中することにより「Internal DNS Server」の負荷が上がり「Web Server」へのDNS名前解決のレスポンス時間も劣化してしまいます。
Unbound を導入する事でアクセスが集中する「Internal DNS Server」を経由せずに名前解決を行う事ができます。
今回の Unbound 導入後の構成は以下のような形になります。
このようにWebアプリケーションと同じサーバに Unbound を配置する事で内部ネットワークの通信量も削減する事ができます。実際に弊社にて導入したある系統のサーバでは Unbound 導入前は UDP session が 3249 qps あったものが 542 qps (83.32% の削減) まで減らす事ができました。
Unbound インストール
では実際に Unbound を「Web Server」にインストールしてみます。CentOS 6.5 x86_64 を対象にします。
unbound の rpm は epel から持ってくる事にします。
これで以下の rpm パッケージがインストールされます。
Unbound 設定
Unbound 自身で名前解決ができるようにルートDNSサーバの root hints ファイルを手元に持ってきます。
/etc/unbound/unbound.conf を修正します。
デフォルトで起動するように chkconfig を設定します。
Unbound 起動とテスト
起動して実際にDNS名前解決をしてみましょう。
無事にDNS名前解決できました。しかし初回DNS名前解決で 1.3 sec もかかってしまってます。これはルートDNSサーバから階層的に構築されているそれぞれのDNS管理サーバに対して探索を行っているため時間がかかってしまっています。
(名前解決したいDNSを管理しているDNS管理サーバに行き着くまでに複数のDNS管理サーバを順に辿っていくためです。)
もう一度試してみると
と一瞬で返ってきました。ではまた 600 sec の TTL(Time To Live) が切れたら遅いのか?というとそんなことはありません。
(TTL に指定されている秒数の間はDNSレコードをキャッシュすることができます。)
2回目はTTLが切れても初回DNS名前解決より格段に早いレスポンスを返しています。
これは Unbound が対象のDNSレコードを管理しているサーバに辿り着くまでに経由したDNSサーバ群のDNSレコードをキャッシュしてくれたために初回DNS名前解決よりも早いレスポンスを返す事ができています。
Webアプリケーションから透過的に Unbound を使う
Unbound にWebアプリケーションからアクセスするには /etc/resolv.conf を修正します。
このように localhost の IP を指定します。これによって Webアプリケーションに手を加える事なく Unbound によるDNS名前解決を行う事ができます。
(注意: /etc/nsswitch.conf の設定によってはうまくいかない場合がありますのでその際は /etc/nsswitch.conf に hosts: files dns と指定してみてください。)
内部zone名のDNSサーバへの問い合わせ
今までの Unbound の設定だと有無を言わさず External DNS Server への問い合わせを行ってしまいますが内部zone名のDNSサーバへ問い合わせを行いたい場合もあるかと思います。
実際、弊社でも内部zone名のDNSサーバへの問い合わせは当たり前のように行っています。
もちろん Unbound では特定の zone に関しての問い合わせ先を変更することができます。
/etc/unbound.conf の設定箇所は以下になります。
この例では「internal.test.local」という zone 名のDNS名前解決の問い合わせ先を「10.1.2.3@53」、「10.4.5.6@53」に行うといった内容になっています。
こうすることによって Unbound は foo.internal.test.local といったDNS問い合わせを External DNS Server に対しては行わず「10.1.2.3@53」 or 「10.4.5.6@53」に対して行うようになります。
ちなみに問い合わせ先が複数指定されている場合は ランダムに round robin で分散されます。
Unbound のメリットとしてこの「問い合わせ先(stub-addr)」に指定できる数がほぼ無制限に指定できます。
(ほぼ無制限と書きましたがコードを読む限りはメモリが空いている限りは指定できます。)
/etc/resolv.conf にも nameserver は複数指定できますが resolv.conf には nameserver を3つまでしか指定できません。
Unbound を使う事でこういったメリットも享受する事ができます。
内部zone名のDNSサーバ指定時の注意
上記で内部zone名のDNSサーバの問い合わせ方法を示しましたがここで1つ注意すべき事があります。
Unbound を導入することで内部zone名のDNS名前解決コストも抑えられるのですが TTL が長すぎると名前解決間隔が長くなってしまいます。
そうすると DB へのアクセスを名前解決によって行っていた場合、DBサーバを1台切り離す際に TTL が切れるまでが長くなかなか切り離す事ができなくなってしまいます。
運用において切り離しを行う場合は問題ないですがDBサーバが障害で落ちてしまった場合、できるだけ早く切り離したいのになかなか切り離してくれなくなってしまいます。
内部zone名のDNSサーバ指定時には適切な TTL 設定を行うように注意が必要です。
まとめ
今回はDNSキャッシュサーバの Unbound について書いてみました。
普段、なかなか意識する事のないDNS名前解決ですが、APIやWebサイトにアクセスする際の一番始めの処理なだけに実はすごい重要な部分だなと個人的には思っています。
例えば自社で提供しているサービスになかなかアクセスこないなと思っていたら、実はDNSサーバが落ちていたなんて事になっていたら非常に悲しすぎます。
今回の記事で設定方法など書いてある通り非常に導入の敷居は低いと思います。
耐障害性も向上する上、Webアプリケーションのプロセス内でDNSキャッシュするなどの煩わしい実装も必要なく、Webアプリケーションのプロセス間でのDNSキャッシュの共有も Unbound に任せてしまえます。
また弊社内で多く利用している実績もあり非常に動作は安定しています。
(あるサーバでは 1000 qps 以上を安定して捌いており今まで Unbound が落ちた事は一度もありません。)
これを機に是非 Unbound の導入を検討してみてはいかがでしょうか?