SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する

コンピュータを正確に時刻あわせをするには、ラジオクロックやGPSなどを使う方法が一番正確なのでしょうが、入手方法も作業手続きも面倒なので、一般には公開されているNTPサーバを使います。

仮想環境で動作しているOSは起動時にハードウェアクロックとの同期が取れないことと、実ハードウェアクロックと仮想マシンが動作するクロックの微妙な差で、時刻がずれるという現象が起こります。また、 XEN 環境では xm pause すると、OSのローカルクロックも凍結した状態になりますから、時刻の狂いを修正しなければなりません。本来なら QEMM の仕事なのでしょうが、このあたりはまだこなれていないようです。

時刻は、OSが起動する際にBIOSクロックを拾って起動し、起動中、ハードウェアと同期をとりながらシャットダウンするときに CMOS クロックに書き込むようです。したがって、内部LANの一次NTPサーバは生のハードウェアを選択します。起動時はとりあえずハードウェアのCMOSクロックから拾い、次にNTPで修正するように動作します。このサーバをターゲットに仮想マシンを二次サーバとしてNTP同期を取るのがよいでしょう。

リアルタイムクロック Wikipedia による

※追加補足 KVM でもハードウェアクロックと同期する機能があるようですが openSUSE のドキュメントではハードウェアクロックの同期とNTPとの併用は推奨していません。個人的にはハードウェアクロックは機械のばらつきで信用できるとは思わないのでよほどのことがない限り仮想環境ではNTPを推奨します。いちいち全部のハードウェアの DEL キーを押しながらBios 画面を開いてNTTの117で確認してから起動画面を眺めるのはあまり気持ちのいいものではありません。

[Important]kvm-clock と NTP について VM ゲスト 内で kvm-clock を使用している場合は、 NTP による時刻同期を併用することはお勧めできません。 VM ホストサーバ 側での NTP は、 VM ゲスト 内での kvm-clock の使用に 関わらず、使用をお勧めします

※追加補足その2--
openSUSE や SUSE Linux Enterprise Server (SLES)を仮想化するときに Time Zone -> Asia/Japan にセットし「ハードウェアクロックを UTC と同期」させない設定(チェックを外す)とこんなダイアログが出ます。

GUI版 yast2
SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_149454.jpg

CUI版 yast
SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_14065188.jpg
 これは UTC をCMOS に同期させず、ローカル時間とするのは如何なものですかねぇ? という警告です。 UTC は絶対時間ですが、ローカル時間を使う場合、Day Light Saving Time (夏時間ですね)によっては一々 CMOS クロックも、夏時間に合わせてその都度変える必要があるよ、という警告です。

 今の日本では夏時間は使いませんが、よく「夏時間を導入しよう」ということは議論されます。英国の夏時間制度はどうなのかわかりませんが、 UTC と同じ時間帯に属する GMT だってローカルタイムゾーンです。英国だからと言って政治的に保障されているわけではないということです。

 大抵の場合、クロック合わせは JST で行います。私もそうしますし、CEさんがマザーボードを交換した場合も自分の時計を見ながら日本時間に設定します。

 マザーボードのトラブルログ(UTC)と、OSのログ(JST)をモニタした時にハードウェアクロックがOSとは異なる UTC で記録されると、当然、顧客から「なぜ日本時間じゃないんだ」とクレームになります。

 今後「日本に夏時間を導入」されると、ここはシステム屋としては UTC を使うか JST を使うべきかは議論すべき点となるでしょう。

 理解が得られるなら、 UTC に徹底すべきだろうし、今の日本では JST でかまわないと思います。ネットワーク内部のハードウェアクロックに UTC と JST が混在していたら、と考えると怖いので、今のところはやっぱりハードウェアクロックは使わないほうが無難だ、と考えます。

Windows は特に何も考えずにローカルタイムで起動し、ハイパーバイザーからUTCをもらいます。したがって、起動時のログ時間が UTC で表示されるようです。

-- 補足ここまで
-- 余談
このチェックを外しておかないと、Linux と Windows とデュアルブートするようなPCでは、Windows も ハードウェアクロックを拾って9時間遅れの UTC になってしまいます。ニホンゴのWindows にはUTCという概念はない様です。というか、ひどく時刻に関しては雑に実装されとぃる感じです。
-- 余談ここまで


VMware は当所の事業レベルでは手が出ないので試していないのですが、数十MbのハイパーバイザーにNTPの機能があるとは思えない(あるようです)ので、別途、ハードウェアとナマのOSを用意して仮想マシンのNTPソースにするのがよいと思います。ハイパーバイザーだけの仮想ホストとOS付のハイパーバイザーの隠れたコスト差はここにあります。

