1. 概要

Linuxアプリケーションを正しく実行するには、正確で同期された時間が必要です。 高可用性クラスター、データベースなどのサービスを考えることができます。 したがって、信頼できるタイムソースを使用してシステムのクロックを同期する必要があります。 これを実現するために、ネットワークタイムプロトコル(NTP)に依存しています。

このチュートリアルでは、RHELベースのシステムでNTPを使用してシステム時刻を構成および同期する方法を学習します。

2. サーバーの時間とタイムゾーン

Linuxシステムには、ハードウェアとシステムクロックがあります。 ハードウェアクロックは、リアルタイムクロック(RTC)とも呼ばれます。  サーバーがシャットダウンしている間でも、カーネルから独立して実行されます。 システムクロックはOSによって維持されます。

Linuxの起動時に、ハードウェアクロックがシステムクロックを更新します。 しかし、ハードウェアクロックは十分に信頼できません。 そのため、NTPを使用して、外部のより正確なタイムソースからシステム時刻を同期します。

言及すべきもう1つの重要な点は、NTPはUTCタイムゾーンに基づいているということです。 したがって、システムのタイムゾーンを適切に構成する必要があります。

まず、timedatectlで時刻情報を表示しましょう。

$ timedatectl
      Local time: Fri 2022-04-29 14:24:42 EDT
  Universal time: Fri 2022-04-29 18:24:42 UTC
        RTC time: Fri 2022-04-29 18:24:42
       Time zone: America/Toronto (EDT, -0400)
    NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: yes
 Next DST change: DST ends (the clock jumps one hour backwards) at
                  Sun 2022-11-06 01:59:59 EDT
                  Sun 2022-11-06 01:00:00 EST

次に、コマンド timedatectl list-timezones を使用して、使用可能なすべてのタイムゾーンを一覧表示できます。

$ timedatectl list-timezones | grep "^Europe/"
Europe/Amsterdam
Europe/Andorra
Europe/Astrakhan
Europe/Athens
Europe/Belgrade
Europe/Berlin
...

grep コマンドを使用して、Europe/。で始まるすべての行を照合します。

最後に、スーパーユーザーとして、ローカルタイムゾーンを設定し、timedatectl出力を出力しましょう。

# timedatectl set-timezone Europe/Athens; timedatectl 
      Local time: Fri 2022-04-29 21:43:21 EEST
  Universal time: Fri 2022-04-29 18:43:21 UTC
        RTC time: Fri 2022-04-29 18:43:21
       Time zone: Europe/Athens (EEST, +0300)
       ...

現地時間が正しいタイムゾーンにあるのに対し、デフォルトのRTC時間はUTCになっていることがわかります。

3. Chronyのインストール

chronyスイートはNTP時刻同期を提供します。 このパッケージは、NTPサーバーの定期的なポーリングを必要としません。 したがって、断続的なネットワークまたはインターネット接続のある環境に適しています。

chronyパッケージがまだインストールされていない場合は、rootユーザーとして次のコマンドを実行できます。

# dnf install chrony

次に、システム時刻を同期するようにchronyを構成する方法を説明します。

4. NTPクライアントとしてのChrony

4.1. 構成

chrony構成ファイルは/etc/chrony.confです。 事前定義されたNTPサーバーのアドレスを表示してみましょう。

$ grep ^server /etc/chrony.conf
server 0.gr.pool.ntp.org
server 1.gr.pool.ntp.org
server 2.gr.pool.ntp.org
server 3.gr.pool.ntp.org

私たちのシステム「host1」はインターネットにアクセスできるので、www.pool.ntp.orgから利用可能なパブリックNTPプールから選択できます。

説明のために、NTPサーバーを優先タイムゾーンに基づいて選択したサーバーに置き換えてみましょう。

$ grep "server " /etc/chrony.conf
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server 0.gr.pool.ntp.org iburst
server 1.gr.pool.ntp.org iburst
server 2.gr.pool.ntp.org iburst
server 3.gr.pool.ntp.org iburst

テキストエディタを使用して、先頭に記号を挿入することにより、デフォルトのNTPサーバーの行をコメントアウトします。 次に、新しいNTPアドレスを追加します。

初期同期を高速化するために、iburstのデフォルトオプションを維持していることに注意してください。

次に、サービスを開始して有効にします。

# systemctl start chronyd
# systemctl enable chronyd

上記では、enableオプションを指定したsystemctlは、サーバーの再起動後に自動的に起動するようにchronydを構成します。

最後に、chronydサービスのステータスを確認しましょう。

$ systemctl status chronyd
 chronyd.service - NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-04-29 21:44:52 EEST; 26s ago

chronyd が実行されたので、時間同期を監視する方法を見てみましょう。

4.2. 時間同期の管理

chronyc コマンドを使用して、NTPのステータスを確認できます。 sourcesオプションと-vフラグを指定してコマンドを実行し、より詳細な出力を行います。

$ chronyc sources -v
210 Number of sources = 4
  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
||                                                 .- xxxx [ yyyy ] +/- zzzz
||      Reachability register (octal) -.           |  xxxx = adjusted offset,
||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
||                                \     |          |  zzzz = estimated error.
||                                 |    |           \
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^- ipa225.1.tellas.gr            1   9   377   128    +65ms[  +65ms] +/-  560ms
^* nero.grnet.gr                 1   9   377   397   -448us[ -298us] +/-   56ms
^+ ipa95.24.tellas.gr            3   8   377   131  +3252us[+3252us] +/-   90ms
^+ ns4.asda.gr                   2   9   377     8   -642us[ -642us] +/-   87ms

