Novell(クラウドコンピューティングのセキュリティ・仮想化ソリューションを実現)

 

VMware ESXサーバの下でLinuxゲストを実行中のタイムドリフト

This document (3858673) is provided subject to the disclaimer at the end of this document.

環境

Novell Open Enterprise Server (Linux ベース)
Novell eDirectory 8.7.3 for Linux
SUSE Linux Enterprise Server 9
SUSE Linux Enterprise Server 10
VMware ESX Server
NTP時刻同期

問題の状況

VMware ESXサーバの下でLinuxゲストを実行中ににタイムドリフトが発生します。

ゲストでeDirectoryを実行中に、ndsrepair -Tが時間の非同期を報告します。
エラー: -659、ツリーへのサーバ追加時

背景:

オペレーティングシステムには、将来の正確な時刻に作業をスケジュールする方法が必要です。そのようなオペレーティングシステムをサポートするプロセッサは、スケジュールされた作業をプロセッサに実行させるために定期的にプロセッサに割り込むことのできるプログラム可能な割り込みタイマを持つ必要があります。この定期的割り込みは、システムクロックティックと呼ばれています。すべてのアクティビティは、この絶え間ない「ハートビート」を使用してスケジュールされます。Linuxカーネル内では、時間は、システムブート以降のクロックティックの合計とみなされます。この計測値は、jiffiesと呼ばれています。

SLES9のLinux 2.6カーネルをSLES8のLinux2.4カーネルと比較すると、ベース割り込み率が100/秒から1000/秒へと変わっています(SLES 10 SPのカーネルは、250 HZに設定されています)。デュアルプロセッサのLinux 2.6カーネルでは、最大3000/秒の割り込み率になります。これは、適度な負荷の下でベアメタルサーバを実行している場合は、通常、問題になりません。ただし、Linuxカーネルの複数のインスタンスが、ホストの実際のハードウェアベースプロセッサを利用しようと競合している仮想化環境では、容易に問題が発生します。システムが長期に渡ってビジーになると、ティックが失われることがあります(仮想化環境では、実際のゲストのOSアクティビティはほとんど要求されません)。これらのティックの喪失は、通常、実行中はウェークアップして割り込みをマスクまたは禁止する必要のあるI/Oとシステムサービスが原因です。長期に渡って割り込みが禁止されると、ティックが蓄積し、カーネルがティックカウントを追跡できなくなり、それらのティックは失われたと見なされます。

Linuxカーネルのゲストオカレンスによって生成される割り込みの数とESXホストカーネルが処理できる数の不一致により、ティックの喪失は頻繁に発生する問題となっています。失われたティックを検出し、修正するため、2.6カーネルにコードが追加されました。ただし、ティックが失われた時刻を正確に検出することが困難な場合があります。x86が割り込みハンドラをキューに入れる方法のせいで、実際には失われたティックがないときに、このコードによって余分なティックが追加されることがあります。これらの余分なティックにより、タイムゲイン(つまり、サーバのタイムソースより時間が進むこと)が発生することがあります。失われたティック自体は、時間の喪失(時間がソースより遅れること)を引き起こします。

解決策

カーネルのティック補償コードで、多すぎるティックが追加されたため、タイムソースより進む時間を最小限にするには、次のブートパラメータを使用します。

clock=pit

(ESX 3.xの下でSLES 10 SP1カーネルを実行する場合は、おそらく、これが変更の必要のある唯一の設定です.)

ESXの下でLinuxゲストを実行する場合は、下記の設定と推奨事項に準拠することにより、その環境での時間同期の問題を回避できます。

仮想化ゲストにNTPをセットアップする

a. 外部の信頼性の高い NTPタイムソースを、ESXホストとその仮想化ゲストの両方に使用してください。ESXホスト自体やその下で実行される仮想サーバをタイムソースにしないでください。それらをタイムソースにすると、仮想マシンの割り込み負荷が増大し、問題が悪化するだけです。

b. NTPソースをセットアップします。

  • /etc/ntp.confファイルを変更します。エントリの前に#記号を挿入することにより、エントリをコメントアウトして、ローカルクロックが使用されないようにします:

    #server 127.127.1.0 # local clock
    #fudge 127.127.1.0 stratum 10

  • ファイルの末尾にこのタイムソースのエントリを追加します(x.x.x.xをサーバのIPアドレスで置き換えてください):

    server x.x.x.x prefer

c. 時間をスラムして(強制して)、NTPデーモンを起動し、時刻を確認します。

  • NTPデーモンを停止します。SLES10上:

    /etc/init.d/ntp stop

    SLES9上:

    /etc/init.d/xntpd stop


  • 次のコードの入力によって、現在の時刻をスラム(強制)します:

    ntpdate x.x.x.x

    (ここで、x.x.x.xは、NTPソースのIPアドレス)
    (表示されるオフセットが1秒未満になるまで、このコマンドを数回強制します.)
  • 再度、NTPデーモンを起動します。SLES10上:

    /etc/init.d/ntp start

    SLES9上:

    /etc/init.d/xntpd

  • 次のコードの入力で、このサーバの「reach」で377が表示されるまで待機します。

    ntpq -p

    (これは、15〜20分にかかることがあります.)

VMware環境を変更する

ESX 2.x の場合のみ -Misc.TimerHardPeriod