-公開NTPサーバと同期する-

ローカルネットワークの入り口でポート123番を通す先に一次同期サーバを設定します。できるだけ、仮想化されたシステムではなく、起動時にとりあえずハードウェアとのCMOSクロック同期が行える「生の」ハードウェアが良いでしょう。私はサーバ専門なので、よくは知らないのですが、ルータなどにNTPの機能があれば利用すべきです。ベアのハードウェアはCMOSクロックで起動して、次に公開NTPサーバー(NICT とか mfeed、あるいはISPのタイムサービスあたり)に正確に同期させます。

そうでないときは XEN が動作する SUSE Linux のDom0の ntp の機能を使います。これももちろん正確な時刻を提供する外部の公開NTPサーバーを使います。

同期元の公開サーバは1つではなく二つ以上を設定するのが良いでしょう。Windows ではデフォルトで time.windows.com となり、全世界何十億台ものデフォルトですから、同期が取れないことが多いと思います。また、Windows ではGUIでは単一のNTPサーバしか指定できないようです。経路的に近くにあるISPや国内の公開サーバーから取得すると、狂いが少ないそうです。国外のサーバを使うと遅延計算によってはかなりの狂いが出ます。

Linux, OES NetWare などは複数のサーバを指定できるため、対障害性を考えて二つ以上の同期先を指定しておくことができます。 SUSE Linux の場合 YaST > Network Service > NTP から設定することができます。設定した内容は /etc/ntpd.conf に書き込まれ、この画面を終了すると自動的にリスタートします。NetWare も Linux も普通のNTPのデフォルトのポーリング間隔確認間隔は10分 ( <--- 時刻同期がシビアなNetWareの場合、Linuxは --> minpoll 64sec:maxpoll 1024sec) です。

Windows はデフォルトが8時間なので、一度時刻が狂うと次のチャンスまで8時間、時刻が狂ったままになります。大きく時間が狂うと次も時刻同期に失敗するので早めにNTTの117番をダイアルして、大体の時間を合わせてください。また Windows システムは他のプラットフォームとの時刻同期を保障していません。内部に専用の時刻同期用の Windows プラットフォームを用意する必要がありそうでうす。

Windows の場合ポーリング間隔を変更するにはレジストリの変更か undocumented な秘密のコマンドが必要です。

SUSE の時刻同期は YaST > Network Service > NTP から簡単に設定できます
SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_15431554.jpg

log ボタンを押して、実際の同期状態をチェックすることができます。ログは /var/log/ntp に書き込まれます。

デフォルトではブート起動しませんので Dulling Boot をチェックします。Add ボタンで ntp.pool から取得するか、内部の同期先をセットします。ルータでもベア一ハードウェアでもRFC標準のNTPでかまいません。番いいのは、Dom0 が稼動する ntp です。Dom0 は少なくとも起動直後にハードウェアクロックから時刻を拾うので、通信経路の問題があってもまぁまぁの時間を配信してくれます。次にNTPソースを指定し正確に同期させます。

DomU の仮想マシンの場合は、ハードウェアクロックのリストをはずしたほうがよいでしょう。仮想上のハードウェアクロックは信用できません。

TEST ボタンを押すと、時刻同期が行えているかどうかチェックできます。
SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_15472220.jpg


SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_14155479.jpg


こうして、LANの入り口近くにDom0 やナマのハードウェアで NTP サービスを稼動させて、他のサーバやPCは全てこのサービスをチェックするようにします。minpoll , maxpoll などのポーリング間隔をここで指定します。注意するのはここで指定する値はビット値だということです。特に指定がなければ、デフォルトで64秒(min-大きくずれた stepmode )から1024秒(max-安定した状態)の間でポーリングを繰り返します。

http://doc.ntp.org/4.2.4/ntpd.html

-OES NetWare の場合-

Monitor > Server Parameter > Time に時刻同期の設定があります。
SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_16302689.jpg


デフォルトの最大ポーリング間隔は600秒(10分)です。
TID 2949745 Timesync Frequently Asked Questions

eDirectory はメジャーなPC用システムとしては、初めて時刻同期を導入しました。非常に時刻同期については敏感です。 OES NetWare/Linux 混在環境では Timesync.nlmのNCP同期 と NTPD が混在するため、移行計画は慎重に行います。

-Windowsの場合-

Windows の場合、次のように設定はシンプルです。導入当初はほとんど time.windows.com への同期ですが、この設定が悪評の w32tm のエラーを発生させます。
SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_125043.jpg


Windows の場合、つぎのような公式サイトの情報が役に立ちます。

