新規のお客様新規アカウントで DNS と CDN の無料プランをご利用いただけます。アカウント作成

DNS がゾーンのネームサーバーを選ぶ仕組み

Yeap DNS でホストする各ゾーンには、2つのネームサーバーが割り当てられます。その組み合わせには、安定性、分散、実際に応答できることが求められます。ハッシュベースの割り当ての仕組みと、「ステータスは意図、ハートビートは事実」である理由を解説します。

Yeap DNS にドメインを追加すると、コンソールに2つのネームサーバー(NS)が表示されます。これらをレジストラで設定すると、ドメインが Yeap に委任されます。一見単純な手順ですが、その裏側では複数の要件を同時に満たす必要があります。この記事では、この2つのネームサーバーをどのように選んでいるかをご紹介します。

3つの要件

  1. 安定していること。 ネームサーバーは、レジストラと TLD レジストリの委任レコードに登録されます。あるゾーンに今日 A と B が割り当てられ、明日 C と D に変わるようでは、レジストラの設定を何度も変更する必要があり、その間に名前解決ができなくなるおそれがあります。あるゾーンに対する選択結果は、決定的でなければなりません。
  2. 分散していること。 すべてのゾーンに同じ組み合わせを割り当てると、少数のノードに負荷が集中し、1つのネームサーバーの障害が全員に影響します。ゾーンごとに異なる組み合わせを割り当てるべきです。
  3. 実際に応答できること。 割り当てたネームサーバーの背後には、稼働中のノードが必要です。稼働ノードのないネームサーバーにゾーンを委任すると、クエリを送っても応答が返りません。

プールモデル

多くのホステッド DNS サービスと同様に、私たちのモデルは3つの層で構成されています。

  • プール:ネームサーバーの集合です。各プランは1つのプールを参照し、無料プランと有料プランでは別々のプールを使用します。
  • ネームサーバー:プール内の各エントリは1つの NS ホスト名です。最終的にレジストラで入力する名前にあたります。
  • ノード:権威 DNS サービスを実際に実行するマシンです。1つのネームサーバーを複数のノードで配信でき、グルーレコードはそれらのノードのアドレスを参照します。

ゾーンへのネームサーバーの割り当てとは、そのゾーンのプランに紐づくプールから、2つのネームサーバーを選ぶことです。

安定したランダム性:ゾーンをシードにしたハッシュによる並べ替え

安定性と分散を両立するために、基本的には Highest Random Weight ハッシュ法(ランデブーハッシュ法、HRW)にあたる、古典的な手法を使用しています。

  1. プール内の各ネームサーバーについて、hash(zoneName + ":" + nameserverId) を計算します。
  2. そのハッシュで並べ替えます。同値の場合は ID で順序を決めるため、常に決定的な順序になります。
  3. 先頭の2つを選択します。
function pickNameservers(pool, zoneName, count = 2):
    if len(pool) <= count:
        return pool
    sort pool by (crc32(zoneName + ":" + ns.id), ns.id)
    return first count items of pool

この方法には、次のような利点があります。

  • 決定的である:入力はゾーン名とプールの内容だけです。同じゾーンなら何度計算しても同じ結果になり、乱数の状態や割り当て時点の負荷には依存しません。
  • 均等に分散する:ゾーンごとに、ランダムに見える異なる並び順が得られるため、全体としてプール内のネームサーバーの組み合わせに均等に分散します。
  • 拡張時の影響範囲が小さい:プールにネームサーバーを追加しても、結果が変わるのは、新しいサーバーが上位2つに入るゾーンだけです。それ以外のゾーンの結果は変わりません。これが、単純な剰余によるハッシュ法に対する HRW の主な利点です。

なお、選択結果はゾーンの作成時に保存されます。後からプールを変更しても、既存ゾーンのネームサーバーが自動的に変わることはありません。そのため、私たちが処理能力を増強しても、お客様の委任先は変わりません。決定性が特に役立つのは、どの経路でゾーンを作成しても、同じ割り当て処理を通り、同じ結果が得られる点です。コンソール、API、プラン購入後の自動プロビジョニングのいずれでも同様です。

