我有两个联网的 voxls,我正在尝试使用 chrony 进行同步。voxls 以截然不同的系统时间启动,就像相隔数年一样。我希望 chrony 在服务开始使用时同步时间makestep
,但在启动 chrony 后,我仍然观察到系统时间有很大差异。
配置如下:
#server 10.0.0.102
makestep 1.0 3
driftfile /var/lib/chrony/drift
rtcsync
allow 10.0.0
local stratum 8
manual
logdir /var/log/chrony
#client 10.0.0.101
server 10.0.0.102 iburst maxpoll 5 prefer
makestep 1.0 3
driftfile /var/lib/chrony/drift
rtcsync
logdir /var/log/chrony
当 chrony 启动时,我希望它能makestep
一口气同步客户端,我看到 systemclt 状态中的时间调整
root@voxl1:~# systemctl status chronyd
● chronyd.service - NTP client/server
Loaded: loaded (/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2023-02-01 21:34:52 UTC; 83 years 0 months ago
Process: 3086 ExecStart=/usr/sbin/chronyd $OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 3088 (chronyd)
CGroup: /system.slice/chronyd.service
└─3088 /usr/sbin/chronyd
Feb 01 21:34:52 voxl1 systemd[1]: Starting NTP client/server...
Feb 01 21:34:52 voxl1 chronyd[3088]: chronyd version 2.4 starting (+CMDMON +NTP +REFCLOCK +RTC -PRIVDROP -...EBUG)
Feb 01 21:34:52 voxl1 chronyd[3088]: Frequency -0.681 +/- 0.232 ppm read from /var/lib/chrony/drift
Feb 01 21:34:52 voxl1 systemd[1]: Started NTP client/server.
Feb 01 21:34:56 voxl1 chronyd[3088]: Selected source 10.0.0.102
Feb 01 21:34:56 voxl1 chronyd[3088]: System clock wrong by 2619696428.415401 seconds, adjustment started
Feb 07 11:02:04 voxl1 chronyd[3088]: System clock was stepped by 2619696428.415401 seconds
如果我使用chronyc tracking
orchronyc sources
观察时间偏移,报告表明时间在 100 微秒内同步。
root@voxl1:~# chronyc tracking
Reference ID : 10.0.0.102 (10.0.0.102)
Stratum : 9
Ref time (UTC) : Sun Feb 07 11:08:34 2106
System time : 0.000066503 seconds slow of NTP time
Last offset : -0.000076736 seconds
RMS offset : 0.000044063 seconds
Frequency : 0.785 ppm slow
Residual freq : -0.216 ppm
Skew : 0.987 ppm
Root delay : 0.004293 seconds
Root dispersion : 0.000069 seconds
Update interval : 129.8 seconds
Leap status : Normal
root@voxl1:~# chronyc sources -v
210 Number of sources = 1
.-- 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
===============================================================================
^* 10.0.0.102 8 6 377 46 -77us[ -109us] +/- 1953us
但是,如果我然后打印日期,它根本不匹配时间服务器。
客户端 10.0.0.101
root@voxl1:~# date
Sun Feb 7 11:12:00 UTC 2106
服务器 10.0.0.102
root@voxl2:~# date
Thu Jan 1 04:43:02 UTC 1970
然后我试图触发一个手册chronyc makestep
,但这似乎也没有效果。
为什么我的日期不一样?makestep 是否按预期工作?chronyc makestep
时钟走多远有限制吗?
编辑:我有一个假设,但我不知道如何检验它。我想我可能会看到下溢错误。1970 年 1 月 1 日是 Unix 纪元。我的假设是当 chrony 第一次尝试在启动时同步客户端时,它会产生下溢错误,我看到了 systemctl 消息
Feb 01 21:34:56 voxl1 chronyd[3088]: System clock wrong by 2619696428.415401 seconds, adjustment started
Feb 07 11:02:04 voxl1 chronyd[3088]: System clock was stepped by 2619696428.415401 seconds
那个不正确的步骤将客户端推送到 2106,chrony 现在认为它与服务器同步,这就是为什么进一步的 makesteps 没有效果并且偏移量看起来很小的原因。
任何想法如何检验这个假设?
是的,有一个限制。同样的限制意味着 NTP 将在 2036 年滚动。
NTP 时间戳格式基于 32 位秒(和 32 位秒的小数)或 136 年,也称为一个NTP 时代。这些之间的差异是正负 68 年。在没有对您所处的时代做出假设的情况下,这是安全的时间增量。
在实践中,实现将更加保守,并假设时代在数据结构的限制之前发生了变化。chrony 的配置脚本默认为构建日期前 50 年。换句话说,大约三年来,1970 年被认为是一个不同的 NTP 时代。它不是,但通常可以假设时钟是在过去 5 年的某个时候设置的。
chrony 计算出的 delta 会在这个时代之前出现。所以它假设时代结束了,做数学模型 136 年。今年减去 1970 年是 53 年前。136 减 53 是 83,这是你的巨大偏移量:
另一种看待 NTP 时代事物的方式是比较那些服务器和客户端时间戳。将两者转换为 UNIX 纪元秒(
date +%s
来自 GNU coreutils),减去 2^32,并减去较小的,它们只相差 42。1970年的服务器时间不平凡。截至 2023 年,我们已经过了 1970-01-01 00:00:00 UTC 16 亿秒。
使用实时时钟。无论客户在被踩踏之前开始做什么似乎都是合理的?不需要准确,让十年正确将是一种改进。即使硬件或软件以硬编码日期开始,也可以纠正,类似于电池没电的 RTC。
为您的 NTP 服务器添加更可靠的时间源。如果你有互联网添加
pool 2.pool.ntp.org
到 chrony.conf。而且,在天空清晰可见的情况下,卫星导航天线可以添加准确的时钟,而无需通过 IP。