DNSのラウンドロビン

DNSのラウンドロビンは枯れた技術で様々な企業で使用されています。

具体的にはDNSの登録する1つのホスト名に対して複数のIPアドレスを登録しておきます。クライアントからの要求に対して順番に先頭のIPを変更して異なるサーバーのIPアドレスを返すことにより負荷分散を行わせるものになります。

ホスト名としてWebserverが以下のように登録してある場合は

Webserver.test.net A 192.168.0.100
Webserver.test.net A 192.168.0.10
Webserver.test.net A 192.168.0.11
Webserver.test.net A 192.168.0.15
Webserver.test.net A 192.168.0.20

クライアント側にこれらのリストが返され、先頭の 192.168.0.100 が使用されます

そして別の端末がWebserverの名前解決を行うと

Webserver.test.net A 192.168.0.10
Webserver.test.net A 192.168.0.11
Webserver.test.net A 192.168.0.15
Webserver.test.net A 192.168.0.20
Webserver.test.net A 192.168.0.100

クライアント側にこれらのリストが返され、先頭の 192.168.0.10が使用されます

このような動作により負荷分散を行います

本日、同僚が研修でテストしていたら思ったような動作にならないと言ってきました。そして調べてみるとWindows Server 2008 と Vista ではラウンドロビンがうまく動かないことがわかりました

どのような動作になるかというと DNSキャッシュの内容が以下のエントリで入ったとします

Webserver.test.net A 192.168.0.100
Webserver.test.net A 192.168.0.10
Webserver.test.net A 192.168.0.11
Webserver.test.net A 192.168.0.15
Webserver.test.net A 192.168.0.20

このようなリストが返されると、一番小さいアドレス(longest match)が選択される仕様になっているようです

2009/11/09 追記
2009/11/18 追記

私の理解が少々間違っていましたので訂正します

実際にはまず自分のIPアドレスを確認します。たとえば、自分のIPアドレスが192.168.0.1だとすると、自分のIPとラウンドロビンのIPを比較します。