Windows Server 2003 で Windows 以外の NTP サーバーとの同期が成功しない

W32Time サービスのレジストリ エントリ

多くの設定は次のレジストリの値を調整します。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters

SUSE Linux 仮想環境で仮想マシンの時刻のズレを修正する_a0056607_1104042.jpg


※ もちろんレジストリを操作することはあまりお勧めするものではありません。バックアップを取ってから行うことです。レジストリの内容そのものはあまり期待せずマイクロソフトにお問い合わせください。

Windows にはシンプルな GUI で時刻の設定が行えますが、複数のサーバを同期元としては定義できないようです。ドメインコントローラなら、コントロールパネルのどこかの「詳細」ボタンの秘密のタブの「詳細設定」の中にあるのかも知れません。見つけたらコメントください。Period パラメータは明示しない場合は一日わずか3回同期をとることがデフォルトのようです。その他のパラメータも多くありますが、詳細に解説したものはこちらにあります。
Windows Time サービスの基本処理

Windows タイム サービスを構成する ※追記
https://technet.microsoft.com/ja-jp/library/cc731191.aspx
次のコマンドがよさそうです。

Windows タイム サービスを構成する

w32tm /stripchart /computer:<ターゲット> /samples:<個数> /dataonly
w32tm /config /manualpeerlist:<ピア> /syncfromflags:manual /reliable:yes /update

例えば nict の ntp サービスに切り替える場合
> ntp.nict.jp にサンプリング先を変える
w32tm /stripchart /computer:ntp.nict.jp /samples:1 /dataonly

> ntp.nict.jp に問い合わせ先を変えるためにレジストリを変更する。
w32tm /config /manualpeerlist:ntp.nict.jp /syncfromflags:manual /reliable:yes /update

これでおバカで仮想化されると UTC になりたがるAD の Windows のドメインコントローラーの時刻は JST で、国内の ntp サーバーと同期を取ることができます。

タスクマネージャに

> net time \\MyNTPserver /set /yes
を設定する方法もあります。起動時と一定時間(NTPなみに10分ごと)に実行させるのもよい方法かもしれません。ただ、ntpd のように minpoll から maxpoll までに序々に「時間を寄せていく」というような機用なことはできないので注意が必要です。一度失敗するとその後8時間は同期しない仕様です。

-NTPD, Timesync の同期-

NTPも Timesync.nlm も動作としては、w32tm のように時間の誤差を一度に修正は行いません。一度に行うと多くのシステム時刻に同期しているアプリケーションに予測できない不具合が発生します。最小ポーリング間隔から始めて徐々に正確な時刻に「寄せて同期」します。10分遅れていると5分進め、次のポーリングで2分半、という感じですね。

この間は短い間隔でポーリングします。ほぼ同期が完了すると、デフォルトで10分の最大ポーリング間隔で時刻同期を観測状態に移行します。NTPD の場合、Step mode から Slow mode という言葉で表現されています。maxpoll の時間は調整できるので、同期がシビアではないシステムの場合は max poll を1時間などの値にしても良いでしょう。

Windows の場合、8時間おきの同期チェックに3度続けて失敗すると、いきなり45分に短縮されるというちょっと乱暴な動きを見せます。誤差が3分以上あるといきなり同期してしまうようですね。まだ同期するならいいのですが、余りに違いすぎると、全く同期しない場合があります。8時間で3度ということは最大24時間は時間がずれたまま運用される可能性があるということです。ドメイン管理者がまずやることはPDCうを再起動したら毎朝NTTの117番で正確な時刻を確認することです。

eDirectory では、大きな時間誤差が発生するとディレクトリオブジェクトに不具合が発生するため、 時刻同期が取れていないと、操作を阻止してくれます。Declare Epoch という最終手段でディレクトリオブジェクトの時刻を強制同期させなければ、ディレクトリのエラーがなくなりません。 もっとも数万人の巨大なディレクトリならば、細かに認証ディレクトリツリーの「ブランチ」ごとにパーティションを分けて、パーティションごとに数台で管理し、タイムスタンプの管理もオブジェクト単位ではなくオブジェクトのアイテムごとに管理するため、 declare epoch はでは最小のトラフィックで同期します。まず数十秒以内に綺麗に修正してくれます。

