凌晨两点,生产环境的告警突然响起——某台核心服务器的时钟偏移了 3 秒,导致分布式锁提前释放,一连串请求涌入错误的时间窗口。你排查了半天才发现,这台服务器的时间同步服务静默失败了整整一周。
前言
在 CentOS 7 之前,ntp 是 Linux 时间同步的标准工具;CentOS 7 之后,chrony 逐渐成为更主流的替代实现,以其更高的精度和更好的适应性著称。本文从 NTP 协议原理出发,分别介绍 ntpd 和 chrony 的配置方式,对比两者的适用场景,并涵盖 PTP 高精度同步、时区管理以及完整的故障排查流程。
一、NTP 协议原理
1.1 Stratum 层级模型
NTP 采用分层(Stratum)架构来传递时间,层级数越小,时间源越权威:
Stratum 0 原子钟、GPS 接收器、CDMA 基站(参考时钟) │Stratum 1 直连 Stratum 0 的时间服务器(主时间服务器) │Stratum 2 从 Stratum 1 同步的二级服务器 │Stratum 3 从 Stratum 2 同步的三级服务器 │ ... 最多支持 Stratum 15 │Stratum 16 表示未同步状态关键规则:
- 客户端始终向 Stratum 值更小的服务器同步
stratum 16表示该节点处于未同步状态,不会被其他节点选为时钟源- 每经过一级,stratum 值 +1;如果一台服务器同时从多个源同步,它取所有源中最小的 stratum +1 作为自身的 stratum
1.2 NTP 时间同步过程
NTP 同步的核心是计算客户端与服务器之间的偏移量(offset)和网络延迟(delay)。一次 NTP 交互包含四个时间戳:
客户端 服务器 │ │ │──── T1 (请求发送时间) ────────>│ │ │ T2 (请求到达时间) │ │ T3 (应答发送时间) │<──── T4 (应答到达时间) ────────│ │ │计算公式:
偏移量 offset = ((T2 - T1) + (T3 - T4)) / 2往返延迟 delay = (T4 - T1) - (T3 - T2)NTP 假设网络往返路径对称,偏移量计算中两个方向的延迟取平均值来抵消路径差异。当网络不对称时(如上行 10ms、下行 50ms),偏移量计算会有误差,这也是 chrony 相比 ntpd 的改进方向之一。
1.3 NTP 报文与端口
- 传输层协议:UDP 123
- 报文模式:客户端-服务器模式(Mode 3/4)、对等体模式(Mode 1/2)、广播模式(Mode 5)
- 报文大小:48 字节(不含认证),加上认证扩展后约 68 字节
warning
防火墙配置时,NTP 使用 UDP 协议而非 TCP。很多运维人员误配为 TCP 123,导致同步始终失败。
二、NTP 时间同步(ntpd)
2.1 安装和基本配置
# 1. 安装 ntp 服务yum install ntp
# 2. 修正系统时间后同步到硬件时钟hwclock -w服务端配置(/etc/ntp.conf):添加以下两行,使服务器在无外部源时仍可与本地硬件时钟同步:
server 127.127.1.0fudge 127.127.1.0 stratum 8127.127.1.0 是 NTP 的「本地时钟」伪地址,fudge 用于将该本地时钟的 stratum 调整为 8,确保在有外部源时不会被优先选择,但在失去外部源时仍能提供时钟服务。
客户端配置(/etc/ntp.conf):注释掉无效的同步源,添加内网服务器地址:
# 注释掉原有无效 server 行,添加:server 192.168.1.1 iburstiburst 选项让 ntpd 在启动时快速发送 6 个请求(间隔 2 秒),加速初始同步。不加此选项时,ntpd 需要数分钟才能完成首次同步。
# 3. 启动 ntpd 服务service ntpd start2.2 访问控制配置
ntpd 使用 restrict 指令控制访问权限,这是安全加固的关键配置:
# 默认拒绝所有访问restrict default kod nomodify notrap nopeer noquery
# 允许本机完全访问restrict 127.0.0.1restrict ::1
# 允许内网网段查询和同步,但不允许修改服务器配置restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap nopeer
# 允许指定服务器作为上游时间源restrict 0.centos.pool.ntp.org nomodify notrap nopeerrestrict 权限关键字说明:
| 关键字 | 作用 |
|---|---|
kod | 发送 Kiss-o’-Death 报文拒绝违规访问 |
nomodify | 禁止修改服务器运行时参数 |
notrap | 禁止陷阱消息(trap) |
nopeer | 禁止对等体关联 |
noquery | 禁止状态查询(ntpq/ntpdc) |
noserve | 禁止时间同步服务 |
important
restrict 规则按匹配精度排序,更具体的规则优先。如果配置了 restrict default ignore 但忘记添加内网 restrict 允许规则,客户端将完全无法同步。
2.3 常用维护命令
# 强制立即同步(通常在开机时执行)ntpdate 192.168.1.1
# 查看同步状态(是否已同步、同步周期)ntpstat
# 查看远程服务器摘要信息(上次接收时间、轮询间隔、延迟、抖动)ntpq -p
# 调试同步失败原因(输出详细日志)ntpdate -d 192.168.1.1
# 查看 ntpd 与上游的详细关联状态ntpq -c assoc
# 实时监控 ntpd 统计信息ntpq -c sysstats
# 查看 ntpd 日志journalctl -u ntpdntpq -p 输出解读:
remote refid st t when poll reach delay offset jitter==============================================================================*ntp1.example.com .GPS. 1 u 64 128 377 1.234 -0.567 0.890+ntp2.example.com .PPS. 1 u 32 128 377 2.345 0.123 1.012-ntp3.example.com 10.0.0.1 2 u 128 128 377 5.678 3.456 2.345*:当前使用的同步源(系统对齐的选择)+:备选源(通过合并算法参与时间计算)-:被排除的源(聚类算法判定离群)x:虚假时间源(被 falseticker 检测标记)reach:最近 8 次轮询的可达性(八进制,377 = 全部可达)
常见同步失败原因:
Server dropped: strata too high:服务器 stratum 值过大,需确保服务端有有效的同步源,或配置与本地硬件时钟同步(见上文第三步)Server dropped: no data:版本不兼容、防火墙屏蔽了 UDP 123 端口,或服务器restrict配置禁止了客户端访问
三、Chrony 时间同步
Chrony 相比传统 NTP 有更快的收敛速度,对不稳定网络环境(如虚拟机、笔记本)的适应性更强,是 CentOS 7+ 和 RHEL 8+ 的默认时间同步方案。
3.1 安装和基本配置
# 安装 chronyyum install chrony
# 同步硬件时钟hwclock -w服务端配置(/etc/chrony.conf):
# 启动本地参考模式(即使无外部源,也能作为内网时钟源)local stratum 10
# 允许指定网段的客户端同步(留空表示允许所有)allow 192.168.1.0/24
# 指定 NTP 服务器池作为上游源pool 2.centos.pool.ntp.org iburst
# 记录时钟漂移,加速重启后同步driftfile /var/lib/chrony/drift
# 记录测量日志(用于调试)logdir /var/log/chronylog measurements statistics tracking客户端配置(/etc/chrony.conf):
# 添加内网时间服务器server 192.168.1.1 iburst
# 允许时钟在启动后前三次更新时步进(而非渐进调整)makestep 1.0 3
# 记录漂移driftfile /var/lib/chrony/drift
# 硬件时钟同步(将系统时间同步到硬件时钟)rtcsyncmakestep 1.0 3 表示:在前 3 次时钟更新中,如果偏移量大于 1 秒,直接步进调整而非缓慢偏移。这对于启动时系统时间偏差较大的场景非常有用。
# 启动 chronydsystemctl start chronydsystemctl enable chronyd3.2 三种同步模式
| 模式 | 关键字 | 说明 |
|---|---|---|
| Server 模式 | server | 严格分层:客户端向服务器同步,反向不影响 |
| Pool 模式 | pool | 指定 NTP 服务器池(DNS 解析出多个地址),chronyd 自动选最优,默认取 4 个源 |
| Peer 模式 | peer | 对等关系:双方互为服务器和客户端,适合两台主机互相备份时钟 |
配置示例——多源冗余:
# 使用国内 NTP 池(适合国内服务器)server ntp.aliyun.com iburstserver ntp.tencent.com iburstserver time.cloudflare.com iburst
# 或使用 pool 自动解析多个源pool cn.pool.ntp.org iburst maxsources 43.3 常用维护命令
# 立即强制同步系统时钟(不等待自然收敛)chronyc -a makestep
# 查看所有同步源及其状态chronyc sources -v
# 查看追踪信息(误差、漂移率等)chronyc tracking
# 查看 chronyd 日志journalctl -u chronyd
# 查看 NTP 源的详细统计信息chronyc sourcestats -v
# 手动添加/删除 NTP 源(运行时生效,不写入配置)chronyc add server ntp.example.comchronyc delete ntp.example.com
# 查看当前活动的 NTP 源数量chronyc activity
# 查看客户端访问日志(服务端使用)chronyc clientschronyc tracking 输出解读:
Reference ID : A9FEA97B (ntp.aliyun.com)Stratum : 3Ref time (UTC) : Thu Mar 09 14:30:00 2026System time : 0.000123456 seconds slow of NTP timeLast offset : -0.000456789 secondsRMS offset : 0.000789012 secondsFrequency : 5.678 ppm slowResidual freq : -0.001 ppmSkew : 0.012 ppmRoot delay : 0.023456789 secondsRoot dispersion : 0.001234567 secondsUpdate interval : 1032.2 secondsLeap status : NormalSystem time:当前系统时钟与 NTP 时间的偏差Frequency:硬件时钟的漂移率,单位 ppm(百万分之一),正值表示硬件时钟偏快Root delay:到 Stratum 1 服务器的总网络延迟Root dispersion:最大误差估计值Leap status:闰秒状态,Normal 表示无闰秒预告
3.4 常见问题排查
tip
时间同步失败时,按以下顺序逐步排查:
-
防火墙:NTP 使用 UDP 123 端口,确保防火墙放行:
# firewalldfirewall-cmd --add-service=ntp --permanent && firewall-cmd --reload# iptablesiptables -A INPUT -p udp --dport 123 -j ACCEPTiptables -A OUTPUT -p udp --sport 123 -j ACCEPT -
服务端 allow 配置:确认
/etc/chrony.conf中allow配置允许客户端所在网段访问。 -
本地参考模式:若内网服务器无法连接外部 NTP 源,必须配置
local stratum 10,否则 chronyd 在「非同步状态」下不会向客户端提供时钟服务。stratum数值越小表示时间越可靠(1 为原子钟级别,10 为降级本地参考)。 -
时区统一:时区不一致会导致时间显示错误(但不影响 UTC 同步):
timedatectl list-timezones | grep Shanghaitimedatectl set-timezone Asia/Shanghaitimedatectl status -
通过 chronyc 诊断:
chronyc sources -v # 检查同步源状态(* 表示当前使用的源)chronyc tracking # 查看系统时钟误差和漂移 -
ntpd 与 chronyd 冲突:两者不能同时运行,chronyd 启动时会检测并拒绝启动:
# 检查是否有 ntpd 在运行ps aux | grep ntpd# 停用 ntpd 并确保 chronyd 正常systemctl stop ntpdsystemctl disable ntpdsystemctl start chronyd -
虚拟机时钟漂移:虚拟机由于 CPU 时间片调度,时钟漂移比物理机严重得多。推荐在虚拟机中优先使用 chrony,并适当缩短同步间隔:
# /etc/chrony.conf — 虚拟机优化配置server 192.168.1.1 iburst maxpoll 6makestep 0.1 3maxpoll 6将最大轮询间隔设为 2^6 = 64 秒(默认 2^10 = 1024 秒),在虚拟机环境中能更快补偿漂移。
四、Chrony vs NTPd 对比
| 特性 | Chrony | NTPd |
|---|---|---|
| 启动同步速度 | 数秒内完成(硬件时钟准确时更快) | 需要数分钟到数十分钟 |
| 网络适应性 | 间歇连接、高延迟、高抖动环境优秀 | 需要稳定网络 |
| 时钟调整方式 | 支持步进+渐变(makestep) | 仅渐变调整(slow slew) |
| 硬件时钟同步 | 内置 rtcsync 自动同步 | 需要外部脚本或手动 hwclock |
| 漂移估算 | 实时估算,动态适应硬件漂移 | 基于 driftfile,启动后重新学习 |
| 默认部署 | RHEL 7+/CentOS 7+/Ubuntu 18.04+ | RHEL 6 及更早版本 |
| 广播/多播 | 不支持 | 支持 |
| 参考时钟驱动 | 支持(通过 refclock 接口) | 原生支持更多硬件参考时钟 |
| 资源占用 | 内存约 1.5MB | 内存约 2.5MB |
| 配置复杂度 | 较简单,默认配置即可用 | restrict 规则较复杂 |
选型建议:
- 新部署:始终选择 chrony,除非有特定的广播/多播需求
- 虚拟机环境:必须选择 chrony(ntpd 在虚拟机中表现很差)
- 已有 ntpd 部署:如无问题可保持现状,但新建集群应使用 chrony
- 需要广播模式:选择 ntpd(chrony 不支持 NTP 广播/多播客户端)
五、PTP 高精度时间同步
5.1 PTP 简介
PTP(Precision Time Protocol,IEEE 1588)是一种亚微秒级精度的时间同步协议,适用于金融交易、电信网络、工业控制等对时间精度要求极高的场景。
| 特性 | NTP | PTP |
|---|---|---|
| 精度 | 毫秒级(1-10ms) | 亚微秒级(<1us) |
| 协议 | UDP 123 | UDP 319(事件)+ 320(通用) |
| 硬件支持 | 不需要硬件时间戳 | 推荐硬件时间戳 |
| 典型应用 | 服务器集群、办公网络 | 金融、电信、工业控制 |
| 拓扑 | 客户端-服务器/对等 | 主从分层(BC/OC/TC) |
5.2 PTP 架构角色
普通时钟 (OC) 边界时钟 (BC) 透明时钟 (TC) ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ │ │ │ │ 单端 │ │ 多端 │ │ 多端 │ │ 口 │ │ 口 │ │ 口 │ │ │ │ │ │ │ └──────┘ └──────┘ └──────┘ 终端设备 网络交换机 网络交换机 参与 BMCA 级联 PTP 透传修正驻留时间- Grandmaster:顶级时钟源(接 GPS/原子钟),通过 BMC(Best Master Clock)算法选举
- Boundary Clock (BC):边界时钟,从一个端口同步,从其他端口分发,减少级联误差累积
- Transparent Clock (TC):透明时钟,不参与同步,仅修正报文在交换机内的驻留时间
- Ordinary Clock (OC):普通时钟,只有一个 PTP 端口的终端设备
5.3 Linux PTP 配置(linuxptp)
# 安装 linuxptpyum install linuxptp
# 查看网卡是否支持硬件时间戳ethtool -T eth0ethtool -T 输出中,hardware-receive 和 hardware-transmit 为 on 表示支持硬件时间戳,这是实现亚微秒精度的关键。
PTP 主时钟配置(/etc/ptp4l.conf):
[global]# 仅使用硬件时间戳time_stamping hardware
# 优先级(数值越小越优先当选 Grandmaster)priority1 128priority2 128
# 时钟类型clockClass 248
# 同步间隔(log2 秒,0 = 1秒,-1 = 0.5秒)logSyncInterval 0
# 延迟请求间隔logMinDelayReqInterval 0# 启动 PTP 主时钟(使用硬件时间戳)ptp4l -i eth0 -m -S
# 使用软件时间戳(无硬件支持时)ptp4l -i eth0 -m -S --software_timestamping
# 启动 phc2sys(将系统时钟同步到网卡 PTP 硬件时钟)phc2sys -s eth0 -w -mPTP 从时钟配置:
# 作为从时钟运行(自动通过 BMC 算法选举)ptp4l -i eth0 -m -s# 查看同步状态pmc -u -b 0 'GET CURRENT_DATA_SET'pmc -u -b 0 'GET TIME_STATUS_NP'pmc 输出中 offset from master 字段表示从时钟与主时钟的偏差,单位纳秒。
note
PTP 的精度严重依赖网络设备支持。普通交换机会引入不确定的存储转发延迟,导致精度退化到 NTP 水平。要达到亚微秒精度,需使用支持 BC 或 TC 的 PTP 交换机。
六、时区管理
6.1 timedatectl 完整操作
# 查看当前时间设置timedatectl status# 输出示例:# Local time: Thu 2026-03-09 22:30:00 CST# Universal time: Thu 2026-03-09 14:30:00 UTC# RTC time: Thu 2026-03-09 14:30:00# Time zone: Asia/Shanghai (CST, +0800)# System clock synchronized: yes# NTP service: active# RTC in local TZ: no
# 列出可用时区timedatectl list-timezones
# 搜索时区timedatectl list-timezones | grep -i shanghaitimedatectl list-timezones | grep -i tokyo
# 设置时区timedatectl set-timezone Asia/Shanghai
# 设置 UTC 时区(服务器推荐)timedatectl set-timezone UTC6.2 硬件时钟(RTC)管理
Linux 有两个时钟:系统时钟(内核维护,启动时从 RTC 读取)和 硬件时钟/RTC(主板电池供电,关机后保持)。
# 查看硬件时钟时间hwclock --show
# 将系统时间写入硬件时钟(系统→硬件)hwclock --systohc
# 将系统时间写入硬件时钟(指定 UTC 格式)hwclock --systohc --utc
# 将硬件时钟时间读入系统(硬件→系统)hwclock --hctosys
# 查看硬件时钟使用的时区标准timedatectl | grep "RTC in local TZ"important
服务器推荐将 RTC 设为 UTC(RTC in local TZ: no),避免时区转换混乱。双系统(Linux + Windows)环境需注意 Windows 默认将 RTC 视为本地时间,可能导致时间偏移 8 小时。
双系统时间冲突解决方案:
# 方案一:让 Linux 使用本地时间(不推荐)timedatectl set-local-rtc 1
# 方案二:让 Windows 使用 UTC(推荐)# 在 Windows 注册表中添加:# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation# RealTimeIsUniversal = QWORD 16.3 时间同步与 NTP 的联动
# 查看当前时间同步状态timedatectl timesync-status
# 开启/关闭 NTP 同步timedatectl set-ntp truetimedatectl set-ntp false
# 手动设置时间(需先关闭 NTP)timedatectl set-ntp falsetimedatectl set-time "2026-03-09 22:30:00"七、配置最佳实践
7.1 生产环境 Chrony 配置模板
# /etc/chrony.conf — 生产环境推荐配置
# === 上游时间源 ===# 使用多个国内源 + 国际源做冗余server ntp.aliyun.com iburst minpoll 4 maxpoll 6server ntp.tencent.com iburst minpoll 4 maxpoll 6server time.cloudflare.com iburst minpoll 4 maxpoll 6
# 兜底:使用本地硬件时钟local stratum 10
# === 客户端访问控制 ===allow 10.0.0.0/8allow 172.16.0.0/12allow 192.168.0.0/16
# === 时钟调整策略 ===# 启动后前 3 次更新允许步进(偏移 > 1 秒时直接跳转)makestep 1.0 3
# 运行时最大偏移速率(避免时钟跳变影响应用)maxchange 1000 1 2
# === 硬件时钟同步 ===rtcsync
# === 日志与数据 ===driftfile /var/lib/chrony/driftlogdir /var/log/chronylog measurements statistics tracking
# === 安全加固 ===# 禁止运行时通过 chronyc 修改配置cmdport 0# 或限制为仅本地访问# bindcmdaddress 127.0.0.1# bindcmdaddress ::17.2 内网层级同步架构
对于大规模内网部署,推荐采用层级架构:
┌─────────────────┐ │ 公网 NTP 源 │ │ (阿里云/腾讯云) │ └────────┬────────┘ │ ┌────────▼────────┐ │ 核心时间服务器 │ │ (Stratum 2) │ │ chrony + local │ └────────┬────────┘ │ ┌──────────────┼──────────────┐ │ │ │ ┌────────▼──────┐ ┌────▼────────┐ ┌───▼─────────┐ │ 部门时间服务器 │ │ 部门时间服务器│ │ 部门时间服务器│ │ (Stratum 3) │ │ (Stratum 3) │ │ (Stratum 3) │ └────────┬──────┘ └─────┬───────┘ └──────┬──────┘ │ │ │ ┌────▼───┐ ┌────▼───┐ ┌────▼───┐ │ 终端设备 │ │ 终端设备 │ │ 终端设备 │ └────────┘ └────────┘ └────────┘架构要点:
- 核心时间服务器至少部署 2 台,互为 peer 备份
- 每台核心服务器从 3+ 个公网 NTP 源同步
- 部门级服务器从核心服务器同步,降低公网流量
- 所有服务器配置
local stratum 10,确保上游断线时仍能提供时钟服务
7.3 监控与告警
# 检查同步状态的脚本(可用于监控)#!/bin/bashSYNC_STATUS=$(chronyc tracking | grep "Leap status" | awk '{print $4}')OFFSET=$(chronyc tracking | grep "System time" | awk '{print $4}')
if [ "$SYNC_STATUS" != "Normal" ]; then echo "CRITICAL: NTP not synchronized (Leap status: $SYNC_STATUS)" exit 2fi
# 偏移量超过 100ms 告警if (( $(echo "$OFFSET > 0.1" | bc -l) )); then echo "WARNING: Clock offset too large: ${OFFSET}s" exit 1fi
echo "OK: Clock synchronized, offset: ${OFFSET}s"exit 0# 定期检查脚本加入 crontab# 每 5 分钟检查一次同步状态*/5 * * * * /usr/local/bin/check_ntp_sync.sh >> /var/log/ntp_check.log 2>&1八、完整故障排查流程
高级排查技巧:
# 1. 抓包分析 NTP 报文tcpdump -i eth0 udp port 123 -vv
# 2. 查看 chronyd 的详细运行日志chronyc -m tracking sources sourcestats
# 3. 检查是否有其他进程占用 UDP 123ss -ulnp | grep :123
# 4. 验证 DNS 解析(NTP 池模式依赖 DNS)dig cn.pool.ntp.org
# 5. 测试特定 NTP 服务器的连通性nc -vzu ntp.aliyun.com 123
# 6. 检查系统是否启用了时间同步服务冲突systemctl list-units --type=service | grep -E 'ntp|chrony|systemd-timesyncd'九、参考资料
- chrony 官方文档
- chrony.conf 配置参考
- NTP Pool Project
- Red Hat — Configuring NTP Using the chrony Suite
- RFC 5905 — Network Time Protocol Version 4
- IEEE 1588 — Precision Time Protocol
- linuxptp 项目
参考
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






