
CentOS 7上做时间同步绕不开chrony。我在生产环境里从ntpd切到chrony踩过的坑比想象中多时间源配错、防火墙没放行、时区不对、虚拟机时钟疯狂漂移……每次排查到最后都发现根源不复杂但就是能让人卡上大半天。这篇把配置chrony时间源的核心细节一次讲透包括为什么CentOS 7默认选它、chrony.conf每项参数怎么理解、chronyc怎么读结果、常见故障怎么定位。适合刚接手CentOS 7系统的运维新人也适合被时间同步问题折腾过的老手翻一翻。1. 为什么CentOS 7默认用chrony而不是ntpdCentOS 7之后的系统已经在默认安装中把chrony作为首选时间同步方案老牌的ntpd仍然可以装但官方倾向已经非常明显。很多人一开始都会困惑ntpd不是挺成熟吗为什么说换就换如果时间同步方案本身只是“能同步就行”那两者确实差别不大但在精度、速度和抗抖动能力上chrony确实更有竞争力。1.1 先从结构说起chronyd和chronycchrony的实现不像老ntpd那样一个进程全包而是明确分成两个程序。chronyd是常驻后台的守护进程承担所有NTP网络通信和时钟调整工作chronyc是命令行客户端负责和chronyd通信查看状态、修改配置、强制同步。两者通过本机回环地址交互装好chrony后直接敲chronyc就能和本地守护进程对话不需要额外指定IP。这种拆分带来的好处是权限和工作域的隔离。日常查询和调试不需要碰守护进程本身管理能力也可以独立授权。实际使用中chronyc提供的子命令覆盖了状态查看、源切换、手工追时间、客户端统计等几乎所有运维动作比老NTP工具链用起来顺手得多。1.2 chrony比ntpd强在哪几个点第一是启动同步速度。NTP的默认校准方式是一点一点往正确时间上靠这在偏差小的时候没毛病但如果系统刚开机或者CMOS电池老化导致时间差出几个钟头还慢腾腾校正就出问题了。chrony配合配置文件里的makestep指令只要检测到偏差超过阈值直接一步跳到正确时间之后再用微调维持精度。第二是网络适应性。chronyd在算法层面做了更多功课它会把每次NTP往返的延迟、偏移都记录下来通过统计模型估算真实时间偏移及方差而不是简单相信最近一次结果。网络抖动大的环境下这个模型能明显减少错误跳跃也不会因为某一次响应慢就把时间源标记为不可用。第三是对漂移的自学习。本机晶振频率受温度、电压影响会漂移chronyd会把这个漂移趋势估算出来并写进driftfile。这样即使系统重启同步收敛速度也很快不用重新从头学习一遍。下面这张表可以直观感受两者差异维度chronyntpd首次同步速度iburst下秒级完成通常较慢可能要几分钟大偏差修正makestep直接跳变默认缓慢爬升网络抖动适应基于统计模型更稳健一般易受瞬时抖动影响漂移学习持续写入driftfile重启后快速收敛也有数据记录但恢复较慢配置文件单文件语法清晰配置分散部分版本还依赖ntpdate配合1.3 哪些场景建议切到chrony严格说在CentOS 7里chrony不是“可选”而是默认方案系统服务就叫chronyd。如果你某台机器跑的还是ntpd大概率是早期手动装的。从维护角度讲官方已经减少对ntpd的投入新特性基本都在chrony这边所以建议回归到chrony。另外如果网络环境复杂、同步精度要求高比如有交易审计、日志时间关联需求chrony的优势就很明显。我见过不少环境要求所有服务器时间误差不超过几百毫秒用chrony配合局域网内的高质量时间源是可以做到的。反过来如果只是普通测试机那用哪个其实差别不大但既然系统默认给了chrony就没有必要额外装一套ntpd。2. 动手前的环境自检与安装动手配置之前我习惯先花几分钟看一遍系统现状。这一步能省掉后面很多排查时间尤其是处理一台已经在跑时间服务的老环境。2.1 先看时区、时间与同步状态先执行timedatectl一口气把时区、当前时间、NTP同步状态都确认了timedatectl输出结果里重点看三项。第一是Local time也就是本地时间确认它和当前实际时间大致对得上如果差距离谱说明硬件时钟或时区可能有问题。第二是Time zone如果系统是Asia/Shanghai通常没问题如果显示成UTC之类后面所有日志时间都会错乱。第三是NTP synchronized字段它表示当前日期时间同步服务是否成功启用。看到yes说明之前已经有人管着时间同步看到no就说明这台机器的时间基本处于没人管的状态。云服务器初始化镜像一般会把时区预设好但自建的物理机或者从模板克隆出来的虚拟机经常出问题所以这一步别跳。时区不对的话先用下面命令修正timedatectl set-timezone Asia/Shanghai改完再执行timedatectl确认。这一步只影响时间的本地展示和NTP同步本身没关系但如果你配置好了chrony却发现“时间差8小时”八成就是时区问题。2.2 安装chrony并确认服务运行CentOS 7的最小化安装一般也带上chrony但保险起见还是确认一下rpm -qa | grep chrony如果没有输出直接安装yum install -y chrony安装完成后先别急着改配置把服务状态看一下systemctl status chronyd如果显示active (running)说明服务已经在运行。如果显示inactive让它跑起来再设置开机自启systemctl start chronyd systemctl enable chronyd这里有个细节如果你刚装好chrony开机自启务必打开否则下次重启后又会回到没有时间服务的状态。别问我为什么强调接手的机器里因为漏掉这一步导致时间失准的案例实在太多了。3. 配置时间源/etc/chrony.conf逐项拆解配置chrony的核心就是编辑/etc/chrony.conf。每个发行版默认内容略有不同但核心语法一致。我接下来说的都是生产环境里真正用到的项以及每项背后的道理。3.1 server、pool和iburst该怎么选配置时间源最常见的是server指令server 某个时间服务器域名或IP iburst比如用公共NTP池server 0.pool.ntp.org iburst server 1.pool.ntp.org iburst server 2.pool.ntp.org iburst要留意的是server一行一个时间源多配几个相当于给自己加了冗余。chronyd会从中选择最优源而不是“众人抬轿”。至于iburst是干什么用的它在服务刚启动时钟偏差较大时连续发送8个请求加速首轮同步。没有这个参数首次同步可能要等几十秒甚至更久加上iburst之后通常几秒内就能完成。基本生产配置里都会加iburst。除了server还可以用pool关键字配置一个NTP服务器池。pool背后的机制是DNS解析时会返回一组随机服务器chronyd自动从这组服务器里挑选。与之相比server就是固定那几个IP不会自动轮换。如果公司内部只有两三台固定时间服务器用server就够如果走公共NTP服务用pool更合理。看一下比较典型的混合配置pool 0.pool.ntp.org iburst server 10.0.0.1 iburst server 10.0.0.2 iburst这里内网固定时间源放前面公共池兜底。chronyd在启动后会同时探测所有源选中最可信的一个作为主同步源同步失败时自动切换到其他源。我曾经遇到过内网时间服务器偶尔抽风的情况公共池的存在让整条同步链没有中断。3.2 别忽略makestep、driftfile和rtcsync接下来是三个容易被忽略但极其重要的指令。第一个是makestep。默认配置里一般是makestep 1 3含义是如果系统时钟和正确时间的偏差超过1秒那么在启动后的前3次时钟更新时chronyd直接跳跃调整而不是一点一点爬。写“1 3”是为了开机阶段快速纠偏等到系统已经平稳运行后续同步都走平滑微调避免服务里的时间突然跳变带来麻烦。如果你发现某台机器重启后时间总是慢了几个小时加不加makestep会直接决定你是等上半小时还是一分钟。第二个是driftfiledriftfile /var/lib/chrony/drift这行让chronyd把测量到的本机晶振漂移率存起来。重启之后chronyd可以基于历史漂移数据更快收敛。没有driftfile的话每次开机都要重新学习一遍漂移规律同步质量会打折扣。第三个是rtcsyncrtcsyncrtcsync告诉chronyd每次系统时间校准完之后顺手把系统时间写入硬件时钟。CMOS电池供电的硬件时钟本来精度就差加上长期不校准偏差只会越来越大。rtcsync相当于让系统时间和硬件时间始终联动。如果不写这一行重启后系统可能会用一块明显落后的硬件时钟作为初始时间又得费劲校准一次。3.3 allow/deny把服务范围管起来chrony既能做客户端也能做服务端给局域网内其他机器提供时间。如果你不需要对外服务默认配置就够。但如果你开了服务端就一定要用allow管好范围allow 192.168.1.0/24 allow 10.0.0.0/8 deny 0.0.0.0/0allow后面跟网段含义是只允许这些网段的客户端来查时间。deny 0.0.0.0/0是兜底拒绝优先级上allow在deny之前所以具体行为等价于白名单。生产环境里这步不能省否则相当于把NTP服务裸奔到公网容易被利用来发起流量放大攻击虽然端口偶尔看着不起眼但暴露后消耗的带宽都是实打实的。3.4 local stratum做本地时钟兜底还有一个很实用的配置local stratum 10意思是如果chronyd无法从任何外部时间源同步比如内网断网了依然把自己宣告为stratum 10的本地时间服务器让局域网里依赖它的其他机器不至于群龙无首。stratum是NTP的层级概念值越小代表越接近权威时间源。普通时间服务器的stratum一般在2到4之间本地兜底的10在时间源层级里已经属于“实在没辙才认”的级别但总比让客户端完全没有时间来源强。我在一个内网环境里专门验证过这个场景把外部网络断开客户端访问chrony服务端依然能拿到时间只是层级偏高。等外网恢复后chronyd会自动回到正常外部源整个过程不需要人工干预。4. 重启服务与验证同步效果配置文件改完正式启动验证。这一章我会把生产环境里最常用的验证命令和使用心得一起说。4.1 重启chronyd并确认状态每次改完配置文件都要重启chronyd才能让配置生效systemctl restart chronyd systemctl status chronyd如果配置文件语法有错误服务可能会启动失败。这时可以通过systemctl status的输出或者journalctl -u chronyd查看日志定位到哪一行配错。还有一个小习惯改配置之前先备份一份比如cp /etc/chrony.conf /etc/chrony.conf.bak回滚起来比重新回忆改了什么快得多。4.2 chronyc sources结果该怎么读查看已配置时间源的当前状态最常用的是chronyc sources -v输出结构类似210 Number of sources 3 MS Name/IP address Stratum Poll Reach LastRx Last sample ^* 192.0.2.1 2 6 37 28 487us[501us] /- 12ms ^- 192.0.2.2 2 6 37 29 -102us[ -98us] /- 18ms ^? 192.0.2.3 3 6 3 112 -896us[ -896us] /- 120ms先看第一列M字符。^代表这是一台服务器代表对等体。第二列S字符是状态^*表示这个源正在被chronyd作为当前同步源^表示它是候补源并且通过了基本校验^-表示它可用但优先级较低^?表示状态未知或不可达。看到一个^*就说明同步链路已经通了。Reach是最近8次询环的成败掩码数值是8次询问结果的二进制位掩码换算而来。能达到37这种值说明最近通信基本正常Reach长期偏低就说明源有问题。LastRx是多久前收到这个源的上一次响应单位秒。如果这个值一直增长而没有新响应说明时间源开始不响应你的请求了。Last sample是最近的偏移样本比如487us表示这个源认为本机快了487微秒。4.3 chronyc tracking和sourcestats进一步确认想知道当前时间的偏移到底多小用chronyc tracking输出里最有用的是Last offset和System time。System time如果显示0.000000xxx seconds fast说明系统时间比真实时间快了不到1毫秒。实际运维中只要偏差在合理范围内就好不用追求绝对零偏移。chronyc sourcestats -v可以看每个源更详细的统计信息包括样本数、频率偏移和残差方差。如果某个源的残差方差明显偏大说明它不太稳定这时候优先考虑换掉这个时间源。如果时间已经差得很远可以执行chronyc makestep手动让chronyd立即执行一次时钟跳跃把偏差快速抹平。这个命令在服务刚启动、还没完成自动校准的情况下特别有用。执行完再查一下tracking通常能看到偏移被大幅收敛。5. 常见问题排查与避坑实录时间同步相关的故障九成以上集中在几个地方。这一章按我实际排查的经验把典型问题列出来基本可以当速查表用。5.1 时间源状态全是问号怎么办如果chronyc sources里看到多个^?源说明chronyd无法对这些源完成有效通信。排查顺序一般是先确认这台机器能不能访问相应网络再检查防火墙有没有放行UDP 123端口。云服务器和物理机的防火墙习惯不一样云上iptables可能没开但安全组规则里把UDP 123挡了物理机上firewalld的默认zone也可能拦了入站请求。简单验证网络通路可以从其他机器用nc或tcpdump看报文也可以直接看journalctl -u chronyd里有没有网络不可达的报错。UDP 123如果不放行概率上讲就是网络配置问题。5.2 日期没问题但时间总是差8小时这个坑我在好几个新人团队里见过。系统时间本身是准的但显示时间总是差8小时原因是时区配置成了UTC。虽然chrony同步的是UTC时间戳跟时区设置无关但本地时间的展现完全由时区决定。处理起来很快timedatectl set-timezone Asia/Shanghai执行完timedatectl再确认显示正常了。这类问题很典型排查的时候如果发现NTP synchronized是yes但时间看起来还是不对第一个就该怀疑时区。5.3 重启后时间容易跑偏如果机器每次重启后系统时间都明显落后多半是rtcsync没配置或者硬件时钟本身出了问题。先确认是否开启了rtcsync再手动同步一次硬件时钟hwclock --systohc这个命令把当前系统时间写入硬件时钟。加上chrony的rtcsync配置之后正常就不需要频繁手工处理了。物理机和虚拟机都可能遇到这个问题尤其在长时间关机或断电后更明显。5.4 虚拟机环境下时钟漂移更快虚拟化环境下时间同步问题比物理机更常见。因为虚拟机的时钟由宿主机调度CPU频率抖动、电源管理策略都会导致时间漂移更快。基本做法是虚拟机的chrony配置里保留多个时间源并开启makestep。如果用的是云主机平台一般本身就提供了时间同步服务可以优先把平台提供的时间服务器配置进去效果更稳。另外不建议在虚拟机里同时运行ntpd和chrony两套服务冲突会造成时钟反复跳跃。装好chrony后把ntpd停掉并把开机自启禁用避免下次重启又拉起来。5.5 chronyc连不上chronyd执行chronyc sources时如果提示无法连接说明chronyd没在运行或者它的本地通信socket有问题。先用systemctl status chronyd看看服务状态如果是failed再journalctl -u chronyd查看日志。配置文件写错、端口被占都会导致启动失败。这种排查下来一般就是恢复chronyd运行不需要大改配置。最后再分享一个小经验关键业务服务器上建议把chrony日志接进系统日志统一收集时间同步异常时能第一时间发现比事后翻记录要省心得多。如果你遇到某台机器长时间同步不上别死磕配置先抓包看一眼UDP 123的报文往返很多时候答案就在网络层。