DNSラウンドロビン
1つのホスト名に、複数のサーバのIPアドレスを登録しておき、問合せのたびに返す順番を変えることで、アクセスを複数のサーバに振り分ける方法。専用の負荷分散装置がいらないが、故障したサーバにも振り分けてしまう。
イマシルちゃんの解説
DNSラウンドロビンは、名前からIPアドレスを調べるDNSを使って、アクセスを複数のサーバへ分ける負荷分散の方法だよ。
同じWebサイトを提供できる複数のサーバのIPアドレスを、一つのホスト名に登録しておくんだ。
問い合わせへの応答では、そのアドレスを並べる順番を変えるよ。
利用者側が先頭のアドレスを選べば、接続先が分かれるんだ。
専用の負荷分散装置を置かずに始められるのが利点だよ。
ただし過去の応答を再利用できるキャッシュなどの影響で、均等に分かれるとは限らないんだ。
この解説はわかりやすかったですか?
より深い解説
一つの名前から複数の接続先を返す
DNSラウンドロビンでは、同じホスト名に複数のIPアドレスを登録し、応答する順番を変えて接続先を分散させる。IPv4アドレスにはAレコード、IPv6アドレスにはAAAAレコードを使う。登録内容を管理して応答するのは権威DNSサーバである。
同じ名前・種類・クラスのレコードの集まりをRRsetという。独自の例として、同じ役割を持つ二つのプロキシを一つの名前で利用するため、次の二つのAレコードを登録する。
proxy.example. 120 IN A 192.0.2.21
proxy.example. 120 IN A 192.0.2.22
120は、キャッシュとして情報を再利用できる期間を秒で示すTTLである。各サーバを区別するIPアドレスを、共通の名前へ対応させている。二つのサーバが同じIPアドレスを共有する設定ではない。
例えば応答内の並びを「192.0.2.21 → 192.0.2.22」から逆順へ変えると、先頭のアドレスを選ぶ利用者の接続先を分けられる。ただし、返す順序の決め方はDNSサーバの実装・設定に依存し、受け取った側がアドレスを並べ替える場合もある。必ず先頭へ接続するというDNS共通の規則ではない。
利点は、通信を中継する負荷分散装置を置かず、離れた場所のサーバも接続候補にできることである。 Webサーバだけでなく、同じサービスを提供するプロキシなどにも利用できる。
名前解決の回数と通信量は一致しない
端末からの問い合わせを代行するフルサービスリゾルバは、得られた応答をキャッシュする。キャッシュを使える間は、権威DNSサーバへ毎回問い合わせ直す必要がない。複数の利用者が同じ保存情報を使うと、接続先が偏ることがある。
また、一度接続した利用者が同じTCP接続を使い続ければ、その通信は選ばれたサーバへ届き続ける。一つの接続が運ぶデータ量も利用者ごとに異なる。
したがって、応答内の順番を変えること、接続数が分かれること、通信量が均等になることは同じではない。 単純なDNSラウンドロビンは、各サーバの現在の負荷を測定して最も空いているサーバへ要求を送る方式ではない。
個別のサーバを監視して登録内容へ反映する
弱点:単純に複数のアドレスを登録するだけでは、故障したサーバも接続候補に残る。 異常な候補を外すには、各サーバの死活監視と、DNSの登録内容を変更する処理を別途組み合わせる。
監視元が共通の名前proxy.exampleだけを使うと、正常な方へ接続して、もう一方の停止を見逃す可能性がある。サーバごとのIPアドレスや個別のホスト名を使い、どちらを調べた結果かを明確にする。
プロキシのアプリケーションプロセスが停止しても、OSが動いていればpingに応答する場合がある。必要なプロキシ機能まで確認するには、検出したい障害に合うヘルスチェックを選ぶ。監視する層や応答内容の決め方は、死活監視の記事で扱う。
DNSを更新した後も、利用者側に古い応答が残る点には注意が必要である。異常の検出と、すべての利用者が別の接続先を使うまでの時間を分けて考える。
登録変更が接続先へ反映されるまで
権威DNSサーバから192.0.2.21のレコードを削除しても、各地のフルサービスリゾルバへキャッシュの削除命令が送られるわけではない。既に受け取った応答は、通常はその応答のTTLに従って再利用される。
次の例では、キャッシュは期限まで利用し、期限切れの次の問い合わせで最新の情報を取得するものとする。端末側の追加のキャッシュや、期限切れの情報を例外的に利用する機能は省略している。
| 時刻 | 起きること | 名前解決への影響 |
|---|---|---|
| 0秒 | リゾルバが二つのアドレスを120秒の有効期間で受け取る | 両方が接続候補になる |
| 30秒 | 192.0.2.21のサービスが停止する | DNSの登録内容はまだ変わらない |
| 40秒 | 監視結果に基づいて192.0.2.21を登録から外す | 新しい情報を取得したリゾルバには192.0.2.22だけが返る |
| 80秒 | 最初のリゾルバへ問い合わせる | 古い応答が有効なので、192.0.2.21を含む情報が返り得る |
| 120秒以降 | 期限切れ後の問い合わせで再取得する | 更新後の候補を利用できる |
TTLを短くすれば、古い情報を再利用する期間を抑えやすい。一方で、問い合わせの頻度が上がり、DNSサーバの負荷が増える場合がある。値を小さくするだけで、障害検出や端末の再試行まで速くなるわけではない。
計画的な切替えでは、元の長いTTLで保存された情報が残らないように、事前に値を下げてから十分な時間を置く。変更時に新しい値を設定しても、すでに配布された古い応答の残り時間をさかのぼって短縮することはできない。
接続先の選び直しと既存の通信を分ける
DNSの登録変更は、すでに確立したTCP接続を別サーバへ移動させない。接続が失敗した後に、アプリケーションが別アドレスへの再試行や名前の再解決を行い、新しい接続を作る必要がある。再試行の順序や回数は利用するソフトウェアによって異なる。
同じ利用者が次回も同じサーバへ接続するセッション維持も、DNSラウンドロビン単体では保証できない。ログイン状態などを各サーバのメモリだけで保持する構成では、別サーバへ接続した後も業務を続けられるかを確認する。
| 方法 | 接続先を選ぶ場所と特徴 |
|---|---|
| 単純なDNSラウンドロビン | 名前解決で複数候補を返す。監視や候補からの除外は別に用意する |
| ロードバランサ | 通信を受けて処理先を選ぶ。設定に応じてヘルスチェックやセッション維持を利用できる |
| PACファイルの複数候補 | 対応するアプリケーションがプロキシの候補を持ち、失敗時に次の候補を試す |
必要な切替え時間、対応する利用ソフトウェア、通信量、状態の引継ぎから方式を選ぶ。名前解決の仕組みだけで、アプリケーション全体の可用性が決まるわけではない。
管理データの保護は別に設定する
DNSラウンドロビンは負荷分散の方法であり、ゾーン情報の読み出しを制限する機能ではない。ゾーン転送の許可先をセカンダリDNSサーバなど必要な相手に限定する設定は、権威DNSサーバ側で別に管理する。
参考資料
- RFC 1035:レコードの形式とキャッシュの有効期間
- RFC 2181:同じ名前・種類・クラスのレコードの扱い
- ISC BIND:応答するレコードの順序とキャッシュによる制約
- RFC 8767:情報を更新できない場合に期限切れデータを使う例外