AD の場合はかなり大雑把な時刻同期のメカニズムなのでデフォルトで運用しているとディレクトリオブジェクトの不整合が頻繁に起こりそうな気がします。もっとも作り自体が大雑把なので、同期していなくても操作できてしまうというのも問題です。ADで巨大なドメインを作ると、タイムスタンプ管理が「オブジェクト丸ごと」でオブジェクトのアイテム単位でタイムスタンプを管理できません。eDirectory のように細かく認証ディレクトリをブランチごとにパーティション化できないので、時刻同期に問題が起こるとドメイン全体のタイムスタンプの修正にえらくトラフィックが発生して修正に手間がかかりそうです。

-強制的に時間を合わせる-

-Windows の場合
> w32tm /config /manualpeerlist:My_NTP_Server:0x8 /syncfromflags:MANUAL

-Linux の場合
# ntpdate My_NTP_Server

ということになるようですが、Windows の場合、時計のプロパティからNTTの117番で確認した「おおよそ」の時間を設定してポーリングで時刻同期を行うのがよさそうです。

-OES NetWare の場合
date, time コマンドで大まかに時刻をセットして、set timesync restart flag=on を実行します。後はポーリング間隔で同期することを待ちます。数分以内に時刻同期が完了します。

-同期の確認-

-Windows の場合

> w32tm /rsync を実行します

C:\>w32tm /resync
再同期のコマンドを送信: local computer...
コマンドは正しく完了しました。


失敗した場合はNTTの117に問い合わせます。

ただし、スタンドアローンな Windows サーバの場合、w32tm 自体が信頼できないので、meinverg 氏の ntpd を使った方が無難で便利です。特に複雑なことをしなくても10分おきにポーリングしてこまめに時刻を修正します。
http://www.meinberg.de/english/sw/ntp.htm

実際の使用感はこちらをご参考ください。
仮想化環境でのWindowsの時刻同期の問題

特にラップトップのようにドメインやイントラNTPと同期が取れない状況でもインターネットと繋がれば公開NTPと同期してくれるので愛用しています。何しろ w32tm ではひとつしか同期先を設定できないし、ドメイン管理下ではNTPの設定もできませんので便利です。

Windows のドメインの時刻同期は Windows 以外と相性がよくないようなので、「ナマのWindowsハードウェア」を仮想サーバとは別に用意して時刻サーバにするのがよいかも知れません。うまくいけば、Linux の NTPD と時刻同期ができる場合もあります。

-Linux の場合

# ntpq -p を実行します。
linux-c63e:~ # ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
LOCAL(0) .LOCL. 10 l 36 64 377 0.000 0.000 0.001
softbank2190571 219.188.200.128 3 u 956 1024 377 58.345 7.152 0.626
+ns.doga.co.jp 133.243.238.243 2 u 425 1024 377 67.948 16.031 3.188
*sylph.white-voi 150.26.2.66 2 u 996 1024 337 38.048 10.104 5.491
l inux-c63e:~ #


OES NetWare の場合

: tymesync debug=7 をセットして裏画面の同期状態をチェックします。また DSrepair に「時刻同期のチェック」があるので、この機能で全てのサーバが問題なく同期状態を保持していること確認します。

- 追記 2015/11/19 CMOS クロックの異常が原因 -
実際にあったことなのですが、マザーボードの故障が原因で、親鯖の時刻はあっているのに小鯖の時刻が狂うという現象があります。
Windows Server 2008 on AWS ~時刻同期の罠~
http://www.skyarch.net/blog/?p=1105#

上の例では AWSのインスタンスを別なサーバーに移動したら治った、というケースです。つまりハードウェアの故障です。親鯖のLinux は ntp などで時刻を取得してしまえば、CMOSが狂っていてもOS上では正しい時刻を保持できます。date コマンドを実行すれば、ほぼ正確な時刻を表示するでしょう。しかし完全仮想化された Windows の小鯖はいったん時刻ずれを起こすと親鯖のハイパーバイザーを経由して誤った CMOS クロックを参照しようします。準仮想化ではこのような現象は出ないようです。目の前で時計が早回しされてしまうという、どうしようもない Windows の時刻同期の仕様ですね。
- 追記終わり -


-まとめ-

- 外部の信頼できるタイムプロバイダーを2つ以上指定して社内の参照元とする。
- NTP が動作するPCは仮想マシンではなく、親(ホストコンピュータ)を使う。
- Windows のタイムソースは社内のタイムソースを ZENworks などで配信する。
- NTPD や Timesync ではほとんどデフォルトで運用して問題ないが、Windows は調整の要あり

こんなところでしょうか。

- Keyword -

SUSE Linux SLES 11 NTP Windows W32TM NetWare Timesync.nlm Time Syncronization

Visit my website islandcenter.jp-NTPD, Timesync

お問い合わせは
islandcenter.jp








by islandcenter | 2008-07-02 08:10 | プライベートクラウド | Comments(0)