一、chrony简单介绍
1.1 ntp协议简介
NTP是一种用于同步计算机网络时间的协议,它基于UDP协议,用于将网络中的计算机时钟同步到UTC(世界统一时间)。通过配合各个时区的偏移调整,NTP可以实现精准的时间同步功能。在Linux系统中,该NTP协议由运行在用户空间中的守护程序实现。
用户空间守护程序更新内核中运行的系统时钟。系统时钟可以通过使用各种时钟源来节省时间。通常,使用时间戳计数器(TSC)。TSC是一个CPU寄存器,用于计数自上次复位以来的周期数。它非常快,具有高分辨率并且没有中断。
1.2 chrony简介
Chrony是NTP协议的一种实现,它使用NTP协议来同步系统时间。与传统的NTP相比,Chrony具有更高的精度和更快的同步速度。Chrony通过与多个NTP服务器进行通信,使用具有自适应补偿精度的算法来计算时间偏差,并根据需要进行时间调整。此外,Chrony还提供了一些额外的功能,如纠正时钟频率偏差和对网络延迟的优化。
chrony包括两个程序:
- chronyd:一个在用户空间中运行的守护程序
- chronyc:一个命令行工具,用来监控chronyd的性能,也可以用来在chronyd运行时改变它的运行参数。
[root@iZj6ccjjtnsdvrl5u3l0p5Z ~]# ps -ef | grep chrony
chrony 558 1 0 22:15 ? 00:00:00 /usr/sbin/chronyd
[root@iZj6ccjjtnsdvrl5u3l0p5Z ~]# systemctl status chronyd.service
● chronyd.service - NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
Active: **active (running)** since Mon 2024-07-22 22:15:14 CST; 1h 40min ago
Docs: man:chronyd(8)
man:chrony.conf(5)
Main PID: 558 (chronyd)
Tasks: 1 (limit: 47654)
Memory: 980.0K
CGroup: /system.slice/chronyd.service
└─558 /usr/sbin/chronyd
7月 22 22:15:14 iZj6cbi9r4z8ew3byr9eczZ systemd[1]: Starting NTP client/server...
7月 22 22:15:14 iZj6cbi9r4z8ew3byr9eczZ chronyd[558]: chronyd version 3.5 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
7月 22 22:15:14 iZj6cbi9r4z8ew3byr9eczZ chronyd[558]: Frequency -36.148 +/- 0.130 ppm read from /var/lib/chrony/drift
7月 22 22:15:14 iZj6cbi9r4z8ew3byr9eczZ systemd[1]: Started NTP client/server.
7月 22 22:15:25 iZj6ccjjtnsdvrl5u3l0p5Z chronyd[558]: Selected source 100.100.61.88
7月 22 22:15:25 iZj6ccjjtnsdvrl5u3l0p5Z chronyd[558]: **System clock wrong by 1.195893 seconds, adjustment started**
默认情况下chronyd只接受来自本地chronyc实例的命令,但它也可以配置成接受来自远程chronyc实例的命令。远程连接需要被restricted。
注:chronyc默认通过socket访问本地chronyd进程,远程chronyc访问本地chronyd需要额外配置chronyd允许访问
1.3 chrony的工作原理
当chronyd启动时,它会首先尝试从配置文件中读取NTP服务器的信息。然后,它会与这些服务器建立连接,并交换时间信息。通过比较本地时间与服务器时间,chronyd可以计算出时间偏差和频率偏差,并据此调整系统时钟。同时,它还会根据网络状况和系统负载等因素,动态调整同步的间隔和精度。
Chrony的工作分为两个主要部分:时钟偏差的测量和时钟的校准。
- 时钟偏差的测量:Chrony定期向配置的时间服务器发送请求,收到响应后,它会计算往返延时和本地时钟与服务器时间的差异。
- 时钟的校准:根据测量的偏差,
chronyd会逐渐调整本地时钟的速度,减少与标准时间的差异。
同步时间周期: Chrony的同步周期不是固定的,它会根据网络条件和之前的同步精度动态调整。初次启动时,Chrony会更频繁地同步,以快速减小时钟偏差。随着时间的推移,如果网络条件稳定,Chrony会逐渐增长同步间隔,减少系统负载
- 监听端口: 323/udp,123/udp
- chrony并且兼容ntpd监听在udp123端口上,自己则监听在udp的323端口上
- 服务unit文件: /usr/lib/systemd/system/chronyd.service
- 配置文件: /etc/chrony.conf
1.4 chrony相比于ntp的优势
- chrony使用硬件时间戳来同步系统时钟的能力。这有助于提高在局域网(LAN)上同步时间的准确性
- Chrony在各种条件下都表现良好,包括间歇性网络连接,网络严重拥塞,温度变化(普通计算机时钟对温度敏感)以及无法连续运行或在虚拟机上运行的系统。
- 更快的同步只需要数分钟而非数小时时间,从而最大程度的减少时间和频率误差,这对于并非全天运行的台式计算机或系统而言非常有用。
- 能够更好的响应时间频率的快速变化,这对于具备不稳定时钟的虚拟机或导致时钟频率反复变化的节能技术而言非常有用。
- 在初始同步后,它并不会停止时钟,以防对需要系统时间保持单调的程序造成影响。
- 在应对临时非对称延迟时,(例如:大规模下载造成连接饱和时)提供了更好的稳定性。
- 无需对服务器进行定期轮询,因此具备间歇性网络连接的系统仍然可以快速同步时钟。
1.5 实际使用中的ntp服务
精确度:以阿里云香港地区ECS为例,采用阿里云默认ntp时钟源,通常时间精确度在us级别,但是波动较大(1us到几百us之间),偶发可能会出现ms级别延迟,如果业务特别敏感,可能会有业务感知。如果想要进一步提高精确度,需要采用其他方式,ptp、原子时钟等。
二、chronyd介绍
chronyd是实际进行时钟同步的守护进程
可以根据 man 5 chrony.conf 命令查看所有chrony.conf支持的配置参数
配置文件:/etc/chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
# 配置NTP服务器
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
# Record the rate at which the system clock gains/losses time.
# 记录系统时钟获得/丢失时间的速率至drift文件中
driftfile /var/lib/chrony/drift
# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
# 默认情况下,chronyd通过减慢或加快时钟速度来逐渐调整时钟。如果时钟与实际时间偏差太大,则需要很长时间才能纠正错误。这种方法叫做步进时钟(时间跳变)。
# 此处表示如果调整值大于1000秒,则这将使系统时钟步进,但仅在前十个时钟更新中。
makestep 1000 10
# Enable kernel synchronization of the real-time clock (RTC).
# 启用RTC(实时时钟)的内核同步
rtcsync
# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *
# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2
# Allow NTP client access from local network.
# 只允许192.168.网段的客户端进行时间同步
#allow 192.168.0.0/16
# Serve time even if not synchronized to a time source.
# NTP服务器不可用时,采用本地时间作为同步标准
#local stratum 10
# Specify file containing keys for NTP authentication.
# 指定包含NTP验证密钥的文件
#keyfile /etc/chrony.keys
# Specify directory for log files.
# 指定日志文件的目录
logdir /var/log/chrony
# Select which information is logged.
# 将对系统增益或损耗率的估计值以及所做的任何转换记录的更改记录到名为的文件中tracking.log。
#log measurements statistics tracking
# 其他未在默认配置文件的配置项
# 在第一次时钟更新之后,chronyd将检查每次时钟更新的偏移量,它将忽略两次大于1000秒的调整,并退出另一个调整。
maxchange 1000 1 2
# 该rtcfile指令定义中的文件名chronyd可以保存跟踪系统的实时时钟(RTC)的精度相关的参数。
rtcfile /var/lib/chrony/rtc
allow
- 功能:allow指令用来允许一个主机、子网或网络中的ntp客户端来访问该机器,将该机器作为ntp服务器。默认情况下不允许任何ntp客户端访问,也就是说chronyd纯粹作为一个ntp客户端运行。如果使用了allow指令,那么chronyd将既是它的服务器的客户端,也是其他ntp客户端的服务器
- 语法:
# 配置示例allow foo.example.net
allow 1.2 #允许ip为1.2.x.y的客户端访问
allow 3.4.5 #允许ip为3.4.5.x的客户端访问
allow 6.7.8/22 #允许6.7.8.x,6.7.9.x,6.7.10.x和6.7.11.x访问
allow 6.7.8.9/22 #效果同上
allow 2001:db8::/32 #ipv6
allow 0/0 #允许所有ipv4地址访问
allow ::/0 #允许所有ipv6地址访问
allow #允许所有客户端访问
# 条目顺序执行,配合deny可以进行筛选
# allow指令还有一个特殊用法allow all,它具有更大的效果,这取决于配置文件中指令的顺序。为了说明这一点我们看下面的两个配置示例:
#示例1
allow 1.2.3.4
deny 1.2.3
allow 1.2
# 示例1的配置,表示允许1.2.x.y的客户端访问,阻止其中的1.2.3.x的客户端访问,但是又允许1.2.3.4客户端访问。
#示例2
allow 1.2.3.4
deny 1.2.3
allow all 1.2
# 示例2中的配置,最终会允许1.2.x.y中的所有客户端访问。也就是指令allow all 1.2覆盖了前面deny 1.2.3指令的作用
bindcmdaddress
- 功能:修改chronyd绑定的用来与chronyc连接的网络接口。默认情况下chronyd与loopback接口绑定(ip为127.0.0.1和::1),也可以也可用来更改Unix domain command socket文件的路径
- 语法:
bindcmdaddress 0.0.0.0
bindcmdaddress ::
bindcmdaddress /var/run/chrony/chronyd.sock
注:对于ipv4和ipv6两种协议,bindcmdaddress指令各只能使用一次
log
- 功能:log指令设定日志记录哪些信息,log有下面几个可选项
- 语法:
log measurements statistics tracking
measurements:此选项记录原始NTP测量及相关信息到一个名为measurements.log的文件。
statistics:此选项记录有关回归处理(regression processing)的信息到一个名为statistics.log的文件。
tracking:此选项记录时间的增益或损耗率的变化,以及所做的更改到tracking.log文件。
rtc:此选项记录有关系统RTC时钟的信息。
refclocks:此选项记录原始的和过滤的参考时钟的测量信息到refclocks.log文件。
tempcomp:此选项记录温度测量信息以及系统速率补偿信息到tempcomp.log文件。
logdir
- 功能:设定日志文件的存储路径
- 语法:
logdir /var/log/chrony
makestep
- 功能:
- 通常chronyd会通过减缓或加快时钟来纠正系统的时间偏移。在某些情况下,系统时钟可能会与真实时间偏差很多,此时,修正系统时钟将需要很长的时间。步进时钟(时间挑边)可以快速修正偏差较大的时间误差,但是有可能会导致一些程序异常,因此应当慎用这个选项。makestep指令用来配置步进时钟。
- 第一个数值表示允许使用步进时钟的时钟偏差的最小值,单位秒(s)。也就是说当时钟偏差大于该数值时,使用步进时钟来快速调整时间偏差。
- 第二个数值表示,允许chronyd在启动后的前几次更新时间中使用步进时钟来修正时间偏差。第二个数值为负,不限制更新次数。
- 语法:
makestep 10 3
# 假如时间偏差大于10s,允许在前3次时钟更新中使用步进时钟来修正偏差
maxchange
- 功能:maxchange指令后的第一个数值表示,时间更新时可修正的最大时间偏差,单位秒(s)。第二个数值表示不检查前几次时钟更新的偏差值,以允许chronyd初始时可以修正较大的时间偏差。第三个数字,表示当时间偏差查过指定的最大值的情况出现时,忽略时间偏差大于最大偏差值的次数。当出现时间偏差值大于设定最大值情况的次数大于第三个数值时,chronyd会退出并在syslog中记录日志。第三个数值为负表示chronyd永远不退出。
- 语法:
maxchange 1000 1 2
#时间偏差最大值为1000s,不检查第一次时间更新时的时间偏差
#当出现时间偏差值大于1000s两次后,chronyd退出并在syslog中记录日志
minsources
- 功能:该参数设置在本地时钟更新之前,时间源选择算法中需要考虑的可选的时间源的最小数量,默认值是1。将此选项设置为更大的数值,可用于提高可靠性。更多的时间源将不得不彼此协商一致,并且当只有一个时间源(该时间源提供的时间可能是不正确的)可达时,本地时钟将不会更新。
noclientlog
- 功能:noclientlog指令不带参数,它设置chronyd不记录客户端访问日志。通常情况客户端访问日志是被记录的,并且使用chronyc的clients命令可以报告客户端访问的统计数据。
stratumweight
- 功能:stratumweight指令设置当chronyd从可用时间源中选择同步源时,每一stratum应添加多少同步距离。
- 默认情况下,该值是0.001秒。这意味着,在选择同步源的过程中,只有当时间源距离之间的差异以毫秒为单位时,时间源的stratum才有意义。在chronyd选择同步时间源时,即使处于stratum低层次的时间源距离更远,也比另一个处于stratum高层次的时间源更容易被选中。将stratumweight设置为0时,可以使chrongyd选择时间源时忽略stratum层次。
rtcfile
- 功能:rtcfile指令用来设置保存与跟踪RTC准确性相关的参数的文件名称,当chronyd退出或chronyc发出writertc命令时,chronyd将信息(RTC错误,RTC错误发生时间以及RTC增益或损耗率)存储入这个文件中
- 语法:
rtcfile /var/lib/chrony/rtc
rtcsync
- 功能:rtcsync指令使得chronyd定期将系统时间复制到RTC时钟,并且不再尝试跟踪RTC时钟的偏移。
- rtcsync指令无法与rtcfile指令一起使用
- 在Linux系统上,内核每过11分钟复制系统时间到RTC时钟
- 语法:
rtcsync
server
- 功能:这是指定NTP服务器的指令
- 语法:
iburst:当Chrony第一次启动或无法从服务器获得响应时,该参数的含义是在头四次 `NTP` 请求以 `2s` 或者更短的间隔,而不是以 `minpoll x` 指定的最小间隔,这样的设置可以让 `chronyd` 启动时快速进行一次同步,这对于初次同步或网络条件不稳定时快速准确地设置时钟非常有用。
perfer:加上prefer表示首先以该server为标准同步
driftfile
- 功能:chronyd程序的主要行为之一,就是根据实际时间计算出计算机增减时间的比率,将它记录到一个文件中是最合理的,它会在重启后为系统时钟作出补偿,甚至可能的话,会从时钟服务器获得较好的估值
- 语法:
driftfile /var/lib/chrony/drift
三、chronyc指令介绍
chronyc tracking
-
- 功能:显示系统同步时间细节
-
- 结果:
[root@iZj6ccjjtnsdvrl5u3l0p5Z ~]# chronyc tracking
Reference ID : 64643D58 (100.100.61.88)
Stratum : 2
Ref time (UTC) : Mon Jul 22 15:07:22 2024
System time : 0.000039673 seconds fast of NTP time
Last offset : +0.000002173 seconds
RMS offset : 0.000072077 seconds
Frequency : 18.653 ppm slow
Residual freq : +0.001 ppm
Skew : 0.019 ppm
Root delay : 0.000788279 seconds
Root dispersion : 0.010930535 seconds
Update interval : 516.4 seconds
Leap status : Normal
相应字段含义:
Reference ID:当前chrony同步的ntp服务器ID以及域名(ip),参考ID是一个十六进制数,以避免与IPv4地址混淆。
Stratum:这个数字向你表明你的服务器距离源时间有多远。在这个例子中,我们的设备被归类为第2层源,因为我们正在连接到第1层源。这个值并不是一个NTP服务器准确度或可靠性的指标,只是它与源时间服务器的距离有多远(第0层)。0层源可以是一些超级精确的东西,比如原子钟
Ref time (UTC):该字段为我们提供Chrony处理来自源NTP服务器的最后一次测量的UTC时间
System time:该值表示你的系统时间比NTP服务器时间快或慢多少。Chrony不是将系统时钟调整到这个时间,而是通过略微加快或减慢速度来缓慢地重新修正它。Chrony将继续这样做,直到系统时间与NTP服务器的时间一致。软件这样做的目的是为了制止因时间的突然转变而造成时效性软件的错误。
Last offset:上次时钟更新的时候本地的偏移量
RMS offset:偏移值的长期平均值
Frequency:“频率”是如果chronyd不对其进行校正,则系统时钟出错的速率。用ppm(百万分之一)表示。例如,值1 ppm表示当系统时钟认为它已提前1秒时,它实际上已相对于真实时间提前了1.000001秒。
Residual freq:显示了当前选定参考源的“剩余频率”。这反映了来自参考源的测量结果表明该频率应与当前使用的频率之间的任何差异
Skew:频率上的估计误差范围
Root delay:这是到第1层计算机的网络路径延迟的总和,该计算机最终从该第1层计算机同步。根延迟值以纳秒分辨率打印。在某些极端情况下,该值可以为负。(这可能发生在对称的对等方排列中,其中计算机的频率彼此不跟踪,并且相对于每台计算机的周转时间,网络延迟非常短。)
Root dispersion:根扩散:这是通过所有计算机累积到第1层计算机的总色散,最终从第1层计算机对其进行同步。色散是由于系统时钟分辨率,统计测量变化等引起的。根色散值以纳秒分辨率打印
Update interval:更新间隔
Leap status:这是飞跃状态,可以是“正常”,“插入第二”,“删除第二”或“未同步
chronyc sources -v
-
- 功能:显示正在使用的时钟源相关的信息
-
- 结果:
[root@iZj6ccjjtnsdvrl5u3l0p5Z ~]# chronyc sources -v
210 Number of sources = 15
.-- 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
===============================================================================
^* 100.100.61.88 1 10 377 696 +54us[ +109us] +/- 11ms
^? 203.107.6.88 0 10 0 - +0ns[ +0ns] +/- 0ns
^? 120.25.115.20 0 10 0 - +0ns[ +0ns] +/- 0ns
^? 10.143.33.49 0 10 0 - +0ns[ +0ns] +/- 0ns
^+ 100.100.3.1 2 10 377 873 -590us[ -536us] +/- 14ms
^+ 100.100.3.2 2 10 377 688 +1137us[+1137us] +/- 15ms
^- 100.100.3.3 2 10 357 223 -58us[ -58us] +/- 14ms
^? 10.143.33.50 0 10 0 - +0ns[ +0ns] +/- 0ns
^? 10.143.33.51 0 10 0 - +0ns[ +0ns] +/- 0ns
^? 10.143.0.44 0 10 0 - +0ns[ +0ns] +/- 0ns
^? 10.143.0.45 0 10 0 - +0ns[ +0ns] +/- 0ns
^? 10.143.0.46 0 10 0 - +0ns[ +0ns] +/- 0ns
^+ 100.100.5.1 2 10 377 684 +724us[ +724us] +/- 15m
^+ 100.100.5.2 2 10 377 692 -966us[ -966us] +/- 16ms
^+ 100.100.5.3 2 10 377 34m +208us[ +255us] +/- 17ms
相应字段含义:
M:这表示信号源的模式。^表示服务器,=表示对等方,#表示本地连接的参考时钟
S:此列指示源的状态。“ *”表示chronyd当前同步到的源。“ +”表示可接受的来源,已与所选来源合并。“-”表示组合算法排除的可接受源。“?” 指示已失去连接性或其数据包未通过所有测试的源。“ x”表示一个时钟,它chronyd认为是虚假行情(其时间与大多数其他来源不一致)。“〜”表示时间似乎变化太大的来源。“?” 启动时也会显示条件,直到从中至少收集了3个样本为止
Name/IP:这显示了IP源的名称或地址
Stratum:这显示了来源的层次,如其最近收到的样本中所报告的那样。层0代表硬件参考时钟(GPS、原子钟等),层1表示具有本地连接的参考时钟的计算机。与第1层计算机同步的计算机位于第2层。与第2层计算机同步的计算机位于第3层,依此类推。
Poll:这显示轮询源的速率,以2为底(2^6)单位s。因此,值为6表示每64秒进行一次测量。chronyd 根据当前情况自动更改轮询速率
Reach:这显示了源的范围寄存器以八进制数字打印。该寄存器有8位,并在从源接收或丢失的每个数据包上进行更新。值377表示已收到所有最后八次传输的有效回复
LastRx:此列显示多久以前从源接收到最后一个样本。通常以秒为单位。通常以秒为单位,字母m、h、d、y分别表示分钟、小时、天、年。
Last sample:此列显示上次测量时本地时钟与源之间的偏移。方括号中的数字表示实际测得的偏移量。这可以以ns(表示纳秒),us(表示微秒),ms(表示毫秒)或s(表示秒)作为后缀。方括号左侧的数字表示原始测量值,已调整为允许此后施加于本地时钟的任何摆度。+/-指示器后面的数字表示测量中的误差范围。正偏移表示本地时钟位于源时钟之前。
chronyc makestep
-
- 功能:手动触发同步时间
-
- 结果:
[root@iZj6ccjjtnsdvrl5u3l0p5Z ~]# chronyc makestep
200 OK
chronyc activity
-
- 功能:服务端查看server端在线情况和时间同步情况
-
- 结果:
[root@iZj6ccjjtnsdvrl5u3l0p5Z ~]# chronyc activity
200 OK
15 sources online
0 sources offline
0 sources doing burst (return to online)
0 sources doing burst (return to offline)
0 sources with unknown address
参考文献:
chrony – Documentation (chrony-project.org)
Linux ❉ Chronyd时间同步服务器详解-CSDN博客
Linux:Chrony时间同步服务的工作原理与配置_chrony与server时钟同步的时间间隔-CSDN博客
Linux 硬件时间(RTC time)、系统时间(UTC时间、Universal time)、本地时间(Local time)、时区(Time zone)与夏令时(DST)解析-CSDN博客