Contents

Linux上的网络时间同步

1. 概述

Linux 应用程序需要准确且同步的时间才能正常运行。我们可以想到高可用集群、数据库等服务。因此我们需要使用可靠的时间源来同步我们系统的时钟。为此,我们依靠网络时间协议 (NTP)。

在本教程中,我们将学习如何在基于 RHEL 的系统上使用 NTP 配置和同步我们的系统时间。

2. 服务器时间和时区

在 Linux 系统上,我们有硬件和系统时钟。硬件时钟也称为实时时钟 (RTC)。即使服务器关闭,它也独立于内核运行。而系统时钟由操作系统维护

在 Linux 启动期间,硬件时钟更新系统时钟。但是硬件时钟不够可靠。出于这个原因,我们使用 NTP 从外部和更准确的时间源同步我们的系统时间。

另一个要提到的关键点是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 套件提供 NTP 时间同步。此软件包不需要定期轮询 NTP 服务器。因此,它适用于网络或互联网连接断断续续的环境。 如果还没有安装 chrony 包,作为 root 用户,我们可以运行:

# dnf install chrony

接下来,我们将看到如何配置 chrony 来同步我们的系统时间。

4. Chrony 作为 NTP 客户端

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选项的systemctlchronyd 配置为在服务器重启后自动启动。

最后,让我们检查一下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

让我们了解两个重要列的含义:

S列为我们提供了有关 NTP 源状态的详细信息。**星号*表示我们的系统当前与nero.grnet.gr同步。*而加号+*表示也可以考虑另外两台服务器进行同步。

Stratum列的取值范围为 1 到 15。具有较低值的时间源具有较高的精度。

我们已经看到“host1”正在与互联网上的 NTP 服务器同步时间。接下来让我们看看如何为我们称为“host2”的另一个节点启用 NTP。

5.配置NTP服务器

与“host1”不同,“host2”无法连接到互联网。为了克服防火墙限制,我们可以为本地网络上的“host2”提供时间。为了演示,我们将 chrony 设置为“host1”上的 NTP 服务器。

从“host1”,让我们使用选项*–list-services*运行命令firewall-cmd

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

从上面,我们看到防火墙不允许 UDP 端口 123 上传入的 NTP 数据包。

因此,让我们使用选项运行firewall-cmd命令 — permanent和 — add-service

# 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作为我们的时间服务器。我们使用/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选项将调试消息打印到终端。此外,我们将 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 服务器时间之间的偏移。