2つの重要な列の意味を理解しましょう。

S 列には、NTPソースの状態に関する詳細が表示されます。 アスタリスク*は、システムが現在nero.grnet.grと同期されていることを意味します。 プラス記号+は、他の2台のサーバーも同期の対象と見なすことができることを示します。

Stratum 列は、1から15の範囲の値を取ります。 値が小さい時間ソースの方が精度が高くなります。

「host1」がインターネット上のNTPサーバーと時刻を同期していることを確認しました。 次に、「host2」と呼ばれる別のノードでNTPを有効にする方法を見てみましょう。

5. NTPサーバーの構成

「host1」とは異なり、「host2」はインターネットに接続できません。 ファイアウォールの制限を克服するために、ローカルネットワーク上の「host2」に時間を提供できます。 実例を示すために、「host1」でNTPサーバーとしてchronyを設定しました。

「host1」から、オプション –list-servicesを指定してコマンドfirewall-cmdを実行してみましょう。

# firewall-cmd --list-services
dhcpv6-client ftp ssh tftp

上記から、ファイアウォールがUDPポート123での着信NTPパケットを許可していないことがわかります。

したがって、オプション— permanent および— add-serviceを指定してfirewall-cmdコマンドを実行してみましょう。

# firewall-cmd --permanent --add-service ntp
success

ルールが正常に追加され、再起動しても永続的になっていることがわかります。

その後、 reload オプションを使用して新しいファイアウォールルールをロードし、アクティブにします。

# firewall-cmd --reload
success

次に、ローカルサブネットからNTPサーバーへのアクセスを許可します。

$ grep ^allow /etc/chrony.conf
allow 192.168.5.1/24

最後に、chronydサービスを再起動しましょう。

# systemctl restart chronyd

「host2」から、/etc/chrony.confファイルのserverディレクティブを更新します。

$ grep ^server /etc/chrony.conf
server host1

タイムサーバーとしてhost1を使用していることに注意してください。 [X5X] / etc / hosts ファイルを使用して、host1をそのIPアドレスにマップします。

最後に、構成をテストするために、-dおよび-Qフラグをchronydコマンドに渡します。 -Q オプションを使用して、システムクロックを調整せずにNTPサーバーにクエリを実行します。

$ chronyd -d -d -Q "server host1 iburst" 
2022-04-29T22:21:13Z main.c:515:(main) chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
...
2022-04-29T22:21:13Z ntp_sources.c:479:(resolve_sources) resolving host1
2022-04-29T22:21:13Z ntp_sources.c:407:(name_resolve_handler) host1 resolved to 1 addrs
2022-04-29T22:21:13Z ntp_sources.c:380:(process_resolved_name) (1) 192.168.5.102
2022-04-29T22:21:13Z ntp_core.c:1176:(transmit_timeout) Transmit timeout for [192.168.5.102:123]
2022-04-29T22:21:13Z ntp_io.c:896:(NIO_SendPacket) Sent 48 bytes to 192.168.5.102:123 from [UNSPEC] fd 4
2022-04-29T22:21:13Z ntp_io.c:698:(process_message) Received 48 bytes from 192.168.5.102:123 to 192.168.5.103 fd=4 if=2 tss=1 delay=0.000089723
...
2022-04-29T22:21:15Z ntp_core.c:1176:(transmit_timeout) Transmit timeout for [192.168.5.102:123]
2022-04-29T22:21:15Z ntp_io.c:896:(NIO_SendPacket) Sent 48 bytes to 192.168.5.102:123 from [UNSPEC] fd 4
2022-04-29T22:21:15Z ntp_io.c:698:(process_message) Received 48 bytes from 192.168.5.102:123 to 192.168.5.103 fd=4 if=2 tss=1 delay=0.000085051
...
2022-04-29T22:21:17Z reference.c:905:(special_mode_sync) System clock wrong by 194.827846 seconds (ignored)
...

上記のコマンドでは、 -d オプションを2回使用して、デバッグメッセージを端末に出力します。 また、NTPサーバーアドレスをhost1。として指定します。

生成されたメッセージから、NTPサーバーがクライアントの要求に応答していることがわかります。 ただし、クライアントのシステム時刻はNTPサーバーの時刻とは異なります。 オフセットは約194秒です。

次に、「host2」の時刻を「host1」のNTPサーバーと手動で同期する方法を見てみましょう。

6. 時間を手動で更新する

chronyd を使用して、コマンドラインからシステムクロックを設定できます。 -q オプションを指定して実行し、時計を更新しましょう。

$ chronyd -q "server host1 iburst"
2022-04-29T22:26:46Z chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
2022-04-29T22:26:50Z System clock wrong by 194.831537 seconds (step)
2022-04-29T22:26:50Z chronyd exiting

手動で時刻を更新した後、 chronyd-Qを使用して測定されたオフセットを再度印刷できます。

$ chronyd -Q "server host1 iburst"
...
2022-04-29T22:27:17Z System clock wrong by 0.001776 seconds (ignored)
...

以上のことから、システムクロックとNTPサーバーの時刻との間のオフセットを減らすことができました。

7. 結論

この記事では、NTPサービスについて説明しました。 タイムゾーンを適切に設定し、時刻同期のためにNTPクライアントとサーバーを構成する方法を学びました。