快速校准时间

在云计算环境,KVM Guest运行的操作系统在某些情况下比较容易出现时钟偏移,例如,如果qemu热升级,可能会短时间suspend住虚拟机,这会导致guest os恢复运行以后,时钟出现偏移。如果时钟偏移较大,由于ntpd服务是步进方式修正时间,所以修正过程可能会非常缓慢。

使用ntpdate快速校准时间

在操作系统首次启动的时候,有些发行版采用 ntpdate 命令快速矫正时间,然后继续启动 ntpd 服务确保服务器的时钟时钟准确。

我们在处理服务器时钟偏移矫正时,也可以采用类似方法。

需要注意:很多应用程序依赖正确的时钟,例如交易应用、加密通讯应用,当时钟差异较大,会导致会话失败;而且,如果时钟突然大幅变化,也会导致业务异常,甚至导致错乱的交易记录。所以,ntpd服务矫正时间是建议采用渐进步进方式校准,而不是大幅度修改系统时间。

  • 检查 /etc/ntp.conf 配置,获取当前服务器的时钟服务器列表

cat /etc/ntp.conf | grep server
  • 停止ntpd服务 - ntpdate和ntpd使用相同的socks,所以不能同时运行

systemctl stop ntpd
  • 使用ntpdate命令矫正时间,这里使用的 <ntp_server_ip> 是从 /etc/ntp.conf 配置中查询出来的服务器地址

ntpdate <ntp_server_ip>

ntpdate 命令支持多个ntp服务器,也就是可以同时提供多个ntp服务器地址,会自动选择最为准确的时间服务器进行同步,例如:

ntpdate 192.168.6.1 192.168.6.2 192.168.6.3

显示输出:

Mon May 24 20:59:13 CST 2021
24 May 21:00:07 ntpdate[467955]: step time server 192.168.6.1 offset 47.550589 sec
Mon May 24 21:00:07 CST 2021
  • 以下命令将校准时间写入本地时间(可选):

hwclock -w --localtime
  • 以下命令恢复ntpd服务运行:

systemctl start ntpd

(推荐)使用ntpdate快速校准时间

我使用上述 ntpdate 方法校准服务器时间,我的同事向我提了一个问题:

最好不要通过查询 /etc/ntp.conf 而是通过一条命令就能更新时钟。因为每个机房都有自己的时钟服务器,要分析配置文件找本地机房时钟服务器逻辑复杂不好维护脚本。最好通过一个全局域名(dns view)之类的,一个域名(或ip)就能够更新时钟。

这个问题促使我查询并学习了一些有关NTP的资料,发现原来 ntpd 服务其实是提供了直接校准时间的命令参数的,只是我们平时都是配置了ntpd服务持续维持正确时间,而忽视了这个功能参数。

通常情况下 ntpd 对于时钟的校准是缓慢步进方式的,所以对于时钟差异较大的时间调整非常缓慢。此外,如果是服务器启动时的主机时钟(由计算机内集成的time-of-year 芯片,也称为TOY芯片,维持关闭时期的时间)和ntp服务器时间差异超过1000s,则ntpd认为出现非常错误,ntpd会自动退出并发出紧急消息。

不过,ntpd也提供了一个快速校准时钟的参数 -g ,这个参数会忽略TOY芯片时间,并且直接将时钟设置为ntp服务器时间。注意,一旦时钟设置,大于1000s的时钟差异错误依然会让ntpd退出。

为了能够快速正确校准时钟,同时让ntpd服务在校准时钟之后立即退出(方便我们再次以daemon方式运行ntpd),我们通常会结合 -q参数来使用 -g参数,也就是 ntpd -gq,这样通过ntpd命令校准时间后自然退出,我们就可以在正确的时钟情况下,重新启动 ntpd服务来维护主机时钟。

举例:

  • 首先我们停止ntpd服务,然后将时间调整错误值

systemctl stop ntpd
date
  • 使用 date 命令检查当前正确时间

Tue May 25 14:22:29 CST 2021
  • 使用 date -s 命令设置一个错误时间

date -s "2 May 2021 1:1:1"

此时显示系统时间被调整成错误时间:

Sun May  2 01:01:01 CST 2021
  • 执行时钟校准命令 - 这个命令不需要指定ntp服务器,服务器配置是从 /etc/ntp.conf 配置中读取的

ntpd -gq

此时可以看到ntpd服务启动并设置时间,然后自然退出:

 2 May 01:01:13 ntpd[15472]: ntpd 4.2.8p10@1.3728-o Thu May 18 14:01:20 UTC 2017 (1): Starting
 2 May 01:01:13 ntpd[15472]: Command line: ntpd -gq
 2 May 01:01:13 ntpd[15472]: proto: precision = 0.112 usec (-23)
 2 May 01:01:13 ntpd[15472]: switching logging to file /var/log/ntp.log
 2 May 01:01:13 ntpd[15472]: Listen and drop on 0 v6wildcard [::]:123
 2 May 01:01:13 ntpd[15472]: Listen and drop on 1 v4wildcard 0.0.0.0:123
 2 May 01:01:13 ntpd[15472]: Listen normally on 2 lo 127.0.0.1:123
 2 May 01:01:13 ntpd[15472]: Listen normally on 3 eth0 192.168.6.201:123
 2 May 01:01:13 ntpd[15472]: Listening on routing socket on fd #20 for interface updates
25 May 14:24:15 ntpd[15472]: ntpd: time set +2035372.774127 s
ntpd: time set +2035372.774127s
  • 再次 date 检查时间就可以看到正确时钟

Tue May 25 14:24:22 CST 2021
  • 然后我们就可以启动ntpd服务以便维护好系统准确时间

systemctl start ntpd

参考

Last updated