11000000 10101000 00000000 00000001 = 192.168.0.1 = Client IP to match.
11000000 10101000 00000000 01100100 = 192.168.0.100 = (24 + 1 = 25 bits matching the client IP)
11000000 10101000 00000000 00001010 = 192.168.0.10 = (24 + 4 = 28 bits matching the client IP)
11000000 10101000 00000000 00001011 = 192.168.0.11 = (24 + 4 = 28 bits matching the client IP)
11000000 10101000 00000000 00001101 = 192.168.0.15 = (24 + 4 = 28 bits matching the client IP)
11000000 10101000 00000000 00010100 = 192.168.0.20 = (24 + 3 = 27 bits matching the client

ここでIPアドレスのマッチングを行います。第3オクテットまでは同じなので第4オクテットに着目します。

192.168.0.10
192.168.0.11
192.168.0.15

が28bit matchなので、この中の先頭のIPアドレスが選択されます。

ですのでこの場合は 192.168.0.10 が選択され続けることになります。

これはVistaよりIPv6がデフォルトで動作する仕様変更に伴い、RFC3484に従ったためにおこるものらしいです

ただし、実機確認してみると意外なことが判明!

この動作は同一セグメントでの動作で、異なるセグメントの場合はちゃんとラウンドロビンが動作しました。

Pingでのテストによると、もしマッチングビットが同じで通信が不可能な場合キャッシュに登録された順番にIPを試します。結果的に通信が確立されたIPがあった場合はそのIPに固定された通信を行います。

192.168.0.10(不可)
192.168.0.11(不可)
192.168.0.15 追記はここまで(2009/11/09)

この動作を以前と同様にするにはレジストリの変更が必要になります

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters
DWORD = OverrideDefaultAddressSelection
Value data: = 1

ちなみに、Windows7 と Windows Server 2008 R2 ではこのレジストリがデフォルトで1になっています(キーは存在しません)。よって、クライアントにWindows7を使用している場合は特に問題はないということになりますね。

参考

DNS Round Robin and Destination IP address selection

いや~、知らなかったな~~~

Windows 7 USB/DVD Download Tool(WUDT)を試す

Windows 7 USB/DVD Download Tool(WUDT)とは、NetbookなどDVDドライブがついていない端末において、USBを使用してインストールをする目的で作られたツールになります。

要するに、手持ちのWindows7 ISO イメージをUSBに入れることによって、同OSをインストールするためのブータブルUSBメモリを作成します。Windows 7インストールDVDも作成可能です(USBメモリや外付けDVDドライブからのブートにはBIOS設定の変更が必要)。

ここで注意が必要なのはISOイメージが必要だということ

DVDしかないときは、それをISOに変換するツールがないとだめですね

そしてUSBは最低4Gバイトの容量が必要なこと

この条件を満たせば、USBへのWindows7インストールイメージが作成できます

Windows 7 USB/DVD Download Tool

12/9にGPLv2に沿った形で再公開しました。更に今回は日本語版もありますね!ただし、このソフトを利用するには.NET Framework 2.0が必要なほか、環境によっては「Image Mastering API v2.0 (IMAPIv2.0) の更新プログラム」を適用する必要があります。

http://wudt.codeplex.com/releases/view/37074

インストール後、WUDTを起動しISOファイルを指定します

WS000002

メディアタイプをUSBとしてクリック

WS000003

ここで使用するUSBを選択してBegin copyingをクリック

WS000004

フォーマットが始まり、その後USBにイメージがコピーされます

WS000005

終わるとこんな画面になります

WS000006

そして完了したUSBをのぞいてみます。Windows7のメディアは複数エディションがインストールできる統一メディアになっているので、これを複数エディションがインストールできるようにカスタマイズしてみます。

このエディションはあるファイルに書き込まれています。

sourcesフォルダにあるei.cfgをみてみると

[EditionID]
Ultimate
[Channel]
Retail
[VL]
0

このように記述されていました。

このファイルを削除します。そうすると各エディションが選べるようになります。

*ただし、EnterpriseはVL用なのでこのファイルを消してもエディションは選べません。よってコンシューマー用に限ります。

Hyper-V2.0におけるNLB設計

NLBを構築する際には注意しなくてはいけないことがあります。それはHyper-Vで構築しようが、物理サーバーで構築しようが同じです。

今回は結論から書きますが、Hyper-VでNLBを設定するサーバーに対してはVLANを使用して専用セグメントを作ることがベストだと考えます。NBLの条件としてはユニキャストモードで構築するとします。

さて、ここでなぜVLANを使用するのか?

ここで考えなくてはいけないのが、NLB(ユニキャストモード)における動作になります。

NLBの動作

NLBを構築すると、NLBに参加しているホストのMACアドレスはNLBのMACアドレスに置き換わります。ここで問題なのはスイッチとの関係になります。スイッチはポートごとにMACを登録しますが、この状態だと複数のポートに同じMACアドレスがあることになります。となると、スイッチではMACアドレスが適切に登録されないという事態が発生するのです。そこで、NLBに参加しているホストはフェイクのMACアドレスを送信するようになります。

この図で解説すると、本来のMACアドレス02-bf-a-a-a-aが02-01-a-a-a-aとして送信されることになります。ただし、ARPデータは本来のMACアドレスである02-bf-a-a-a-aをさすんです。よって、クライアント側ではIPとMACアドレスの対応は正常に行われることになります。

ではクライアントからNLBにアクセスする際の動作としては、NLBのMACアドレスはスイッチに登録されていないので、全てのポートにフラッディングされることになります。そうすると、NLBに参加している全てのサーバーにデータは届きます。

ここでNLBのアルゴリズムである、統計的完全分散フィルタリングアルゴリズムによって適切なサーバーでデータが処理されることになります。

ここで問題です

NLBに参加していないPCやServerたちにも、NLB宛てのデータが届いてしまうのです!しかし、自分宛のパケットではないのでドロップ処理を行い受け付けません。要するに同じセグメントに参加しているコンピュータには不要なパケットがバンバン届くんですね。

よって、NLBを構築する際には専用セグメントを作成して、その中だけでNLBパケットを完結させる必要があるんです。

そのためには、Hyper-V環境ではVLANを使用するのが最も効率が良い方法だと考えるからになります。

Hyper-V 2.0 新機能~ネットワーク負荷分散(NLB)設定

TechED2009ではHyper-V2.0においての設計についての話が結構ありました。そこで検証作業を行いました。

Hyper-V2.0でも1.0と同様の設定が必要になると思っていましたが違う点がありましたので注意する必要があります。

それは、Hyper-V1.0のときはNLBを設定する際にはゲストOSのネットワークのMACアドレスを静的にし、NLBを構成した際に配布されるMACアドレスに書き換える必要がありました。

参考:

http://support.microsoft.com/kb/953828/ja

そこで、Hyper-V2.0でも同じことをしなくてはいけないと思いいざ構成してみると・・・・

WS000013

ここでNLBのMACアドレスをメモ・・・「02-bf-ac-10-0a-96」

WS000014

あらかじめゲストOSのネットワークアダプタには「MACアドレスのスプーフィングを有効にする」にチェックを入れておきます

WS000016

あれれ、静的MACアドレスにしなくても収束してしまった

WS000015

確認のためにゲストOSのMACアドレスを調べると・・・NLBのMACアドレスになっている!!

まとめ

  • Hyper-V1.0では静的MACにして、NLBのMACアドレスに書き換える必要がある
  • Hyper-V2.0では「MACアドレスのスプーフィングを有効にする」にチェックを入れておく

ということになりますね。いや~、知らなかった(汗)

Hyper-V 2.0 新機能~仮想マシンのインポート

細かい点なんですが、Hyper-V1.0のときはエクスポートした仮想マシンをインポートする際には、必ず目的の場所にコピーをしてからインポートしていました。その理由は1回インポートした仮想マシンは再度インポートできないのでその対策がひとつ。

もう一つは、エクスポートする際には外付けHDDなどに行う場合が多いです。その外付けHDDを別のHyper-Vがインストールされている物理マシンに接続し、インポート作業を行うことになります。もしこのままインポートを行ってしまうと、その外付けHDDが仮想化マシンの保存場所になってしまいます。これは困りますよね~

そんなことから、インポートする際にはエクスポートしたデータを目的の場所にコピーしてからインポートを行うということをしていました。

ではHyper-V2.0ではどうなったか?

インポート

すべてのファイルを複製し、同じ仮想化マシンを再度インポートできるようにする」というオプションが付加されたんです。これで、今まで行っていたコピーする作業は自動的に行われることになります。

ここで注意が必要なのは、「仮想マシンをコピーする」チェックですが、この操作を行うと仮想マシンIDが新たに作られるだけで、インポートするゲストOSには変化がありません。ということはSIDの問題などがあるということになります。

また、インポートした仮想マシンの仮想ネットワークに外部接続ネットワークがつけられていた場合は、再設定が必要になるということでしょうか。

Hyper-V 2.0 新機能~ネットワーク編その4

そのほかのネットワーク新機能としては

  • ジャンボフレームのサポート
  • TCPオフロードのサポート

があげられます。

ジャンボフレームやTCPオフロードはホストでは使用できましたが、Hyper-V2.0(Windows Server 2008 R2)より、ゲストOSでサポートされるようになりました。

WS000005

これがHyper-V1.0のゲストOS上のネットワークプロパティの詳細設定です。 (Jumbo Packetの項目はありませんね)

WS000010

これがHyper-V2.0のゲストOS上のネットワークプロパティの詳細設定です。

これらの画面を見れば一目瞭然ですね。

ジャンボパケットはデフォルトでは無効ですので必要ならここの値を変更する必要があります。ただし、通信経路すべての機器がジャンボフレームに対応していないと使えませんので注意が必要です。

ジャンボパケットとは通常イーサネットでは最大1518バイトで通信を行いますが、それよりも大きなパケット通信を行うことを言います。通常1G以上の通信で使用します。10、100Mでの通信でジャンボパケットを使用すると逆にパフォーマンスが劣化したり、リンクが失われる場合がありますので注意が必要です。

TCPオフロードはデフォルトでペアレントOSおよび仮想端末側でオートになっています。

確認方法としてはそれぞれのコマンドプロンプトより

netsh int tcp sh global

TCPオフロードとはネットワーク通信における計算処理をCPUが行っていますが、それをNICに行わせることによってコンピュータまたはサーバー上のネットワークデータの処理を向上させるのに役立ちます。

今まではたとえホストOSでTCPオフロードを使用していても、仮想マシンのネットワーク処理はホストOSのCPUが担当していました。この処理を有効にすることにより10%程度の処理速度の向上が見込まれるようです。

Hyper-V 2.0 新機能~ネットワーク編その3

Hyper-Vにおける推奨のネットワーク構成としては、管理用ネットワークと仮想マシン用ネットワークを分けて構築しましょうということでした。

ではHyper-V1.0において具体的にどのように行うの?

  1. 物理NICを2枚用意する
  2. NIC1を管理用、NIC2を仮想マシン用とする
  3. Hyper-Vマネージャより仮想ネットワークマネージャを開き、NIC2に外部のネットワークを作成する
  4. ホストOSのネットワーク接続からNIC2にバインドされている仮想NICを無効化する

ポイントは4番の仮想NICを無効化するになります。これを行わないとNIC2で管理が行えてしまうからです。

ではHyper-V2.0では?

管理共有

Hyper-V2.0では、外部ネットワーク作成において新しいオプションが増えています。「管理オペレーティングシステムにこのネットワークアダプタの共有を許可する」です。

ということで実際には

  1. 物理NICを2枚用意する
  2. NIC1を管理用、NIC2を仮想マシン用とする
  3. Hyper-Vマネージャより仮想ネットワークマネージャを開き、NIC2に外部のネットワークを作成する
  4. 管理オペレーティングシステムにこのネットワークアダプタの共有を許可する」のチェックがないことを確認する

実は、Hyper-V2.0では「管理オペレーティングシステムにこのネットワークアダプタの共有を許可する」にチェックを入れないとホストOSのネットワーク接続に仮想NICは現れなくなりました。これは、いい変更ですね。

以上のように、より簡単に管理用と仮想マシン用のネットワークの分離ができるようになりました。

Hyper-V 2.0 新機能~ネットワーク編その2

厳密に言うと新機能ではないのですが、新たにインターフェイスが用意されたものがあります。それが、[MACアドレスの範囲]になります。

MACアドレスの範囲

Hyper-Vの仮想マシンのMACアドレスは動的に設定することができます。

実は、Hyper-Vの役割がインストールされた際にMACアドレスプールがレジストリに設定されます。

HKLMSoftwareMicrosoftWindows NTCurrentVersionVirtualization

MinimumMacAddress
MaximumMacAddress

指定例:
MinimumMacAddress = 00-15-5d-ec-34-00
MaximumMacAddress = 00-15-5d-ec-34-FF

*上位MACアドレスの00-15-5dはマイクロソフトが保有しているアドレスになるので固定にする必要があります。

がアドレス範囲として設定されることになります。

参考:Dealing with MAC address pool duplication in Hyper-V

さて、この設定が問題になることとしてはHyper-Vの役割をインストール済みの状態で、マスターとして設定したのちに複数台の物理マシンに展開したとします。仮にSysprepを実行してもこのアドレス範囲は変わりません。

ということは、複数のHyper-Vマシン上で仮想マシンを作成すると仮想マシン間でMACアドレスのバッティングが発生する可能性があります。

Hyper-V1.0の時にはこのレジストリ情報を変更することによって回避していました。すでにゲストを構築済みの場合は、一度ネットワークアダプタを削除し、再度作成する必要があります。

Hyper-V2.0では、インターフェイスからMACアドレス範囲を変更できるようになったんですね。

Hyper-V 2.0 新機能~ネットワーク編その1

ネットワークの設定において「MACアドレスのスプーフィングを有効にする」という機能が追加されました。

ネットワークアダプタ1.0

これがHyper-V1.0のネットワークアダプタの画面になります

ネットワークアダプタ2.0

これがHyper-V2.0のネットワークアダプタの画面になります

さて、これって何?

仮想ネットワークマネージャからネットワークを作成すると仮想スイッチが作られます

仮想スイッチ

この仮想スイッチは通常のスイッチと同様にMACアドレスの学習をします。しかし、ここで問題になるのはそもそも仮想マシンは物理MACを持っていません。ということはMACアドレスは常に仮想MACということになります。これは便利な半面、使い方によってはセキュリティ上の問題が発生する可能性があります。

仮想マシンで異なる複数のMACアドレスがあった場合は再学習されてしまいます。これはこれで正しい動作なのですが、Hyper-V2.0ではこのような動作を禁止させる仕様になりました。

参考:New in Hyper-V Windows Server 2008 R2 Part 2 – MAC Spoofing

チェックなし(セキュアモード)とした場合は次のようになります

  1. 仮想ネットワークに設定されたMACアドレスのみが自分が送るパケットの唯一の送信元MACアドレスになる
  2. 仮想マシンは宛先MACアドレスが登録されたMACアドレスのユニキャストのみを受信します。そのMACを宛先とするパケットは他のポートにフラッディングされることはない
  3. 仮想スイッチは学習するのでルーティングテーブルを含む様々な内部構造をメンテナンスします。仮想マシンを起動し仮想ネットワークが起動したらルーティングテーブルに自分のMACアドレスを登録し、他のポートに移動しないようにする
  4. トラフィックがスイッチによってフラッディングされる必要がある場合、セキュアモードになっているそのポートに対しては行われない
  5. 仮想マシン内のMACアドレスは上書きはされない

チェックを入れた場合(セキュアレスモード)は

  1. 仮想マシンはすべてのMACアドレスのトラフィックを送受信する
  2. 仮想マシンはフラッディングされたユニキャストパケットを受信する
  3. ポートに対して複数のMACアドレスを学習させることができる。またルーティングテーブルはスイッチポートを通過した時点で学習される
  4. 仮想マシンはMACアドレスを上書きできる

NLBを構築する際には(ユニキャスト構成)各ネットワークのMACアドレスをNLBで設定した仮想MACアドレスに変更しなくてはなりませんその場合は、この「MACアドレスのスプーフィングを有効にする」にチェックを入れたセキュアレスモードにする必要があります

2009/09/15追記

NLB構成の際には、静的MACにしてNLBのMACアドレスに変更する必要はないようです。検証の結果、自動的に適用されました。

キャッシュされたログオン

ドメイン環境において、ネットワークに接続していなくてもクライアントコンピューターにログオンできます。それはキャッシュされたログオン情報を使用してのログオンとなります。この話は以前からあり、最新OSであるWindows7でも同様です。

この仕組みとしてはレジストリに記載されている情報を使用します。

HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrent VersionWinlogon

値の名       : CachedLogonsCount
データ タイプ: REG_SZ
値           : 0 – 50

デフォルト値は10になっています。

これは10個のログオン情報を記憶するということで、ログオン回数とは関係ありません。

ちなみにWindows Server 2008では25に変更されましたが、Windows Server 2008 R2では、またもとの値の10に変更されました。

GPOでも変更できます

コンピュータの構成Windows の設定セキュリティの設定ローカル ポリシーセキュリティ オプション対話型ログオン : ドメイン コントローラが利用できない場合に使用する、前回ログオンのキャッシュ数

から設定を行います。

ここでの考察ですが、ドメイン環境で使用しているのであればキャッシュは使われたくないというニーズは必ずあります。そのような場合はこのレジストリを変更すれば対応できます。

しかし、組織においてノートPCを使用していて外部で使用する際にはネットワークに接続していない環境でPCにログオンしなくてはなりません。その際にドメインアカウントではなくローカルアカウントの使用をしなくてはならないのがネックになりますね。また、アカウントを変更するということは、ドメインで使用しているユーザープロファイルと、ローカルで使用するユーザープロファイルの使い分けをしなくてはならないのが現状です。たとえば、ノートPCをドメイン環境でも使用している状態で、外部からVPN接続をして使うという状況もあります。その際にプロファイルが異なっていると何かと不便ですね。端的な例だとメール(Outlookなど)など情報がプロファイルに記入されるものは特に不便です。

こんなことからやはりキャッシュされたログオンは必要なのかな?なんて思う今日この頃です。

まだ調べきれてない情報として、現在キャッシュされたログオンなのか?そうではないのか?の簡単な判別方法があるのかです。

SETコマンドを使用すれば、現在接続しているlogonserverが判りますが、キャッシュされたログオンでも同じ情報が出てくるのでこれではだめですね~

net user <アカウント名>の最終ログオン日時を見たのですが、なぜか更新されていない。なんでだろう・・・・