资讯详情

Linux时间同步方案对比:Chrony配置、安装与故障排查实战

📅 2026/10/6 21:11:29 | 华诺云谱 👁 阅读
Linux时间同步方案对比:Chrony配置、安装与故障排查实战
做Linux运维、搞过数据库集群或者搭过k8s的都明白时间同步这件事平时存在感极低可一旦出问题轻则日志乱序、认证失败重则分布式系统脑裂、交易对不上账。今天要说的Chrony就是Linux下目前最主流、也是系统默认标配的时间同步方案它解决的正是“服务器时间不准”和“同步过程不可控”这两大痛点。不管你是管着一台机器的新人还是维护几百台服务器的老手弄清楚Chrony的选型逻辑和实操细节都能少踩很多坑。这篇文章不打算念官方文档我只把这几年的使用经验和对Chrony的理解拆开讲它比老牌NTP强在哪、换掉ntpd之后配置该怎么写、离线环境怎么装上、同步状态怎么查、遇到“万年不同步”怎么排查。你会看到可以直接拿去套用的配置也会看到我实际踩过的一些坑尤其是那些官方文档里不太会写明白的细节。1. Chrony比传统NTP强在哪1.1 先说清楚时间同步到底在同步什么很多人把时间同步简单理解成“把系统时间改成和网络时间一样”这个说法不准确。真正靠谱的时间同步不是盲目地拿服务器本地时间跟网络源做差值然后强改而是要让系统的本地时钟持续且平滑地跟踪标准时间。系统时钟本身由硬件振荡器驱动每一台机器的晶振都有微小偏差温度、负载都会影响走时速率所以偏差会不断累积。同步工具要做的其实是两件事一是校正当前偏差二是估算并修正本地时钟的走时速率也就是漂移率。传统ntpd的做法是周期性小步调整选出一组可用源按复杂算法计算偏移然后以很细的粒度 slewing这个过程可能很慢。而Chrony从设计上就针对现代环境做了大量优化它能在几秒到几十秒内完成首次同步对网络抖动和源不稳定也有更好的容忍度因为它不只是“跟某个源对表”而是把每次测量结果都记录下来做统计分析结合漂移率来持续校正时钟频率。我举一个很好理解的类比ntpd像是你每隔半小时看一次标准钟每次发现慢了就拧一下手表但你的表本身走多快其实没有校准Chrony则是不仅对时间还会推算“你这块表每24小时会慢多少秒”然后直接微调走时速率。这种机制决定了Chrony在长时间运行、网络质量一般、甚至切换时间源的情况下精度和稳定性都更优秀。1.2 和ntpd、systemd-timesyncd的对比之前常见的方案就三个ntpd、systemd-timesyncd、Chrony。很多人问过我用哪个我的意见一直很明确如果是对时间精度、可用性有要求的服务器就选Chrony别犹豫。对比项ntpdsystemd-timesyncdChrony首次同步速度慢通常要几分钟甚至更久快但仅做粗略同步快秒级完成初次校时漂移率校正支持但收敛慢基本不校准硬件时钟根据历史测量实时校正断网/源失效恢复恢复较慢能力弱记录历史恢复后迅速重新同步服务器模式支持配置繁琐不支持原生支持内网做授时很方便与systemd集成一般偶尔有冲突原生集成集成良好chronyc交互工具ntpq功能分散无chronyc非常强大实时可控systemd-timesyncd适合笔记本、桌面这类“差不多就行”的场景它简单但它真的只是“同步”连启动时是否立即跳变这种策略都不好控制。而Chrony兼顾了轻量、精确、可当NTP服务器三大需求这也是为什么从RHEL/CentOS 7开始它就成了默认。1.3 现代Linux为什么默认都是它如果你装过CentOS 7以上或Ubuntu 18.04之后的系统会发现系统里已经默默装好了chrony配置文件也在/etc/chrony.conf。为什么发行版要选它当默认除了上面提到的精度和速度还有一个重要原因是它和现代Linux的运行方式结合得很好。现代服务器动辄几十上百台系统通过systemd统一管理服务chrony原生支持systemd开机自启、崩溃自动拉起都不需要额外脚本。它还支持将系统时间修正的幅度控制在可接受范围内避免因为“同步”导致进程里已经计算好的时间忽然跳变这对数据库事务、分布式锁这类场景特别重要。还有一点Chrony被设计成即便处于无网络环境或只有低质量网络时也能合理工作它会保存漂移率到driftfile重启后下一次同步不会从零开始。2. 从安装到基础配置的完整过程2.1 在线安装和首次启动如果你的机器能正常访问软件源安装Chrony基本没有任何难度。CentOS/RHEL系用yumDebian/Ubuntu系用apt看命令# CentOS / RHEL 7/8/9 yum install -y chrony # Debian / Ubuntu apt install -y chrony装完之后先把服务跑起来然后验证一下状态systemctl enable --now chronyd systemctl status chronyd chronyc tracking首次执行chronyc tracking如果输出里有“Leap status : Normal”这样的字样说明它已经开始正常跟踪时间源了。注意这里的服务名是chronyd因为进程名是chronyd管理命令是systemctl加上chronyd——这个细节搞错的人不少有人systemctl start chrony直接报错找不到服务。2.2 CentOS 7离线环境用rpm包安装离线环境安装是很多内网部署的硬需求热搜词里也看到“centos7 chrony 离线下载安装”这里我补一个完整的做法。理论上Chrony依赖很少核心是chrony这个包本身但为了稳妥建议把依赖一并下载。在一台可以联网的同版本CentOS 7机器上用yumdownloader把rpm包pull下来yum install -y yum-utils mkdir -p /data/chrony-rpm cd /data/chrony-rpm yumdownloader --resolve chrony执行完后目录下会多出几个rpm文件包括chrony本体和它依赖的libseccomp等把这些文件拷到内网机器上执行rpm -ivh *.rpm或者用yum localinstall做依赖检查yum localinstall -y *.rpm离线装完之后配置文件位置依然是/etc/chrony.conf服务名也一样。我见过有的环境离线源不完整localinstall会报缺少依赖所以最稳的办法是把“能联网的同版本机器”和“目标离线机器”的系统版本保持完全一致比如都是CentOS 7.9否则可能会有glibc版本冲突。2.3 配置文件的骨架每个参数到底在管什么/etc/chrony.conf是核心我先把一个比较有代表性的基础配置贴出来然后逐行讲它背后的逻辑# 上游时间源iburst表示启动后快速连续采样若干次 server ntp.aliyun.com iburst server ntp1.aliyun.com iburst server cn.pool.ntp.org iburst # 本地时钟漂移率保存文件 driftfile /var/lib/chrony/drift # 允许系统时间偏差超过1秒时前3次同步直接跳变 makestep 1 3 # 允许哪些网段访问本机时间服务 allow 192.168.1.0/24 allow 10.0.0.0/8 # 即便没有上游源本机也以stratum 10级别向外提供服务 local stratum 10server那一行不用多说值得解释的是iburst和minpoll/maxpoll。minpoll/maxpoll控制轮询间隔默认是6到10对应64秒到1024秒。初次启动时如果加上iburstchronyd会在前几秒内连续发送多个请求加速首次同步这个参数强烈建议保留能大幅缩短从启动到“可用状态”的时间。makestep这行很多人不理解。任何时间同步工具都不会轻易让系统时间直接跳变因为时间跳变会让依赖单调递增时间的程序出现逻辑错乱。makestep 1 3的意思是如果检测到系统时间与源时间偏差超过1秒并且之前已经完成的同步次数少于3次就允许直接跳变校正时间。初始时间差很大时smothing校正可能需要几小时甚至一天这对于刚装好的机器是灾难所以前几步采样允许跳变是合理的等系统进入稳定跟踪状态后再通过微调走时速率来校正秒级以内的偏移。allow和local stratum通常成对出现作用是把你这台机器变成内网NTP服务器。allow是控制接入网段的白名单local stratum是用来定义“当上游不可达时本机仍然作为本地时间源发布服务并且宣称自己stratum是10”。这在完全隔离的内网、只有一台机器能接触外部时间源的场景下非常有用。2.4 时区和RTC的关系也顺带讲清楚Chrony只管时间同步它不负责时区。很多人配置文件见都没改却老觉得“时间不对”其实是系统时区没设置好。装完系统后我建议顺手执行timedatectl set-timezone Asia/Shanghai timedatectl看到“Local time”和“Universal time”都正常System clock synchronized字段为yes说明系统时间本身和实际时区都没问题。有些机器还会涉及硬件时钟也就是CMOS里的RTC建议统一用UTC或者跟系统一致即可一般来说执行timedatectl set-local-rtc 0让RTC使用UTC标准可以避免双系统时区混乱的问题。3. 实操篇把Chrony灵活用起来3.1 内网时间服务器的搭建和客户端接入实际运维中很常见的拓扑是外网源 → 核心时间服务器 → 几百台内网机器。这样内网各机器不必都访问公网只要核心服务器出网即可内网同步延迟低、成功率也高。搭建服务器端时在核心机器上打开上游源配置并加上allow把内网网段放进来。同时为了让本机在断外网时也能兜底建议开启local stratum。之后客户端机器只需要配置一条核心服务器的地址server 192.168.1.10 iburst然后重启chronyd、稍等几秒用chronyc sources查看同步状态应该会看到目标服务器处于^*状态表示当前正在使用的已同步源。如果看到^?或^这样的标记说明源还有问题需要往下排查。这里再多说一句stratrum它是时间源层级0为最高层级通常指GPS/原子钟向外逐级增加。客户端通过内网时间服务器去同步时同步源层级就是核心服务器对外宣告的层级。配置local stratum 10会因为层级较深而让客户端认为这个源“级别不够好”但只要网络里没有更优源客户端依然会采用。内网环境不用太纠结层级数字除非你有严格的分层规范。3.2 chronyc命令速查这几个操作你必须会chronyc是Chrony自带的命令行工具也是排查问题的钥匙。我把最重要的几个命令整理成一张表方便你对照着用命令作用什么时候用chronyc tracking查看系统时间与参考时间的偏差、漂移率、同步状态最常用先跑这个就对了chronyc sources -v列出当前配置的所有时间源带状态标记看源是否可达、是否被选为同步源chronyc sourcestats查看各源的测量统计信息包括偏差和抖动分析源质量时用chronyc makestep手动触发立即跳变校时刚配置完、时间差较大时chronyc burst 3/3临时加快采样频率需要快速校准漂移率时chronyc clients查看有哪些客户端在向本机请求时间排查服务器端被谁访问时chronyc activity查看各源在线的连接状态批量观察源可用性chronyc select查看当前选择的同步源列表判断哪个源在起作用以chronyc tracking为例它的输出里我最关注的是“System time”这一行System time : 0.000123456 seconds fast of NTP time如果偏差是正数说明本地时间比标准时间快负数说明慢。正常情况下这个值应该在毫秒量级。如果看到巨大偏差比如几十秒配合“Last offset”那行也能看出一些线索。这些信息可以直接拿来对接监控脚本。还有sources -v输出的第二列是状态标记字符。看到^*表示这个源是当前主同步源这是最理想的状态^表示这是一个可用的备用源^?表示源不可达或在初始化^-表示该源被排除或被标记为不可用。看到^?之后再去查网络连通性、防火墙大多能定位问题。3.3 一个场景把CentOS 7服务器切换成Chrony很多线上机器以前用的是ntpd要切换到Chrony并不是简单的yum install就完事。如果你发现机器上同时装了ntpd和chrony优先禁用前者systemctl stop ntpd systemctl disable ntpd systemctl enable --now chronyd timedatectl set-ntp yes注意timedatectl set-ntp yes这步很关键它会把systemd的timesyncd也标记为不可用避免多个时间服务同时工作。如果之前用过timesyncd还要把systemd-timesyncd服务停掉否则端口123会被占用或者出现策略冲突。切换后先看chronyc sources确认状态然后对比系统时间。我第一次切换时遇到一个现象chronyd看起来正常但系统时间纹丝不动查了一圈发现是chronyc tracking显示“Leap status : Not synchronised”后来发现是防火墙没放行UDP 123。这类问题放到后面的排查部分一起说。3.4 用脚本监控同步状态给运维加道保险时间同步有没有生效不能靠肉眼去等建议写个简单的巡检脚本放到cron里定时跑#!/bin/bash stratum$(chronyc tracking | grep -i Stratum | awk {print $2}) if [ $stratum 10 ]; then echo WARN: time source is local, not synchronised fi这里判断的逻辑是如果stratum变成了10说明本机没有可用的上游源只能靠local stratum兜底这是一个需要立即关注的信号。你还可以从chronyc tracking里取Last offset的绝对值超过阈值就告警这样能更早发现问题。实测下来这种方式比单纯依赖服务存活状态可靠得多因为服务活着不代表同步健康。4. 常见问题与排查技巧实录4.1 时间源总是显示^?同步不上去这是所有人都会遇到的头号问题我碰到的次数最多。看到^?的第一步不是改配置而是先确认源通不通。用chronyd自带的工具测一下chronyd -Q server ntp.aliyun.com iburstchronyd -Q是前台一次性模式只做一次查询然后打印结果非常适合作连通性测试。如果这里的输出显示“Leap status : Normal”说明从本机到上游源的网络路径没问题问题大概率出在配置文件或服务切换不完整如果报“Name resolve failure”那就是DNS解析不了域名换成IP试试如果没任何响应再查防火墙和路由。在云主机上还有一个常见的坑安全组只放行了TCP端口没有放行UDP 123。NTP协议基于UDP通信很多云厂商的默认安全组规则压根不管NTP但有些自定义的规则会把它拦掉。本地防火墙也一样执行firewall-cmd --add-servicentp --permanent firewall-cmd --reload如果是Debian系且用了ufw则ufw allow 123/udp4.2 系统时间总是跳变数据库事务出问题这就是makestep双刃剑的另一面了。makestep允许偏差超过某个阈值时立刻跳变能够快速校时但对运行中的业务有风险。时间向前跳某些依赖event ID、事务序号的程序会报错时间向后跳更容易破坏分布式系统的秩序。稳妥的做法是对生产环境把makestep设得保守一些比如makestep 10 10意思是初始10次同步允许最大跳变10秒之后所有时间偏差都通过平滑调整绝不跳变。如果绝对不能接受跳变甚至可以把这一步注释掉。我的经验是刚装机时用宽松的makestep业务交付后收紧策略这个切换时刻值得写进运维SOP。4.3 虚拟机里时间老是慢十几秒虚拟机的时间漂移问题非常典型因为宿主机CPU调度会导致Guest的时钟中断不稳定表现为clock慢慢累积误差。Chrony本身能解决大部分问题但还需要注意的是不要同时让VMware/KVM的工具和chronyd一起干同样的事。很多虚拟化平台有自带的“时间同步”插件开着没啥坏处但容易和chronyd产生冲突。另一个容易被忽视的是宿主机时间。如果宿主机本身时间不准虚拟机里Chrony再怎么努力也只能跟着不准。我处理过一起“集群所有节点时间都同步正常但整体偏慢”的问题最后排查到宿主机硬件时钟源的问题。理清这个逻辑后大概就明白为什么核心时间服务器通常建议用物理机配GPS或连接权威NTP源。4.4 常用排查命令的速查表我把自己排查时间同步问题时固定会用到的检查项整理如下按这个顺序走基本能解决九成问题检查项命令或文件期望结果服务是否运行systemctl status chronydactive (running)当前同步状态chronyc trackingStratum不为10Leap status正常时间源状态chronyc sources -v至少有一个^*标记端口监听ss -unlp | grep 123chronyd进程监听UDP 123本机防火墙firewall-cmd --list-alludp 123已放行云安全组云控制台查看入方向UDP 123放行系统时区timedatectl时区正确synchronized字段为yes上游源连通性chronyd -Q server IP iburst能返回Offset信息物理机/虚拟机冲突ps -ef | grep -E ntpdtimed漂移文件权限ls -l /var/lib/chrony/driftchrony用户可读写4.5 时间同步从服务器到客户端为何有时差了几百毫秒内网机器通过NTP服务器同步的时候几百毫秒的延迟很常见原因通常不是Chrony不给力而是客户端和服务器之间的网络路径或服务器本身负载问题。NTP协议在设计时会把网络往返延迟除以2作为补偿所以在网络对称的前提下误差不会太大。但如果你用的是基于Wi-Fi的客户端或者网络拥塞严重这种估算精度就会下降。解决办法是尽量让客户端同步时使用服务器侧接入同一交换机的物理网段避免跨三层路由。另外如果核心时间服务器本身也在向外同步注意它要留出一部分性能。不建议一台服务器既做核心NTP源又跑高负载数据库时间服务的精度会受影响。4.6 换源时常见的一个低级错误配置多个server的时候有人喜欢把所有国内时间源都塞进去结果发现chronyc sources显示几个源之间偏差特别大系统时间在源之间来回横跳。Chrony本身有源选择算法能过滤掉“不合群”的源但如果各源之间本身时间就偏差太大它也会无所适从。我建议核心服务器源的配置控制在3到5个并且尽量选择同一运营商的源或者用官方推荐的pool域名而不是把一堆不相关服务器硬凑在一起。改配置之后别忘了重启chronyd很多人在这个坑里翻过车systemctl restart chronyd改配置后看chronyc sources -v的过渡状态变化等一两分钟再确认最终状态不要只看一眼就下结论。5. 进阶心得把Chrony用在更复杂的架构中5.1 多层时间源的容灾设计大型集群里我比较推荐的是两层结构第一层由两台或多台权威时间服务器组成它们分别连接不同的外部NTP源比如一台连国内公共NTP另一台连另一家公共NTP互为主备。第二层的所有业务机器只同步到第一层的服务器而不是直接访问公网。这样做的原因有三减少公网请求量、让内网机器同步延迟更低、避免外部源故障时全集群一起失去时间基准。第一层服务器之间也要互相指向对方这样当某一台的外部源全部失效时它还能从另一台拿到时间不会瞬间跌落到local stratum。Chrony对多源协作的支持很成熟配置server的指向关系后它会自动处理。5.2 结合systemd定时任务做每日校准Chrony的漂移率修正是持续进行的正常情况下不需要额外做手工校准但某些极端环境比如频繁休眠的笔记本、离线运行很久的嵌入式设备还是建议加一个每日校准任务做双保险chronyc makestep放在root的crontab里每天凌晨执行一次加上之前提到的监控脚本形成“定期校准实时监控”的组合拳。不过在生产服务器上我不建议这样搞让Chrony自己做平滑调整会更安全。5.3 几个我踩过的坑最后分享几个花了我不少时间的坑。第一个坑同时装了ntpd和chrony导致每次启动后两个进程互相拉锯时间忽快忽慢。处理方式很简单ntpd必须彻底disablestrictly speaking系统只允许一个时间同步服务存在。第二个坑在容器里使用Chrony。容器的网络模式如果是host那配置起来和物理机一样但如果是bridge模式容器内看到的123端口可能没法正常收发外部UDP。所以容器场景建议让宿主机做时间同步容器内不折腾NTP最多把宿主机的/etc/localtime映射进来保证时区一致。第三个坑配置文件里的allow指令如果不写默认行为是什么都不允许。也就是说你配好了server但忘了allow客户端会一直显示“Source not synchronised”或者连接被拒绝。反过来想如果你要让本机只做客户端不需要对外服务那千万别写allow更安全。我现在做新环境部署的时候已经养成习惯了装完系统第一件事就是timedatectl看状态接着打开/etc/chrony.conf换掉默认的pool源然后重启chronyd跑一次chronyc tracking确认偏差在毫秒级。这套动作看起来不起眼但恰恰是把很多“时间炸弹”提前拆除的最好方式。时间同步这东西平时真没什么存在感但一旦出错它就是那个让你熬夜排查的元凶而Chrony能让你在做时间这件事上少操一点心。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