朝から昼寝

整理しておきたいIT関連の小ネタ

Chronyによる時刻同期ノウハウ1(基本的な設定)

概要

Chronyは、RHEL7、CentOS7以降におけるデフォルトの時刻同期機能(NTP実装)です。従来はntpdがありました。
本記事は、常時起動させておくサーバにおいてChronyをNTPクライアントとして使用する方法をまとめたものです。主に、RHEL7、CentOS7以降でOS標準のChronyを使用した環境を対象としていますが、基本的にはどのシステムでも共通です。

別記事に、NTPサーバの複数指定や移行についてもまとめてあります。

本記事の目的

  • ChronyでNTPサーバを参照して時刻同期する。
  • 時刻ズレやうるう秒の発生時に考慮すべきポイントを抑えておく。


目次

基本

参照先NTPサーバの指定(server)

設定ファイルを編集します。
# vi /etc/chrony.conf

#server 0.rhel.pool.ntp.org   iburst 
#server 1.rhel.pool.ntp.org   iburst 
#server 2.rhel.pool.ntp.org   iburst 
#server 3.rhel.pool.ntp.org   iburst
server ntp-server1.domain.com iburst
server ntp-server2.domain.com iburst

serverディレクティブは使用するNTPサーバを指定します。上記の1~4行目は、RHEL用のデフォルト設定です。別のNTPサーバを使用する場合には、全てコメントアウトします。
新たにserver行を追加し、ntp-serverX.domain.com部分に参照先NTPサーバを記載します。

iburstオプションは、chronyd起動時、NTPサーバに対し短い間隔で4回問合せし、早く時刻同期できるようにするものです。特に理由が無ければiburstを記載したままで良いです。

参照するNTPサーバが複数ある場合、複数行に分けて記載します。

もう少し詳しい内容や、serverpoolの違い等については、別記事にまとめてあります。

設定反映

/etc/chrony.confの変更後はサービスを再起動して設定反映します。
# systemctl restart chronyd
# systemctl status chronyd

…
Active: active (running) since xxx
…

Active:行が「active (running)」、since xxxが# systemctl restartを実行した時刻になっていればサービス再起動完了です。

動作確認

NTPサーバと時刻同期できていることの確認(chronyc sources)

$ chronyc sources

MS Name/IP address         Stratum Poll Reach LastRx Last sample               
========================================================
^* ntp-server1.domain.com          1   3   111    22  -1000us[ -100ms] +/-   10ms
^? ntp-server2.domain.com          1   3   111    22  -1000us[ -100ms] +/-   10ms
※値はダミーです

行頭が ^* になっている行のNTPサーバと時刻同期できています。
行頭が ^? になっている行のNTPサーバとは、通信が成功していません。NTPサーバの状況確認や、ファイアウォールの設定確認等の対処が必要です。
通信可能なNTPサーバであっても、chronydのサービス起動後、数秒~数十秒(長くて数分程度)は^? のままで、その後 ^* になります。
各項目の簡易説明は$ chronyc -v sourcesで表示できます。詳細は$ man chronycで確認できます。
他に$ chronyc trackingというオプションもあるので、それは後述します。

詳細

stepモードによる時刻同期の考慮(makestep)

chronyd のデフォルト設定では、サービス起動時にシステムクロックの時刻がNTPサーバと大幅にズレていた場合、一気に時刻修正(stepモード)が行われます。
デフォルトではchrony.confの「makestep 1.0 3」という設定により、chronyd起動直後のNTPサーバとのやり取り時に1.0 秒以上の時刻ズレが3回続けて検知された場合にstepモードで時刻修正されます。
一気に時刻修正されると問題があるシステムでは、この設定を予め無効化するか、より詳細に時刻関連の設定をチューニングしましょう。例えば、時刻を正確に扱う必要性のあるデータベースシステムなどです。
無効化する場合は、chrony.confのmakestep行をコメントアウトしてchronydを再起動します。
# vi /etc/chrony.conf

#makestep 1.0 3

なお、このmakestepによる動作は、chronydのサービス起動時に適用されます。つまり、OS再起動時だけでなく、chronydのサービスを再起動しただけでも適用されます。
makestepによる動作を無効化した環境では、サービス起動時にシステムクロックの時刻がNTPサーバと大幅にズレるような状況が生じないよう注意が必要です(サスペンドからの復帰時等)。ズレが大きすぎると、NTPサーバとうまく同期できなかったり、時刻修正の完了までに時間がかかる可能性があります。

うるう秒発生時の振る舞いの考慮(leapsecmode)

数年に1度、うるう秒により60秒目が挿入されることがあります。23:59:60(日本時刻で8:59:60)。システムによっては問題が生じる可能性があるため、うるう秒発生時の振る舞いを考慮しておく必要性があります。

2035年までにうるう秒が廃止される件については、別記事にまとめてあります。

