一般的には、複数のサーバに対して、負荷分散や可用性を確保するには、サーバロードバランサで実現します。
ただし、ロードバランサがない環境の場合に少しでも負荷分散や可用性を高める方法として、DNSラウンドロビンを実装することがあります。
この記事では、下記のように、端末からプロキシサーバ×2台に対して、DNSラウンドロビンによる負荷分散の動作確認をします。
DNSラウンドロビン概要
DNSラウンドロビンとは、DNSのレコードにて、1つの名前に複数のIPアドレスを割り当て、これら複数のIPアドレスをラウンドロビンでDNSレスポンスすることで、負荷分散を図る技術です。
下記は、DNSサーバ(ActiveDirectory:ドメイン名 hirotanoblog.local)のAレコードで、1つの名前 proxy-svに対して、IPアドレスを2つ(10.10.1.100 / 10.10.1.101) を登録します。
DNSラウンドロビンでは、proxy-svのDNSクエリーに対し、10.10.1.100 と10.10.1.101をラウンドロビン(順番)に1アドレスずつDNSレスポンスすると思われがちですが、一般的には、登録されたAレコードのすべてがレスポンスに含まれ、その順番が循環します。
下記は、proxy-svに対して、nslookupを実行した結果です。
1回目のDNSクエリーでは、10.10.1.101 -> 10.10.1.100 の順番で、2回目のクエリーでは、10.10.1.100 -> 10.10.1.101 3回目では、1回目と同様、10.10.1.101 -> 10.10.1.100 と循環しています。
クライアントは、DNSレスポンスの先頭のアドレスから接続を試みます。そのため、クライアントからの接続は、ラウンドロビンにより負荷分散されます。
動作確認
今回は、プロキシサーバの負荷分散をDNSラウンドロビンで実装します。
プロキシは、proxy-svと名前で設定し、片方のプロキシ障害時の切り替わりも確認します。ブラウザはMicrosoft Edgeを使用します。
下記は、https://www.bing.com へプロキシ1号機経由で接続したのち、プロキシ1号機を電源OFFした場合のパケットキャプチャです。(説明に不要な部分は省いています)
DNSクエリー・レスポンス(No1~No2)
端末からDNSサーバへproxy-svの名前解決。10.10.1.100 -> 10.10.1.101の順番でDNSレスポンスされています。下記はDNSレスポンスのキャプチャ抜粋です。
プロキシ1号機接続(No3)
先頭アドレスである10.10.1.100(プロキシ1号機)へ接続
プロキシ1号機の電源OFF(No4~No13 )
プロキシ1号機の電源OFF。端末からプロキシ1号機へTCPを試みる(TCP再送)※大量に出力されるので、一部パケットは省略しています。
プロキシ2号機接続(No14)
10.10.1.101(プロキシ2号機)へプロキシ接続が切り替わる。
障害時のブラウザ側の挙動
プロキシサーバ障害時のEdgeの挙動をnet-exportを使用して確認しました。
net-exportの詳細は下記記事を参照ください。
プロキシ1号機の電源をOFFした場合
プロキシ1号機(10.10.1.100)へプロキシ接続しているところで、電源OFFします。すると、10.10.1.100:3128へTCPの接続を試み、応答が返ってこない状態が続きます。
しばらくすると、IPアドレスの順番を循環させています。(10.10.1.101 -> 10.10.1.100)
10.10.1.101へプロキシ接続し、Web通信が復旧します。
プロキシ1号機のサービスを停止した場合
電源OFFではなく、プロキシサービスを停止します。すると、サーバから接続拒否(RST)されるため、Windowsソケットのエラーを検知し、次のアドレスの10.10.1.101への接続を試みます。
以上、Edgeに合わせて、Chromeも同様の動作となりました。
DNSラウンドロビンは、サーバの生死を監視していないため、サーバ障害時もすべてのIPリストをDNSレスポンスします。そのため、障害サーバへの接続を試みます。負荷分散、可用性はやはりロードバランサのほうが、安定します。
複数のIPアドレスリストのDNSレスポンスを受け取ったあとの挙動は、アプリケーションにより異なると思われます。本番環境へ適用する際は十分な検証を行ってください。
コメント