NTPによる同期について
サーバに関わらず、PCや携帯電話など最近は様々なデバイスが時刻同期をしています。ただ、時刻同期がされていることを認識していても、どのようにされているのかについては知らない人が多いのではないでしょうか。ひょんなことからNTPに関して調査する機会があったので、備忘録としてまとめます。
情報量としては、「とあるSIerの憂鬱」のこちらの記事が詳しいです。
ほんともう、私が書くことが無いくらいに。
NTPとは何ぞや
Network Time Protocolとは、ネットワーク上に接続されている機器の時刻を正しい時刻に同期するために用いられるプロトコルです。今現在NTPのバージョンは4が標準になっています。
詳しい実装は以下のRFCに基づいています。
RFC 5905 - Network Time Protocol Version 4: Protocol and Algorithms Specification
時刻同期の大まかな流れ
時刻同期の仕組みを大まかに記載すると以下のような流れになります。
全体像(RFCより抜粋)
..................................................................... . Remote . Peer/Poll . System . Clock . . Servers . Processes . Process .Discipline. . . . . Process . .+--------+. +-----------+. +------------+ . . .| |->| |. | | . . .|Server 1| |Peer/Poll 1|->| | . . .| |<-| |. | | . . .+--------+. +-----------+. | | . . . . ^ . | | . . . . | . | | . . .+--------+. +-----------+. | | +-----------+. . .| |->| |. | Selection |->| |. +------+ . .|Server 2| |Peer/Poll 2|->| and | | Combine |->| Loop | . .| |<-| |. | Cluster | | Algorithm |. |Filter| . .+--------+. +-----------+. | Algorithms |->| |. +------+ . . . ^ . | | +-----------+. | . . . | . | | . | . .+--------+. +-----------+. | | . | . .| |->| |. | | . | . .|Server 3| |Peer/Poll 3|->| | . | . .| |<-| |. | | . | . .+--------+. +-----------+. +------------+ . | . ....................^.........................................|...... | . V . | . +-----+ . +--------------------------------------| VFO | . . +-----+ . . Clock . . Adjust . . Process . ............
- Peer/Poll Processes:サーバ間で時刻情報や相互同期するための情報をやり取りする
- System Process:通信相手が時刻同期する相手として相応しいかふるいにかける
- Clock Discipline Process:システムクロックの時間と周波数を制御する
- Clock Adjust Process:Clock Discipline Processと連携してシステム時刻を調整する
その中で、時刻の同期先を選択する(ふるいにかける)のはSystem Processです。
System Process(RFCより抜粋)
+-----------------+ | clock_select() | +-----------------+ ................................|........... . V . . yes +---------+ +-----------------+ . . +--| accept? | | scan candidates | . . | +---------+ | | . . V no | | | . . +---------+ | | | . . | add peer| | | | . . +---------- | | | . . | V | | . . +---------->-->| | . . | | . . Selection Algorithm +-----------------+ . .................................|.......... V no +-------------------+ +-------------| survivors? | | +-------------------+ | | yes | V | +-------------------+ | | Cluster Algorithm | | +-------------------+ | | | V V yes +-------------------+ |<------------| n < CMIN? | | +-------------------+ V | +-----------------+ V no | s.p = NULL | +-------------------+ +-----------------+ | s.p = v_0.p | | +-------------------+ V | +-----------------+ V | return (UNSYNC) | +-------------------+ +-----------------+ | return (SYNC) | +-------------------+
こちらの大まかな流れは、時刻同期先の候補となるNTPサーバ群から、NTPサーバの時刻情報や遅延などを考慮して同期先として相応しいかを決定します。決定する仕組みはNTPサーバの時刻情報のズレないし遅延時間から選定に用いる範囲(インターバル)を作成し、過半数のNTPサーバが属することができる範囲を妥当であると判断します。その範囲に属しているNTPサーバは時刻同期先の候補とし、属さないNTPサーバを除外することでふるいにかけます。つまりは多数決です。
最後にNTPサーバの階層構造や遅延などから同期先にふさわしいNTPサーバを選択します。
NTPサーバが同期できない場合
先のセクションで書きましたが、時刻同期にふさわしいサーバ群は日本の政治よろしく多数決によって決まります。NTPサーバが1台の場合の場合は無投票でそのサーバが選任されます。しかし、2台の場合はどうでしょう。2台中2台が候補に属していればよいですが、2台のNTPサーバの時刻がずれている場合、どちらが正しい時刻情報なのか判別できなくなります。この場合、NTPは同期することが不可能となり、時刻同期の仕組みそのものが破たんします。
時刻同期が破たんしないようにするには
NTPのサイトでは、時刻同期のサーバの数は4以上を推奨しています。
理由は以下の通り。
- 同期先が1台の場合、同期先の時刻が正しいか判別できません。また1台構成のため、そのサーバと同期できなくなると、時刻同期そのものが出来なくなります。
- 同期先が2台の場合、どちらが正しいか判別できません。
- 同期先が3台の場合、1台の同期先の時刻情報がおかしい場合でも対応できます。しかし、残り2つのサーバから同期先を選ぶ必要があります。
- 同期先が4台以上の場合、1台または複数の同期先の時刻情報が正しい場合でも時刻同期が可能です。
NTPサーバは2台しかない。でも同期処理が破たんすることは防ぎたい
Red Hatのこちらの情報の通りですが、優先接続先を指定することで破たんを回避することができます。ただし、この場合、優先接続先に指定したサーバの時刻が正しいことを担保できないことに注意が必要です。
Windowsの場合、同期先が複数指定できないのだけど
Windowsの場合、複数のNTPサーバをGUIでは設定することができません。複数指定するためにはレジストリを編集する必要があり、@ITのこちらに設定方法が記載されています。また、同様の内容がマイクロソフトのWindows Time サービスにおける時刻同期の仕組みにも記載されています。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters\NTPServer
サーバのあとに記述するフラグの値は以下の通り。
- 0x9(Clientモード)
- 0x1(Symmetric Activeモード)
- 0x2(Symmetric ActiveモードのFallback用)
- 0x8(RFC1305版Clientモード)
- 0x4(RFC1305版Symmetric Activeモード)
Clientかつスタンバイで指定する場合はフラグ値の足し算になるもよう…。
手元の環境で試したところ、確かにそれっぽく動いているように見えるが真偽は不明。