シードとして使用できるゾーン名がない場合(一部のまれな内部処理経路)には、「ホストしているゾーン数が少ない順」という、決定的な負荷分散方式にフォールバックします。

ステータスは意図、ハートビートは事実

並べ替えの前に、より重要なステップがあります。どのネームサーバーを候補プールに含めてよいかを決めることです。私たちは、こうしたネームサーバーを応答可能と呼んでいます。次の条件をすべて満たす必要があります。

  • ネームサーバー自体が有効になっていること。
  • 有効な NS ホスト名があること。空欄や、テスト用のプレースホルダーではないこと。
  • 紐づくノードのうち、少なくとも1つのステータスが有効であり、かつ直近 15 minutes 以内にハートビートを送信していること。

最後の条件は、詳しく説明する価値があります。データベースのノードのステータスフィールドは運用担当者が設定するもので、「このノードにサービスを提供してほしい」という意図を表しています。しかし、意図と現実は同じではありません。マシンが有効と記録されていても、再インストール、ネットワークの変更、認証情報の失効などにより、すでに長い間応答していない可能性があります。ステータスフィールドだけを信頼して割り当てると、実際には存在しないサービスに新しいゾーンを委任してしまうおそれがあります。

そこで、次のルールを採用しています。ステータスフィールドは意図、ハートビートのタイムスタンプは事実です。 各ノードは設定をポーリングするたびに最終確認時刻を更新し、ポーリングが止まったノードは一定時間後に自動でオフラインと判定されます。割り当て処理が信頼するのは事実だけです。

ノードがゾーンデータを取得する仕組み

割り当てが済んだら、適切なノードにゾーンデータを配置する必要があります。権威 DNS のデータプレーンは、CoreDNS をカスタマイズしたビルドで、プル方式で動作します。

  • 各ゾーンには設定バージョンがあり、これはゾーンの SOA レコードのシリアル番号でもあります。レコードが変更されるたびに値が増加します。
  • ノードは認証付きでコントロールプレーンに定期的に問い合わせ、現在のバージョンを確認します。バージョンが変わった場合は、新しいゾーンデータを取得し、標準的なゾーンファイルとして書き出して再読み込みします。
  • 各ノードが受け取るのは、自身が配信するネームサーバーに割り当てられたゾーンだけで、データセット全体ではありません。
  • ゾーンが無効化または削除されると、コントロールプレーンは一定期間、削除シグナルをノードに送り続けます。ノードはローカルのゾーンファイルを削除し、そのゾーンへの応答を停止します。削除済みのゾーンが一部のノードに残り続けることはありません。

SOA のシリアル番号が設定バージョンになっているため、dig を使って、特定のネームサーバーが最新バージョンを持っているかを確認できます。

dig +short SOA example.com @your-nameserver-hostname

すべてのネームサーバーが同じシリアル番号を返せば、すべてに最新のデータが反映されています。

インフラ用ゾーンから得た教訓

NS ホスト名自体も名前解決できる必要があります。そのグルーレコードとアドレスレコードは、お客様のゾーンと同じシステムで管理する専用のインフラ用ゾーンに置かれています。つまり、このゾーンは常に有効な状態を維持しなければなりません。誤って無効化すると、削除シグナルによってノードからゾーンが削除され、それらのネームサーバーに依存するすべてのゾーンに影響します。削除シグナルを有効にする前のエンドツーエンドテストでは、この点を重点的に確認しました。現在、こうしたゾーンには常駐対象であることを示すマークを付けています。

この教訓は、自らをホストするあらゆるシステムに当てはまります。プラットフォームが自身の重要な依存先をホストする場合、その依存先には追加の保護が必要です。

お客様が行うこと

ドメインを追加した後にお客様が行うのは、コンソールに表示される2つのネームサーバーをレジストラで設定することだけです。ゾーンの詳細ページには、割り当てられたネームサーバーと、それぞれの現在の稼働ノード数が表示されます。コンソールの NS チェックでは、委任が反映されたかどうかを確認できます。それ以外は、割り当て処理と同期パイプラインが処理します。

Yeap Cloud で開発を始める

新規アカウントで DNS と CDN の無料プランをご利用いただけます。

無料登録