ChronyをNTPクライアントとして使用する場合

leapsecmodeディレクティブにより、うるう秒発生時の動作を指定します。

leapsecmodeのデフォルトは"system"です。これはシステムクロックが23:59:59を2回刻むことになるので、1秒間の時刻の逆進が発生します。なお、OSがうるう秒をサポートしていない場合のデフォルト値は"step"です。"step"の場合も、うるう秒発生時の動作は"system"と同様ですが、カーネルでなくchronyがシステムクロックを修正します。

うるう秒発生時の1秒間の逆進を回避したい場合、"slew"の設定が可能です。

  • leapsecmode slew
    うるう秒発生時、システムクロックを徐々に修正します。うるう秒により生じる1秒の時刻差を、デフォルトでは12秒間で修正します(後述のmaxslewrate)。

その他、"ignore"の設定がありますが、"slew"で十分と思われます。

  • leapsecmode ignore
    うるう秒発生時、システムクロックに何も修正を加えません。chronydの通常動作として、その後徐々にシステムクロックを修正します。$ man chrony.confでは、このオプションは複数のchronydが動作する環境において有用であると記載されています(1つはシステムクロックを修正するもの、他はNTPサーバ等の用途(-x)で動作するもの)。

(参考)ChronyをNTPサーバとして使用する場合

ChronyをNTPサーバとして使用し、他のNTPクライアントから参照させる場合に、うるう秒発生時の時刻修正を緩やかにするための設定例です。
"$ man chrony.conf`では、うるう秒対策(leap smear)として、以下の設定例が記載されています。

leapsecmode slew
maxslewrate 1000
smoothtime 400 0.001 leaponly

この設定は、うるう秒挿入時に23:59:59を2回刻まずシステムクロックをゆっくり時刻調整(slewモード)します。また調整速度(maxslewrate)を1000ppmに抑えます(maxslewrateについては後述)。smoothtimeは正確に理解できていませんが、システムが長時間オフラインだった場合などに備え、時刻修正速度の変化を緩やかにするためのオプションのようです。うるう秒発生時にのみ適用されます(leaponly)。
このうるう秒対策の設定は一部の古いシステムでは対応不可のようですので、使用しているシステムのchronyのマニュアル等を確認しましょう。
なお、上記のmaxslewrate 1000は、デフォルトの約80分の1の値です。うるう秒挿入時だけでなく普段の時刻修正の最大速度が制限される設定であるという点は認識しておくべきです(maxslewrateについては後述)。
このうるう秒対策の日本語解説は、RedHat社のページにあります。

時刻修正の速さ(maxslewrate)

chronydは通常動作時、slewモードでゆっくり時刻修正されます。その時刻修正の最大速度がmaxslewrateで設定されます。
maxslewrateのデフォルト値は83333.333 ppmで、これは「1秒の時刻ズレを12秒間で修正」するものです。単位がppm(parts per million)なので、83,333.333 ÷ 1,000,000 ≒ 0.083 (1秒間に1/12秒くらい時刻修正する)ということです。1分間の時刻ズレを修正するのにかかる時間が最速で720秒(12分)です。
従来のntpdでは、500ppm相当の固定値でしたので、それに比べるとかなり速いです。
大きな時刻ズレが生じたときに、条件によってはずっと時刻修正が完了しないままになるといったようなトラブルを回避する上ではある程度速い方が良いです。

動作確認

NTPサーバとの時刻同期状況の詳細確認(chronyc tracking)

前述のchronyc sources以外に、以下のような確認も可能です。
$ chronyc tracking

(★マークは説明用の目印です)
Reference ID    : AB00123C (domain.com)
Stratum         : 1
Ref time (UTC)  : Fri Apr 29 01:22:33 2022
System time     :  0.000000555 seconds slow of NTP time ★
Last offset : -0.000000140 seconds ★ 
RMS offset : 0.000000280 seconds ★
Frequency       : 1.111 ppm slow
Residual freq   : 0.000 ppm
Skew            : 0.090 ppm
Root delay      : 0.00140302 seconds
Root dispersion : 0.001200221 seconds
Update interval : 54.1 seconds
Leap status     : Normal
※値はダミーです。

System Time:行は「X seconds slow of NTP time」と記載されていれば、NTPサーバより時刻がX秒遅れている、「X seconds fast of NTP time」と記載されていれば、NTPサーバより時刻がX秒進んでいるという意味です。
offsetは、算出されたシステムクロックとNTPサーバとの間の時刻差です。Last offsetは、前回の計測時のoffsetであり、正の値はシステムクロックがNTPサーバよりも時刻が進んでいることを示します。RMS offsetは、長期間の平均のoffsetです。

参考

他にもchronycにはオプションがあります。詳細は$ man chronycにて。
chrony.confの各設定詳細は$ man chrony.confにて。

Chronyの提供元は、tuxfamily.orgです。