この変更は、タイムラグの除去に役立ちます。SLES 10 SP1カーネルを実行するESX 3.xサーバで時間が遅延する場合は、おそらく、NTPの設定が正しくないか、ソースに信頼性がないか、またはESXサーバの負荷が高すぎます。仮想マシンをそのサーバから別のサーバに移動するか、および/またはゲストの優先順位を調整すると、ゲストに割り当てられるプロセッササイクルが増えて、問題の解決に役立つ場合があります。VMwareでは、最大および最小回数に関するESX 3.0のデフォルト値は変更しないように推奨しています。

ESX 2.0 Status Monitorを使用して、[オプション]>[詳細設定]の順に選択し、[Misc.TimerHardPeriod]設定までスクロールします。値をデフォルトの1000から333(または250)に変更し、[OK]をクリックします。この変更は動的であり、ただちに実行されます。

カーネルブートパラメータを変更する

ESX 2.xおよび3.x - clock=pit


この変更は、時間の修正し過ぎ(カーネルの補償コードによって生成された余分なティックのために時間が進むこと)の除去に役立ちます。
ゲスト内で、viを使用して/boot/grub/menu.lstファイルを開き、「clock=pit」をtitle Linuxセクションのkernel行の末尾に追加します。
注意: クラスタリング環境での実行中にクラスタリングサービスが起動したとき、clock=pitによって再起動が発生するという報告がありました。それに対する推奨は、このclock=pitをclock=pmtmrに変更することでした。
次に例を示します。

title Linux
kernel (hd0,2)/boot/vmlinuz root=/dev/hda3 vga=0x317 selinux=0 splash=silent
resume=/dev/hda1 elevator=cfq showopts clock=pit

LILOを使用する場合は、次のように、clock=pitパラメータを/etc/lilo.confファイル内のappend=行に追加します:

append="resume=/dev/hda6 splash=silent clock=pit"

lilo.confを編集したら、/sbin/liloの実行で編集内容を有効にすることを忘れないでください。

LILOを使用するか、GRUBを使用するかに関わらず、このパラメータの追加後はサーバを再起動してください。

通常、ゲスト内のNTP時間問題を解決するには、上記の2つのVMware ESXサーバとゲストの変更で十分です。NTP時間の問題がまだ解決しない場合は、次の追加ステップを実行できます。ただし、この変更は、他のすべての方法を試してしまうまでは行わないようにすることをお勧めします。

- ESXファイルシステム上でゲストの設定ファイル*.vmxを見つけます。(デフォルトの保存場所は、 /root/vmware)このファイルをviで開き、ステートメント「tools.syncTime=FALSE」を「tools.syncTime=TRUE」に変更します。この変更を有効にするには、単にリセットするのではなく、SLES9ゲストの電源を完全に切って、設定ファイルを再読み込みさせます。ゲストの電源を再投入すると、ゲストは、その設定ファイルが変更されたことに気づき、再読み込みすべきかどうか尋ねてきます。この質問に「はい」と答えてください。

万一、NTP時間が確実に同期していないと分かった場合は、次の手順が役に立つことがあります:
- 選択したタイムソースが時間を提供し、信頼できるかどうか確認します。
コマンド
ntpq -p
を入力して、選択したタイムプロバイダのエントリの横にアスタリスクが付いているかどうか確認します。

仮想マシンでは、これらの手順に加えて、ブート時にそのAPICおよび/またはACPIを無効にしてから、OSをロードすることが必要な場合があります。

ntpq -pコマンドの使用で、アスタリスクが表示されない場合は、APICが時間同期に干渉している可能性があります。このAPICは、「noapic」パラメータを/boot/grub/menu.lstのブートスイッチに追加してブートアップ時にこのパラメータを渡すことにより、無効にできます。

次のコマンドを入力します:

ntpd

コマンドウィンドウで、「as」を入力することにより、関連付けインデックスのリストを取得します。次に、「rv assid」(ここで、assidは前のステップで表示された番号)を入力することにより、このサーバの詳細なデバッグレポートを取得します。表示される値の多くがNTPのデバッギングに有用です。なかでも最も有用な値は、flash値です。この値は、着信NTPパケットの正常性確認の結果を示します。この値は、「flash=00 ok」である必要があります。

追加情報

タイムドリフトをテストするPerlスクリプト:

次のperlスクリプトを使用すると、上記で示唆された方法が成功するかどうかテストできます:

#!/usr/bin/perl

# Get drift
my $lines = `ntpdate -q pool.ntp.org`;
my @lines = split(/¥s/,$lines);
my $dummy = pop(@lines);
my $drift = pop(@lines);

my $nowstring = `date +"%Y%m%d-%H%M%S"`;
chomp $nowstring;
print "$nowstring -> $drift¥n";

このスクリプトを/usr/local/bin/timedrift-check.plに保存し、実行可能ファイルにします(chmod +x使用)。
このスクリプトは、次のフォーマットで行を出力します:
->
このスクリプトを頻繁に起動すると、タイムドリフトの進展状況を見ることができます。

VMwareナレッジベースの記事

Disclaimer

この情報は、米国Novell, Inc.およびノベル株式会社の内外から発生したものです。本文書の内容または本文書を使用した結果について、いかなる保証、表明または約束も行っていません。また、本文書の商品性、および特定目的への適合性について、いかなる黙示の保証も否認し、排除します。

本文書に記載されている会社名、製品名はそれぞれ各社の商品、商標または登録商標です。

  • ドキュメントID: 3858673
  • 作成年月日: 29-FEB-2008
  • 修正年月日: 16-APR-2009
  • ドキュメントリビジョン:
  • 分類:
  • 対象NOVELL製品およびバージョン: eDirectory, Open Enterprise Server, SUSE Linux Enterprise Desktop, SUSE Linux Enterprise Server
  • カテゴリ: