web-dev-qa-db-ja.com

(プライベート)DNSクラスタリングの最も回復力のある形式?

MAN(bridged))でリンクされた2つのデータセンターを使用したセットアップに取り組んでおり、RedHat Cluster、DRBD、およびその種類のフェイルオーバーモードですべてが2倍になっています。

場所ごとに1つのDNSサーバーがありますが、/ etc /resolv.confに両方を含めることはあまり役に立ちません。 1つがダウンした場合、クライアントは10秒ほど待機します。つまり、フェイルオーバーではなく、負荷分散に使用します。そこで、ucarp(≈VRRP)でVIPを使用するように、2つのサーバーを構成しました。

2つのDNSサーバーの両方を稼働させ、たとえば、常に同じIPに応答する方法はありますか? 1つのNS resquestが2つの答えを得る場合、それは大したことではありません。

エニーキャスト/マルチキャストなどでこれを行う方法はありますか?

編集:エニーキャストは私のシナリオでは何の役にも立たないことがわかりました。静的ルートしかないので、ほとんどのトラフィックは実際には橋を通ります。

興味深いのは、可能であれば、2つのDNSサーバーが同じIP上の要求に応答するようにする方法です。

3
niXar

エニーキャストDNSを使用すると、すべてのクライアントで1つのリゾルバーIPを構成できます。クライアント要求は、(ネットワークルーティングの観点から)「最も近い」サーバーに転送されます。

エニーキャストVIPのアドバタイズメントをヘルスチェックに関連付けた場合(たとえば、既知のドメインのAレコードを要求した場合)、サーバーの1つが失敗すると、そのルートは取り消されます。再収束すると、すべての要求は手動で再構成せずに他のデバイスに転送されます。

実装に関しては、これはハードウェアアプライアンス(F5 Big IP、Citrix Netscalerなど)を使用するか、独自の構成で行うことができます。 DNSサーバーで実行されているルーティングデーモン(Quaggaなど)を実行するか、各エニーキャストVIPの状態を変更するためにルーターにログインするカスタムスクリプトをいくつか用意することができます。

5
Murali Suriar

Resolv.confにいくつかのオプションを設定することで、問題を大幅に軽減できます。

オプションローテーションタイムアウト:2

回転すると、リゾルバーは、タイムアウトしない限り最初のネームサーバーを使用するのではなく、ネームサーバーの1つをランダムに選択します。 timeout:2は、DNSタイムアウトをデフォルト値ではなく2秒に短縮します。

(注:これはDebian/Ubuntuでテストされましたが、これはDebian固有の変更ではないと思います)

6
David Pashley

クライアントを修正します-より良いリゾルバーを使用します。

lwresdはBindの一部です。ローカルサービスとして実行されます。 /etc/nsswitch.confを介して使用するようにlibcを構成するため、静的にコンパイルされたプログラムを除くすべてのプログラムに対して透過的に使用されます。

lwresdは、構成されたネームサーバーのパフォーマンスと可用性を監視します(これは標準のバインド動作です)。ホストが使用できなくなった場合、lwresdはサーバーからバックオフし、すべてのクエリを他の構成済みサーバーに送信します。各ホストでローカルに実行されるため、通常はすべてのクエリを最も近いサーバーに送信する必要があります。

3
BrianEss

2つのLinuxVirtual Server(IPVS)ロードバランサーで内部BGPエニーキャスト再帰DNSクラスターを実行すると、それは魅力のように機能します。

基本的な設定は次のとおりです。すばらしい:申し訳ありませんが、新しいユーザーはハイパーリンクを追加できません...(以下のリンクとその後のリンクを参照してください)

サービスIPにVRRPを使用する場合の問題は、VRRPが2つのサーバー間を移動するため、フェイルオーバーの場合にクエリに応答できるようにするために、ネームサーバーがVRRPにすばやくバインドする必要があることです。 IPVSの設定と同じように、NATを使用してこれを回避できますが、何か問題が発生したときにわかるように、アクティブなサービスチェックを使用して負荷分散することをお勧めします。

マルチキャストを利用するDNS実装(Apple Bonjour/mdnsなど)がありますが、これらは通常、依存型または大量の再帰的DNSサービスにはあまり適しておらず、同じコリジョンドメイン(LANなど)内での使用に制限されていることに注意してください。

2
ZaphodB

単純な愚かな方法:

Linuxにresolv.confのDNSサーバーでもっと積極的になるように依頼してください:options timeout:0.1rotate

したがって、タイムアウトは迅速でローテーションされ、VIP/VRRP /スタッフが管理することなく、両方を使用して負荷をラウンドロビンし、2つのDNSサーバーがジョブを実行します...

2
Mathieu Chateau

エニーキャストは、この要件を解決するために頻繁に使用されます。エニーキャストDNSは、ルーティングおよびアドレス指定ポリシーを使用して、単一のソース(DNSクライアント)と、レシーバーグループ内のサービス(DNS)を「リッスン」する地理的に分散した複数のターゲットとの間の最も効率的なパスに影響を与えます。エニーキャストでは、同じIPアドレスを使用して各リスニングターゲット(この場合はDNSサーバー)をアドレス指定します。レイヤー3ルーティングは、ソース(DNSクライアント)から最も適切な(DNSサーバー)ターゲットへのパケットの計算と送信を動的に処理します。

エニーキャストDNSに関する一連のブログ投稿全体については、www.netlinxinc.comを参照してください。エニーキャストDNSを構成する方法のレシピがあります。このシリーズでは、静的ルーティング、RIPを使用したエニーキャストDNSについて説明しました。まもなく、OSPFとBGPに関するレシピを投稿します。

