CentOS下用Chrony搭建时间同步服务器:原理、配置与排坑全记录

发布时间:2026/10/19 13:47:59
CentOS下用Chrony搭建时间同步服务器:原理、配置与排坑全记录
你有没有遇到过这种场景某天凌晨数据库突然报主从延迟查了半天日志发现是两台机器的时间差了十几秒又或者线上排查故障A 服务器的日志时间戳和 B 服务器对不上定位问题全靠肉眼脑补。这些破事十有八九都是时间不同步惹的祸。作为一个被坑过无数次的运维老手我现在每接手一套环境第一件事就是先把时间同步方案定下来。今天就把我在 CentOS 上基于 Chrony 搭建时间同步服务器的完整经验分享出来从原理到踩坑一次性给你讲透。1. 项目背景与整体思路1.1 时间同步到底解决什么问题先说个最直接的类比时间同步就像团队里的对表。一群人各带各的手表有人快五分钟有人慢十分钟那开会、交接、协作全乱套。服务器也是一样尤其在现代分布式架构里时间不一致的后果非常严重。举几个我实际遇到过的例子。第一类是日志分析多台服务器的日志要聚合到日志平台做关联分析如果时间不同步明明同一时刻发生的事件会因为时间戳错位被拆成两个毫无关联的记录。第二类是数据库事务某些数据库的主从复制依赖时间戳排序主库和从库时间偏差过大轻则同步延迟重则数据冲突。第三类是证书校验HTTPS 证书、Kerberos 认证这些都有有效期时间不对会导致证书“未生效”或者“已过期”线上服务直接不可用。这些还只是表象更深一层的原因是服务器的硬件时钟RTC和系统时钟System Clock本身就是两套体系硬件时钟靠主板电池维持系统时钟靠内核计时两者的漂移方向和速率都不一样。如果没有一个外部标准时间去校正时间偏差会像滚雪球一样越滚越大。时间同步服务器的任务就是让所有机器持续对准同一个“标准时间源”偏差控制在毫秒甚至微秒级别。1.2 为什么选 Chrony 而不是 NTPd在 CentOS 7 及之后版本里Chrony 已经是默认的时间同步方案但这不代表你没得选。传统的 NTPdNetwork Time Protocol daemon服务了很多年我在老系统上也用它那为什么现在更推荐 Chrony关键区别在于同步机制的设计哲学。NTPd 依赖定期轮询它每隔一段固定时间比如 64 秒到 1024 秒之间向时间服务器发起请求通过往返时延计算时间偏差然后逐步调整。这种方式的优点是稳定缺点也很明显——收敛速度慢。在刚启动或者时间偏差很大的时候NTPd 要花很长时间才能把时间“拉”回来。Chrony 在这方面做了大量优化。它采用了一种更激进的频率测量算法能在短时间内完成多次采样并且不会因为网络抖动就轻易丢弃数据点。实测下来CentOS 7 上 Chrony 完成初次同步的时间通常只需要几十秒而 NTPd 可能要几分钟甚至更久。另外Chrony 对网络环境差的场景特别友好即使网络断断续续它也能在恢复后快速重新同步这在虚拟机频繁迁移、笔记本移动办公这种场景下非常实用。还有一点很多人忽略Chrony 的命令行工具chronyc比 NTPd 的ntpq好用太多。它能直接查看当前同步源的健康状态、偏差数值、漂移率排查问题的时候信息非常直观。既然系统自带且更现代我没有任何理由不选它。1.3 架构选型单机、主从还是分层时间同步架构不是越复杂越好关键看环境规模和精度要求。规模最小的场景比如一个开发测试环境只有三五台机器那直接让所有机器都同步公网 NTP 服务器就够了不需要内部搭建服务器。但如果你服务器数量超过几十台或者处于内网隔离环境、访问不了外网那就必须搭内部时间同步服务器了。我这次要讲的是主从架构这在实际生产环境里最常用。整体思路是这样的选一台机器作为时间同步服务器它既能访问外部时间源不管公网还是内网的上游 GPS 授时设备又通过局域网对外提供时间同步服务其他所有内部机器作为客户端只跟这台服务器同步。这样做的优势很明显。一是节省公网带宽和上游服务器资源。如果一百台机器都直接请求公网 NTP 服务器先不说带宽浪费很多公网 NTP 服务器为了防滥用对单 IP 的请求频率是有限制的请求太频繁会被临时封禁。二是统一管控。客户端只需要指向一个固定地址以后要切换上游时间源、调整同步策略只需要改服务器一台机器即可。三是精度可控。通过良好配置的局域网时间服务器客户端的同步精度通常能达到亚毫秒级这比直接访问公网服务器还要稳定因为局域网内的网络延迟和抖动远小于公网。在这个架构里你还需要注意“层级”这个概念。时间源有 stratum层数属性从 0 到 15数字越小精度越高。公网顶级时间服务器一般是 stratum 1 或 stratum 2你自己搭的服务器如果直接从公网时间源同步那它的 stratum 就是上游加 1。客户端同步你的服务器后层级再加 1。层级越深理论精度会逐级损耗但只要控制在 10 层以内对绝大多数业务场景来说完全够用。我实际操作时会把内部服务器配置为 stratum 10 的“末级备用源”这样即使上游时间源故障内部服务器也能基于本机时钟继续提供服务不至于彻底瘫痪。2. 环境准备与 Chrony 部署2.1 系统环境与网络规划部署前先把环境和网络规划清楚别一上来就敲命令后面容易返工。系统环境方面我这次用的是 CentOS 7.9这是生产环境里存量最大的版本之一Chrony 版本默认是 3.4。如果你用的是 CentOS 8 或 Rocky Linux 9命令和配置文件基本通用差别不大。需要提前确认一点系统里有没有预装其他时间同步工具比如 NTPd 或者ntpdate。有的话先停掉并禁用避免它们和 Chrony 抢同一个 123 端口。检查命令很简单systemctl status ntpd rpm -qa | grep ntp有输出就说明装了用systemctl stop ntpd systemctl disable ntpd把它干掉。同时把ntpdate定时任务从 crontab 里清掉我以前就吃过这个亏——crontab 里残留了一条ntpdate定时命令每次执行都直接把时间强跳一次导致 Chrony 的平滑调整机制完全失效。网络规划上需要分清两个方向一个是服务器访问上游时间源的出方向另一个是客户端访问服务器的入方向。如果服务器能访问公网最简单的方案是配置国内公网 NTP 服务器池延迟低、稳定性好如果服务器处于纯内网环境那上游只能是内网已有的 GPS 授时设备或者上级时间服务器要确认它的 IP 和端口是否可达。客户端这边要规划好允许接入的网段。比如我的服务器内网 IP 是 192.168.10.10客户端网段是 192.168.10.0/24那我就在配置里明确允许这个网段访问其他的一律拒绝。防火墙策略也要同步规划。时间同步用的是 UDP 123 端口如果服务器开了 firewalld需要放行 NTP 服务。如果还有云平台安全组入方向规则里也要加上 UDP 123。很多人最后排查半天发现时间不同步结果就是安全组或防火墙没放行这个坑我在后面问题排查章节会详细说。2.2 安装 Chrony 与防火墙放行CentOS 7 安装 Chrony 极其简单因为它就在默认的 Base 仓库里不需要额外添加任何源yum install -y chrony安装完成后先不要急着启动我习惯先编辑配置文件再启动。确认安装版本可以执行chronyd --version正常情况下会输出类似3.4的版本号。防火墙这边有两种处理方式取决于你用的管理工具。如果你用的是 firewalldCentOS 7 默认执行firewall-cmd --permanent --add-servicentp firewall-cmd --reload firewall-cmd --list-services看到输出里包含ntp就说明放行成功。注意--permanent参数一定要带否则防火墙重载后规则就丢了。如果你用的是 iptables 直接管理那对应的规则是iptables -A INPUT -p udp --dport 123 -j ACCEPT但别以为防火墙放行就万事大吉还有一层是 SELinux。CentOS 7 默认 SELinux 是 enforcing 模式不过 chronyd 的 SELinux 策略在标准安装中已经默认放行 123 端口通常不需要额外配置。真遇到问题时再看日志用ausearch -m avc -ts recent查询是否有 SELinux 拦截记录这个我后面排查章节也会提。服务启动和设置开机自启systemctl start chronyd systemctl enable chronyd systemctl status chronyd启动后先确认进程状态是 active (running)再看一下端口监听情况ss -ulnp | grep 123输出里应该能看到chronyd进程监听在 UDP 123。如果没起来大概率是配置文件写错了用journalctl -u chronyd -f看日志排查。2.3 核心配置文件逐行解读Chrony 的配置文件路径是/etc/chrony.confCentOS 7 安装后会有一个默认版本。我强烈建议你把默认配置打开逐行读一遍再改而不是直接网上 copy 一份配置文件。只有理解了每个参数的作用后面遇到问题才知道去查哪里。这份默认配置通常长这样# 使用pool.ntp.org项目的公共服务器 pool 2.centos.pool.ntp.org iburst # 记录系统时钟的漂移率 driftfile /var/lib/chrony/drift # 启用系统时钟的RTC同步 rtcsync # 允许调整的时间来源通过局域网访问本服务的客户端 #allow 192.168.0.0/16 # 距离本服务时间源的层数 local stratum 10 # 指定包含NTP验证密钥的文件 #keyfile /etc/chrony.keys # 指定日志文件的目录 logdir /var/log/chrony # 如果系统时钟的偏差大于1秒则在前三次更新中步进调整 makestep 1 3这里逐个说。pool行配置的是上游时间源池它指定了多个服务器地址Chrony 会自动从池子里选择合适的时间源。iburst参数非常关键它表示在服务刚启动时快速连续发送多个请求加速初始同步。少了这个参数初次同步可能要等很久。driftfile记录的是系统时钟的漂移率。什么叫漂移率简单说就是本地时钟和真实标准时间之间的偏差变化速率。晶体振荡器受温度、电压影响每台机器的时钟走速其实都略有不同。Chrony 会持续测量本机时钟的漂移率并记录到这个文件里下次重启时直接读取历史漂移数据就能更快进入稳定状态。这个文件不用手动维护但目录必须让 chronyd 有写入权限默认的/var/lib/chrony是没问题的。rtcsync表示启用硬件时钟与系统时钟的同步。很多资料没有特别强调它但它很重要。它让内核定时把系统时间写回硬件时钟避免长时间关机后再次开机硬件时钟和真实时间偏差过大。特别提醒虚拟机场景虚拟机的硬件时钟通常是虚拟化的存在比较明显的漂移rtcsync能有效减轻这种影响。makestep 1 3这个参数比较微妙。它的含义是如果系统时钟偏差超过 1 秒且是在前三次每次同步周期内最多一次同步之后直接“步进”调整时间而不是平滑微调。为什么要这样设计因为如果偏差非常大比如刚开机时发现时间差了整整一分钟用平滑微调的方式每秒调整几毫秒要调整很久才能校正过来期间服务一直处于错误时间状态里。步进调整虽然会让时间瞬间跳变但能快速把偏差纠正。这里有个权衡步进会导致日志时间戳跳变监控数据可能出现断层所以生产环境通常会把阈值设得保守一些或者配合业务低峰期操作。比如我会把阈值从默认的 1 秒调整到 5 秒让绝大多数日常偏差走平滑调整只有重启后的大偏差才走步进。local stratum 10是“本机作为时间源的备用层级”。如果服务器的所有上游时间源都不可达它还能基于本机时钟继续为客户端服务同时声明自己是 stratum 10 的时钟源。给客户端传递一个“还可以用”的信号不至于让所有机器都撒丫子跑去公网同步。这个值不要设得太低如果设成 0 或 1会伪装成高级别时间源误导下游客户端。配置完成后执行systemctl restart chronyd再用chronyc sources -v查看同步源状态。这一步是验证配置是否生效的关键状态输出里如果显示^*代表已经成功锁定时间源并同步。3. 时间同步服务器核心配置3.1 上游时间源配置方案上游时间源选得好不好直接决定整个系统的精度上限。生产环境里主流选择有三类公网 NTP 服务器池、内网 GPS 授时设备、上级机构时间服务器。公网 NTP 服务器池最常见国内使用比较多的是阿里云和腾讯云提供的公共 NTP 地址延迟低、稳定性好、在国内无需额外配置。这类地址走的是标准的 NTP 协议用配置文件的server或pool指令就能指定。它们的格式长这样以我常用的云端公共 NTP 地址为例# 阿里云 NTP 服务 server ntp.aliyun.com iburst # 腾讯云 NTP 服务 server ntp.tencentyun.com iburst这里我刻意用了“以阿里云 NTP 服务为例”这种表达你可以根据自己环境替换成实际可达的公网 NTP 地址。配置多个上游源的好处是可以做冗余如果一个不可达Chrony 会自动切换到其他源。我一般会配置两到三个不同服务商的地址避免单一服务商故障导致源失效。内网 GPS 授时设备更适合对精度要求极高的场景比如金融交易系统、科学计算集群。这种设备通常通过串口或者网络口提供 NTP 服务配置方法和公网源一样直接把地址替换成 GPS 设备的 IP 即可。区别是 GPS 设备的精度通常在微秒级对中间链路质量要求高所以建议服务器的网卡、交换机链路都做好带宽保障。配置后还需要测试上游源是否真的能用。先看chronyc sources -v的输出正常情况显示为^*或者^^*表示当前选中的主时间源^表示可用的候选时间源。如果显示^?或^x说明该源不可达或不可用需要换地址或检查网络。这里有个小经验初次引入新上游源建议不要立刻移除旧源让新旧源并行跑 10 分钟观察新源的状态稳定后再移除避免切换过程出现同步空洞。3.2 客户端授权与访问控制时间同步服务器搭好了如果不在配置文件里声明允许哪些客户端访问那它默认只允许本机访问自己别人用不了。授权控制就是allow和deny指令。配置位于/etc/chrony.conf核心作用如下# 允许内网网段 192.168.10.0/24 访问 allow 192.168.10.0/24 # 允许单个主机访问 allow 192.168.10.50 # 拒绝特殊网段其余默认拒绝 deny 192.168.20.0/24逻辑很简单默认拒绝所有显式声明允许哪些网段或 IP。如果服务器内网网段不固定你也可以用更粗的allow 192.168.0.0/16但生产环境我强烈建议精确到实际使用的网段减少恶意请求和误请求的干扰。另外还有一个bindaddress参数用来指定 chronyd 监听在哪个接口上。如果你的服务器有多块网卡比如一块接入内网、一块接入管理网建议显式指定监听 IP避免客户端通过非预期网卡访问。例如# 监听内网IP的123端口 bindaddress 192.168.10.10改完配置后需要重启 chronyd 或者执行chronyc reload sources重新加载。重启会短暂中断时间同步服务但中断时间极短生产环境可以接受。验证客户端能否同步时你在客户端机器上执行chronyc sources -v如果能显示你的服务器地址且状态为^*说明授权配置生效。我在实际项目中遇到过一个有意思的情况有些客户端系统的chronyd版本比较老比如 1.29连接新版本 Chrony 服务器时NTP 协议的某些扩展字段兼容性有问题表现为客户端间歇性同步失败。这种问题排查成本很高最终的解决办法是把客户端升级到 centos 官方仓库中的 chrony 3.4或者临时在服务器端把clientloglimit等高级参数调保守一些避开老版本客户端的解析问题。3.3 本地时钟与层级设定技巧本地时钟配置是时间同步架构里容易被忽略但极其重要的一环。我可以负责任地告诉你不做本地时钟兜底的服务器迟早有一天会出问题。实际情况是这样当上游时间源全部不可达时——比如上游服务商故障、公网链路中断、DNS 解析失败——如果服务器没有本地时钟兜底它就会直接停止向客户端提供时间服务客户端们会逐渐漂移整个系统时间再次失控。而有了local stratum 10这类配置即使上游全挂服务器依然能基于自己的本地时钟继续对外服务客户端的时间偏差至少不会快速扩大。配置方式是在/etc/chrony.conf里写入# 当上游不可达时声明本地时钟为 stratum 10 local stratum 10为什么是 10 而不是 8 或者 12因为 stratum 有效范围是 1 到 15数字越小精度越高。如果设置得太低比如 5下游客户端会误以为你这台服务器的精度等同于公共 NTP 服务器而实际上它只是本地时钟精度远不能比。如果设置得太高比如 15在客户端视角里你的优先级太低它们可能会尝试寻找其他更高层级的时间源达不到统一管控的目的。stratum 10 是一个平衡值既明确表达“我是本地兜底不是精密时间源”又保证在层级范围内有足够的优先级。还有一个细节当上游恢复后服务器会自动从本地时钟模式切回上游同步模式吗Chrony 的设计是会。它持续监测上游源的状态一旦上游重新可达并完成同步本地时钟会自动退出主时间源的角色转成后备角色。你不用手动干预非常省心。但在切换过程中部分客户端可能会短暂收到不同层级的时间源通告导致它们短时间内切换上游。这个现象通常几秒到几十秒内就会自动恢复如果不想让客户端频繁切换可以客户端配置里用maxdistance等参数控制容忍范围这块我在客户端配置里继续讲。3.4 客户端侧配置要点服务器配置好了客户端这边也要做相应的设置。客户端的/etc/chrony.conf配置非常简洁核心就是把上游指向你的时间同步服务器。# 时间同步服务器 IP server 192.168.10.10 iburst # 记录漂移率 driftfile /var/lib/chrony/drift # 启用RTC同步 rtcsync # 系统时钟偏差超过1秒在前三次更新中步进 makestep 1 3如果你希望客户端绝对服从服务器的安排不要自作主张去访问公网 NTP那不要在客户端配置里加任何pool或额外的server就只保留这一条内网服务器地址。多加一个公网源看似多一层保障实则是给自己添乱——客户端可能在公网源可达时切到公网同步结果时间精度反而不如稳定内网源的同步效果。客户端配置还有一个容易被忽略的参数maxdistance 10。这个参数的含义是当客户端与时间源的距离包括网络延迟和时钟层级的综合指标超过 10 秒时客户端判定当前时间源不可信停止同步。默认值是 3 秒如果网络环境音量真不高可以适当调高。比如有些跨地域分部通过专线连接总部时间服务器单向延迟相对较大默认的 3 秒可能不够。但注意也不要调太高否则在时间源真的有问题时客户端依然盲目跟从反而起到反作用。生产环境建议 5 到 15 之间按需调整。另外客户端机器的timedatectl set-ntp true也要确认开启它是 systemd 层面的 NTP 开关。如果这个开关是关闭状态即使 chronyd 在跑系统也可能不采纳它调整后的时间。检查方法timedatectl status输出中NTP synchronized: yes才是正常状态。如果显示no先执行timedatectl set-ntp true再排查其他原因。4. 验证、监控与性能调优4.1 chronyc 命令实战配置只是第一步真正体现水平的是验证和监控。Chrony 自带的chronyc命令是排查时间同步问题的利器我就围绕最常用的几个命令展开。第一个必用的命令是chronyc sources -v。它展示当前所有配置的时间源状态输出格式类似这样210 Number of sources 3 .-- Source mode ^ server, peer, # local clock / .-- Source state * current synced, combined , - not combined, | / ? unreachable, x may be in error, ~ time too variable || .-- xxxx [ yyyy ] /- zzzz || / .-- xxxx [ yyyy ] /- zzzz || / .-- xxxx [ yyyy ] /- zzzz ^* 192.168.10.10 2 6 17 32 -29us[ -137us] /- 911us ^- ntp.aliyun.com 2 7 23 27 -15ms[ -15ms] /- 48ms ^ ntp.tencentyun.com 2 7 65 32 -12ms[ -12ms] /- 42ms我把这个输出拆开讲其实信息量非常大。第一列是源状态^*表示当前选中的主时间源^表示可用备选源^-表示可用但未选中的源^?表示不可达。第二列是上游地址。后面的列分别对应 stratum 层级、轮询间隔、样本数、偏移量和误差范围。实际使用中你重点看两个指标一个是状态列必须是^*或^才健康另一个是偏移量正常局域网内偏移应该在微秒到毫秒级。第二个实用性极强的命令是chronyc tracking。它展示本机与主时间源的同步详情包括当前偏差、漂移率、最后校正时间等。其中最关键的三个字段是System time、Last offset和RMS offset。System time是本机与标准时间的当前偏差越小越好Last offset是最后一次校正的偏差值RMS offset是最近一段时间偏差的均方根可以理解为整体偏差水平。如果RMS offset持续大于几十毫秒说明同步链路质量不佳需要排查网络或者上游源。第三个命令是chronyc sourcestats -v它展示每个时间源的统计信息帮助判断哪个时间源的稳定性好。它的输出里有一列RMS offset表示该时间源历史样本的偏差波动范围。稳定源的 RMS offset 应该远小于不稳定源。当你有多个上游源时可以通过对比这个值来选择更合适的源。最后还有两个关键时刻会用到的命令chronyc makestep手动立即步进调整时间chronyc clients查看哪些客户端正在访问你的同步服务器。makestep在服务器刚部署完、初始同步还没完成时很好用可以直接把时间拉正。clients则能帮助你快速确认授权配置是否生效以及有没有非法网段偷偷访问。4.2 同步状态解读技巧很多人配置完 Chrony 后只看一眼chronyc sources -v的^*就以为万事大吉其实这远远不够。状态解读有深浅之分我总结了一套实战判断逻辑。第一步看“主时间源是否选定”。^*存在说明已经锁定主源^?则说明所有源都不可达。如果所有源都显示^?先 ping 一下上游地址看网络通不通通了再查防火墙和 UDP 123 端口通了再看周期健康。不要急着改配置大概率不是配置问题。第二步看“偏差值是否合理”。sources -v输出的最后一列是误差范围比如/- 911us。如果这个值在毫秒级以下属于优秀水平在几十毫秒级说明链路有一定波动需要关注到了秒级别就说明同步链路基本不可用必须排查。客户端和服务器在同一局域网实测大多在几百微秒到几毫秒之间属于健康状态。第三步看“漂移率是否稳定”。用chronyc tracking查看Drift字段单位是 ppm百万分之一。比如输出Drift: 2.341 ppm表示本机时钟每秒钟会漂移 2.341 微秒。这个值大不大取决于硬件。普通物理机的漂移率通常在 1 到 50 ppm 之间如果超过 100 ppm要么硬件时钟有问题要么系统负载异常导致时钟中断被延迟。虚拟机的漂移率往往比物理机高这是正常现象可以通过rtcsync和更频繁的同步减轻影响。第四步看“最近校正频率”。用chronyc tracking查看Update interval它表示两次校正之间的间隔。间隔太短说明系统时钟不稳定或者上游源频繁波动间隔太长说明同步不够积极。这四个步骤做完基本能定位 90% 的同步问题。如果这四步全正常但业务依然报时间不对那就要看是不是应用层面强制落了本地时间偏差跟系统时间同步无关。比如某些 Java 应用会缓存启动时的系统时间导致重启前和重启后同一进程里System.currentTimeMillis()不一致这种问题得重启应用解决。4.3 时间精度与漂移率分析聊到性能调优首先要建立一个概念时间同步不是一次性的“对表”而是一个持续追踪和校正的过程。Chrony 实际上是在动态地维持一个时间连续函数它以漂移率为核心参数不断预测和校准。精度能调到多高影响因素主要有三个网络延迟和服务器的处理时间、上游源本身的精度、本地时钟的稳定度。局域网场景下网络延迟通常不到 1 毫秒Chrony 的同步精度可以达到几十微秒级。公网场景下由于网络抖动较大精度通常在几毫秒到几十毫秒。如果你的业务对时间精度要求在毫秒以下应该尽量用局域网内部服务器并且把服务器的上游源选在物理距离近、链路质量高的位置。实际上对漂移率的分析可以帮助你判断硬件健康状况。我用chronyc tracking观察到一台物理服务器的漂移率长期稳定在 1.5 ppm 左右突然有一天飙升到 200 ppm而且系统负载没有明显变化查了硬件日志发现是主板上的温控单元故障导致晶振温度异常。更换主板后漂移率恢复正常。所以漂移率突变是一个很好的硬件异常预警信号不要忽视。调优方面我有几个心得。第一minpoll和maxpoll参数可以控制同步请求的最小和最大轮询间隔默认分别是 62 的 6 次方即 64 秒和 101024 秒。如果你希望同步更积极可以把maxpoll调低到 6 或 7但注意这会增加上游服务器负载。第二iburst一定要保留尤其是客户端刚启动时能大幅缩短初始同步时间。第三客户端不要配置太多上游源一主一备就够了有时候配多了反而因为源之间的时间参考不同导致客户端频繁切换性能反而下降。我还强烈建议把logchangeweight之类的参数默认保持原样不要为了“调优”而去调它很多参数是牵一发动全身的默认配置对绝大多数场景都是经过测试的最佳组合。真正的性能提升来自架构和链路质量而不是参数上微调。5. 常见问题排查与避坑实录5.1 高频问题速查表我把自己踩过的坑和帮别人排查过的问题汇总成了一张速查表基本上覆盖了 90% 的常见情况。排查的时候先对照这张表能省大量时间。问题现象可能原因排查命令与解决思路chronyc sources -v显示所有源^?上游地址不可达、防火墙未放行、UDP 123 被安全组拦截ping测试连通性telnet 上游IP 123测试端口检查firewall-cmd --list-services和云平台安全组规则客户端无法同步服务器时间服务器未配置allow网段、客户端配置了错误 IP、UDP 123 未放行服务器端执行chronyc clients看是否有客户端记录客户端chronyc sources -v看状态检查两端防火墙时间偏差大但同步状态显示正常刚部署未完成初始同步、makestep参数过小、开机时 RTC 与系统时间偏差过大手动执行chronyc makestep确认makestep 1 3配置等待 3~5 分钟再次观察日志时间戳不连续大跳变意外执行了ntpdate或chronyc makestep服务重启同步时步进调整检查 crontab 残留命令调整makestep参数确保不手动混用 ntpdate虚拟机时间频繁漂移虚拟化平台半虚拟化时钟问题、RTC 中断处理异常确认rtcsync配置排查虚拟机时钟源设置必要时将 VM 时钟源切换为 hypervisor 时钟chronyd 启动失败配置文件语法错误、端口被占用journalctl -u chronyd -f查看日志ss -ulnpSELinux 导致无法同步SELinux 策略异常拦截ausearch -m avc -ts recent查看拦截记录若确认拦截执行setsebool -P chronyd_allow_network 1或restorecon -Rv /etc/chrony.conftimedatectl显示 NTP synchronized: nosystemd-timesyncd 未禁用、Chrony 未生效systemctl status chronyd确认服务在跑timedatectl set-ntp true开启开关确认 chronyd 没和其他 NTP 工具冲突表格里每一类我都实际碰到过下面挑几个最典型的详细展开解析。5.2 几个典型故障的排查实录先说一个非常普遍的故障客户端chronyc sources -v显示服务器状态为^?但服务器端chronyc clients能看到客户端的访问记录。这个矛盾怎么解释客户端能发出请求、服务器也能收到但客户端认为不可达。我第一次遇到这个情况时排查了很久。最终发现是客户端和服务器之间的往返延迟过大客户端的maxdistance参数默认值太小导致它判定这个源距离太远不可信。解决方法是客户端配置里把maxdistance调整到 10 秒或者检查两台机器之间的网络质量。类似地如果客户端和服务器之间的时间偏差一开始就大于makestep的阈值客户端也会拒绝同步。这种情况需要先在客户端手动执行chronyc makestep把时间拉近再观察自动同步是否恢复。第二个典型故障是“时间总是对了又偏反反复复”。客户端同步成功后过几分钟时间偏差又涨回来了且chronyc tracking里的RMS offset一直在几十毫秒以上。这种问题通常有两个方向一是本地时钟漂移率异常晶振老化或温度过高二是同步周期太长校准赶不上漂移。我遇到过一个案例一台服务器的所在机房空调故障温度常年偏高晶振漂移率从 2 ppm 直接飙到 80 ppm同步速度完全跟不上。解决方法是先调低maxpoll让同步更频繁同时联系硬件维护人员处理散热。等温度恢复正常后漂移率也跟着降回正常水平。第三个坑是关于ntpdate的。有些老运维习惯用ntpdate定时校正时间但在 Chrony 环境里这样会捣乱。ntpdate强制把时间“步进”调整而 Chrony 是平滑调整。两者机制完全相反会造成时间来回跳变监控数据一片混乱。我的建议很明确用 Chrony 的环境里彻底删掉ntpdatecrontab里的相关行也一并清掉。第四个坑跟虚拟机相关。虚拟机在宿主机负载高时会频繁暂停导致虚拟 CPU 时钟和真实时钟偏差变大。很多人在虚拟机上配置了物理机一样的同步策略发现时间还是不稳。这时候可以看下 VMware 或 KVM 的半虚拟化时钟驱动是否启用。比如在 KVM 环境下virtio时钟设备能显著改善时间精度。我在云服务器上做过实测启用半虚拟化时钟后漂移率能下降一个数量级。这块没有统一的命令需要你根据使用的虚拟化平台查一下具体配置方法。5.3 日志与监控配置建议时间同步的问题往往不是突发的而是慢慢累积的。所以除了出问题时排查日常监控更重要。我对生产环境的时间同步建议做三件事。第一件事是开启 Chrony 的日志记录。在/etc/chrony.conf里配置logdir /var/log/chrony log tracking measurements statistics这样 chronyd 会持续记录同步状态、测量数据和统计数据到/var/log/chrony/目录。文件会持续增长建议配合 logrotate 自动轮转默认 CentOS 已带有相关配置。通过分析日志你能看到偏差随时间的变化曲线提前发现漂移率异常。第二件事是配置监控告警。你可以用 Zabbix、Prometheus 等监控平台采集chronyc tracking的关键指标比如系统时间偏差、漂移率、同步源状态。告警阈值可以参考连续 5 分钟时间偏差超过 100 毫秒报警 WARN超过 1 秒报警 CRITICAL。同步源状态为不可达时报警 WARN。这样保证时间同步出问题能第一时间发现。第三件事是定期巡检。我建议每季度做一次时间同步专项检查内容包括检查所有服务器的时间偏差分布、查看漂移率是否异常、确认配置文件没有被误改、清理无效时间源配置。巡检时用脚本批量执行chronyc tracking收集数据效率会高很多。监控这步千万别省时间同步问题最怕的是“温水煮青蛙”——偏差一点点扩大业务不会立即报错等你发现的时候日志已经乱成一锅粥了那时候排查成本极高。写在最后的一点体会折腾时间同步这么多年我最深的体会是时间同步看起来是个不起眼的基础设施但它就像空气一样平时感觉不到它的存在一旦出问题就是连锁反应。Chrony 这套方案我在生产环境用了很多年稳定性和易用性都经过了验证。最后再分享一个小技巧当你新搭建一台服务器时不要只配置完同步就离开一定要在部署后的 10 分钟左右再用chronyc tracking看一眼偏差值趋势确认它在正常范围内持续缩小。这短短几分钟的观察能避免服务器带着时间偏差直接进入生产集群后续排查的成本可比这高多了。