1
netlinxman

スワップオーバーが発生する前に数秒のDNS障害が発生しても問題がない場合は、これを行うための簡単なシェルスクリプトを作成できます。動作しない擬似コードは次のとおりです。

#!/bin/sh
localns=192.168.0.1
remotens=192.168.0.2
currentns=`cat /etc/resolv.conf | grep nameserver | awk '{print $2}'`

while 1; do
    if ping -W1 -q -c3 -i0.5 $localns > /dev/null 2>&1; then
        # Local DNS is up
        [ $currentns != $localns ] || echo "nameserver $localns" > /etc/resolv.conf
        currentns=$localdns
    else;
        # Local DNS is down
        [ $currentns != $remotens ] || echo "nameserver $remotens" > /etc/resolv.conf
        currentns=$remotedns
    sleep 2 # Will detect failures in no more than 5 secs
0
Alex J

サイトのどこかでロードバランサーを使用している場合は、DNSを仮想サービスとして使用するようにロードバランサーを構成できるはずです。

私のケンプロードマスター1500は、フェイルオーバーを伴うラウンドロビンを実行するように設定できます。これは、サービスチェックを使用して、各DNSサーバーが数秒ごとに稼働していることを確認し、2つのサーバー間でトラフィックを分割します。 1つが停止すると、RRプールからドロップアウトし、「アップ」サーバーのみが照会されます。

Resolv.confをロードバランサーのVIPにポイントする必要があります。

0
Matt Simmons

両方のサイトにロードバランサーがある可能性はありますか?そうでなければ、LVSで自家栽培することができます。

ロードバランサー上でVIPである各サイトにDNSサービスアドレスを設定します。次に、2つのDNSサーバー間でそれぞれVIP、ローカルを優先するアクティブ/パッシブロードバランス1。

0
cagenut

最初にVRRPを複製してみますが、VIPを追加します。 VIPごとに、プライマリノードとバックアップノードを交互に使用します。

DNS1 = vip1プライマリ、vip2セカンダリDNS2 = vip2プライマリ、vip1セカンダリ

次に、各クライアントマシンのリゾルバーに両方のIPを設定します。このようにして、負荷はネームサーバー全体に分散されますが、一方がダウンした場合、もう一方が追加の負荷を引き継ぐだけです。

0
eliott

DNSの信頼性が必要です。セットアップに非常に複雑なものを追加すると、何かが壊れたときに絶対的な悪夢が発生します。

提案されたソリューションの一部は、冗長DNSサーバーが同じサイトにある場合にのみ機能します。

基本的な問題は、DNSクライアントが設計どおりに壊れていることです。サーバーに到達できなかった時期を記憶せず、同じ応答しないサーバーに接続しようとし続けます。

NISは、ypbindに状態を保持させることで、この問題を処理しました。不器用な解決策ですが、通常は機能します。

ここでの解決策は、この問題に対する合理的な解決策を実装するためにベンダーに頼ることです。 AAAA要求がタイムアウトに浪費される時間の長さを増しているため、IPV6ではさらに悪化しています。単一の到達不能なDNSサーバーが原因でDNSタイムアウトを待機するのに非常に多くの時間を費やしたため、プロトコルが失敗するのを見てきました(sshd接続など)。

暫定的に、以前に提案されたように、resolv.confを有効なネームサーバーのみを含むスクリプトに置き換えるスクリプトを記述します。このスクリプトをベンダーと共有して、実装を余儀なくされた汚れたソリューションを示します。

これは真剣にテストされておらず、私のように解析するnslookupと、「-q」をサポートするgrepを想定しています。

これを5分ごとにcronから実行します。

重要なフェイルオーバー管理に実際にcronとシェルスクリプトを使用することを真剣に提案しているわけではありません。エラー処理の驚きは大きすぎます。これは概念実証のみです。

これを実際にテストするには、上部の「nameservers =」行を変更し、上部のresolv_confを/tmp/resolv.confではなく/etc/resolv.confに変更し、example.comを含むresolv.confのデフォルトヘッダーを変更します。 。

Resolv.confを置き換える場合は、nscdを再起動する必要がある場合があります。

#!/bin/bash
# full list of nameservers
nameservers="127.0.0.1 192.168.0.1 192.168.1.1"

# resolv.conf filename, change to /etc/resolv.conf for production use
resolv_conf="/tmp/resolv.conf"

# for tracking during the test
failed_nameservers=""
good_nameservers=""

# test loop
for nameserver in $nameservers; do
    if nslookup localhost $nameserver | grep -q 'Address.*127\.0\.0\.1'; then
        good_nameservers="$good_nameservers $nameserver"
    else
        failed_nameservers="$failed_nameservers $nameserver"
    fi
done

# if none succeded, include them all
if [ -z "$good_nameservers" ]; then
    good_nameservers="$nameservers"
fi

# error reporting, consider writing to syslog
if [ -n "$failed_nameservers" ]; then
    echo warning: failed nameservers $failed_nameservers
fi

# create the temporary replacement resolv.conf
new_rc="$resolv_conf.new.$$"
echo domain example.com  > $new_rc
echo search example.com >> $new_rc
for nameserver in $good_nameservers; do
    echo nameserver $nameserver >> $new_rc
done

# don't deploy a corrupt resolv.conf
if ! grep -q nameserver $new_rc; then
    echo warning: sanity check on $new_rc failed, giving up
    exit 1
fi

# keep a backup
if [ -f $resolv_conf ]; then
    rm -f $resolv_conf.previous
    ln $resolv_conf $resolv_conf.previous
fi
# deploy the new one
mv $new_rc $resolv_conf
0
carlito