mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
2937 字
8 分钟
Linux 服务器时间同步
2020-05-30

凌晨两点,生产环境的告警突然响起——某台核心服务器的时钟偏移了 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 字节
Info

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.0
fudge 127.127.1.0 stratum 8

127.127.1.0 是 NTP 的「本地时钟」伪地址,fudge 用于将该本地时钟的 stratum 调整为 8,确保在有外部源时不会被优先选择,但在失去外部源时仍能提供时钟服务。

客户端配置/etc/ntp.conf):注释掉无效的同步源,添加内网服务器地址:

# 注释掉原有无效 server 行,添加:
server 192.168.1.1 iburst

iburst 选项让 ntpd 在启动时快速发送 6 个请求(间隔 2 秒),加速初始同步。不加此选项时,ntpd 需要数分钟才能完成首次同步。

# 3. 启动 ntpd 服务
service ntpd start

2.2 访问控制配置#

ntpd 使用 restrict 指令控制访问权限,这是安全加固的关键配置:

# 默认拒绝所有访问
restrict default kod nomodify notrap nopeer noquery
# 允许本机完全访问
restrict 127.0.0.1
restrict ::1
# 允许内网网段查询和同步,但不允许修改服务器配置
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap nopeer
# 允许指定服务器作为上游时间源
restrict 0.centos.pool.ntp.org nomodify notrap nopeer

restrict 权限关键字说明

关键字作用
kod发送 Kiss-o’-Death 报文拒绝违规访问
nomodify禁止修改服务器运行时参数
notrap禁止陷阱消息(trap)
nopeer禁止对等体关联
noquery禁止状态查询(ntpq/ntpdc)
noserve禁止时间同步服务
Info

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 ntpd

ntpq -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 安装和基本配置#

# 安装 chrony
yum 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/chrony
log measurements statistics tracking

客户端配置/etc/chrony.conf):

# 添加内网时间服务器
server 192.168.1.1 iburst
# 允许时钟在启动后前三次更新时步进(而非渐进调整)
makestep 1.0 3
# 记录漂移
driftfile /var/lib/chrony/drift
# 硬件时钟同步(将系统时间同步到硬件时钟)
rtcsync

makestep 1.0 3 表示:在前 3 次时钟更新中,如果偏移量大于 1 秒,直接步进调整而非缓慢偏移。这对于启动时系统时间偏差较大的场景非常有用。

# 启动 chronyd
systemctl start chronyd
systemctl enable chronyd

3.2 三种同步模式#

模式关键字说明
Server 模式server严格分层:客户端向服务器同步,反向不影响
Pool 模式pool指定 NTP 服务器池(DNS 解析出多个地址),chronyd 自动选最优,默认取 4 个源
Peer 模式peer对等关系:双方互为服务器和客户端,适合两台主机互相备份时钟

配置示例——多源冗余

# 使用国内 NTP 池(适合国内服务器)
server ntp.aliyun.com iburst
server ntp.tencent.com iburst
server time.cloudflare.com iburst
# 或使用 pool 自动解析多个源
pool cn.pool.ntp.org iburst maxsources 4

3.3 常用维护命令#

# 立即强制同步系统时钟(不等待自然收敛)
chronyc -a makestep
# 查看所有同步源及其状态
chronyc sources -v
# 查看追踪信息(误差、漂移率等)
chronyc tracking
# 查看 chronyd 日志
journalctl -u chronyd
# 查看 NTP 源的详细统计信息
chronyc sourcestats -v
# 手动添加/删除 NTP 源(运行时生效,不写入配置)
chronyc add server ntp.example.com
chronyc delete ntp.example.com
# 查看当前活动的 NTP 源数量
chronyc activity
# 查看客户端访问日志(服务端使用)
chronyc clients

chronyc tracking 输出解读

Reference ID : A9FEA97B (ntp.aliyun.com)
Stratum : 3
Ref time (UTC) : Thu Mar 09 14:30:00 2026
System time : 0.000123456 seconds slow of NTP time
Last offset : -0.000456789 seconds
RMS offset : 0.000789012 seconds
Frequency : 5.678 ppm slow
Residual freq : -0.001 ppm
Skew : 0.012 ppm
Root delay : 0.023456789 seconds
Root dispersion : 0.001234567 seconds
Update interval : 1032.2 seconds
Leap status : Normal
  • System time:当前系统时钟与 NTP 时间的偏差
  • Frequency:硬件时钟的漂移率,单位 ppm(百万分之一),正值表示硬件时钟偏快
  • Root delay:到 Stratum 1 服务器的总网络延迟
  • Root dispersion:最大误差估计值
  • Leap status:闰秒状态,Normal 表示无闰秒预告

3.4 常见问题排查#

Info

tip

时间同步失败时,按以下顺序逐步排查:

  1. 防火墙:NTP 使用 UDP 123 端口,确保防火墙放行:

    # firewalld
    firewall-cmd --add-service=ntp --permanent && firewall-cmd --reload
    # iptables
    iptables -A INPUT -p udp --dport 123 -j ACCEPT
    iptables -A OUTPUT -p udp --sport 123 -j ACCEPT
  2. 服务端 allow 配置:确认 /etc/chrony.confallow 配置允许客户端所在网段访问。

  3. 本地参考模式:若内网服务器无法连接外部 NTP 源,必须配置 local stratum 10,否则 chronyd 在「非同步状态」下不会向客户端提供时钟服务。stratum 数值越小表示时间越可靠(1 为原子钟级别,10 为降级本地参考)。

  4. 时区统一:时区不一致会导致时间显示错误(但不影响 UTC 同步):

    timedatectl list-timezones | grep Shanghai
    timedatectl set-timezone Asia/Shanghai
    timedatectl status
  5. 通过 chronyc 诊断

    chronyc sources -v # 检查同步源状态(* 表示当前使用的源)
    chronyc tracking # 查看系统时钟误差和漂移
  6. ntpd 与 chronyd 冲突:两者不能同时运行,chronyd 启动时会检测并拒绝启动:

    # 检查是否有 ntpd 在运行
    ps aux | grep ntpd
    # 停用 ntpd 并确保 chronyd 正常
    systemctl stop ntpd
    systemctl disable ntpd
    systemctl start chronyd
  7. 虚拟机时钟漂移:虚拟机由于 CPU 时间片调度,时钟漂移比物理机严重得多。推荐在虚拟机中优先使用 chrony,并适当缩短同步间隔:

    # /etc/chrony.conf — 虚拟机优化配置
    server 192.168.1.1 iburst maxpoll 6
    makestep 0.1 3

    maxpoll 6 将最大轮询间隔设为 2^6 = 64 秒(默认 2^10 = 1024 秒),在虚拟机环境中能更快补偿漂移。


四、Chrony vs NTPd 对比#

特性ChronyNTPd
启动同步速度数秒内完成(硬件时钟准确时更快)需要数分钟到数十分钟
网络适应性间歇连接、高延迟、高抖动环境优秀需要稳定网络
时钟调整方式支持步进+渐变(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)是一种亚微秒级精度的时间同步协议,适用于金融交易、电信网络、工业控制等对时间精度要求极高的场景。

特性NTPPTP
精度毫秒级(1-10ms)亚微秒级(<1us)
协议UDP 123UDP 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)#

# 安装 linuxptp
yum install linuxptp
# 查看网卡是否支持硬件时间戳
ethtool -T eth0

ethtool -T 输出中,hardware-receivehardware-transmiton 表示支持硬件时间戳,这是实现亚微秒精度的关键。

PTP 主时钟配置/etc/ptp4l.conf):

[global]
# 仅使用硬件时间戳
time_stamping hardware
# 优先级(数值越小越优先当选 Grandmaster)
priority1 128
priority2 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 -m

PTP 从时钟配置

# 作为从时钟运行(自动通过 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 字段表示从时钟与主时钟的偏差,单位纳秒。

Info

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 shanghai
timedatectl list-timezones | grep -i tokyo
# 设置时区
timedatectl set-timezone Asia/Shanghai
# 设置 UTC 时区(服务器推荐)
timedatectl set-timezone UTC

6.2 硬件时钟(RTC)管理#

Linux 有两个时钟:系统时钟(内核维护,启动时从 RTC 读取)和 硬件时钟/RTC(主板电池供电,关机后保持)。

# 查看硬件时钟时间
hwclock --show
# 将系统时间写入硬件时钟(系统→硬件)
hwclock --systohc
# 将系统时间写入硬件时钟(指定 UTC 格式)
hwclock --systohc --utc
# 将硬件时钟时间读入系统(硬件→系统)
hwclock --hctosys
# 查看硬件时钟使用的时区标准
timedatectl | grep "RTC in local TZ"
Info

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 1

6.3 时间同步与 NTP 的联动#

# 查看当前时间同步状态
timedatectl timesync-status
# 开启/关闭 NTP 同步
timedatectl set-ntp true
timedatectl set-ntp false
# 手动设置时间(需先关闭 NTP)
timedatectl set-ntp false
timedatectl set-time "2026-03-09 22:30:00"

七、配置最佳实践#

7.1 生产环境 Chrony 配置模板#

# /etc/chrony.conf — 生产环境推荐配置
# === 上游时间源 ===
# 使用多个国内源 + 国际源做冗余
server ntp.aliyun.com iburst minpoll 4 maxpoll 6
server ntp.tencent.com iburst minpoll 4 maxpoll 6
server time.cloudflare.com iburst minpoll 4 maxpoll 6
# 兜底:使用本地硬件时钟
local stratum 10
# === 客户端访问控制 ===
allow 10.0.0.0/8
allow 172.16.0.0/12
allow 192.168.0.0/16
# === 时钟调整策略 ===
# 启动后前 3 次更新允许步进(偏移 > 1 秒时直接跳转)
makestep 1.0 3
# 运行时最大偏移速率(避免时钟跳变影响应用)
maxchange 1000 1 2
# === 硬件时钟同步 ===
rtcsync
# === 日志与数据 ===
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
log measurements statistics tracking
# === 安全加固 ===
# 禁止运行时通过 chronyc 修改配置
cmdport 0
# 或限制为仅本地访问
# bindcmdaddress 127.0.0.1
# bindcmdaddress ::1

7.2 内网层级同步架构#

对于大规模内网部署,推荐采用层级架构:

┌─────────────────┐
│ 公网 NTP 源 │
│ (阿里云/腾讯云) │
└────────┬────────┘
┌────────▼────────┐
│ 核心时间服务器 │
│ (Stratum 2) │
│ chrony + local │
└────────┬────────┘
┌──────────────┼──────────────┐
│ │ │
┌────────▼──────┐ ┌────▼────────┐ ┌───▼─────────┐
│ 部门时间服务器 │ │ 部门时间服务器│ │ 部门时间服务器│
│ (Stratum 3) │ │ (Stratum 3) │ │ (Stratum 3) │
└────────┬──────┘ └─────┬───────┘ └──────┬──────┘
│ │ │
┌────▼───┐ ┌────▼───┐ ┌────▼───┐
│ 终端设备 │ │ 终端设备 │ │ 终端设备 │
└────────┘ └────────┘ └────────┘

架构要点

  • 核心时间服务器至少部署 2 台,互为 peer 备份
  • 每台核心服务器从 3+ 个公网 NTP 源同步
  • 部门级服务器从核心服务器同步,降低公网流量
  • 所有服务器配置 local stratum 10,确保上游断线时仍能提供时钟服务

7.3 监控与告警#

check_ntp_sync.sh
# 检查同步状态的脚本(可用于监控)
#!/bin/bash
SYNC_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 2
fi
# 偏移量超过 100ms 告警
if (( $(echo "$OFFSET > 0.1" | bc -l) )); then
echo "WARNING: Clock offset too large: ${OFFSET}s"
exit 1
fi
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

八、完整故障排查流程#

flowchart TD START[时间同步异常] --> CHECK1{ntpd/chronyd<br>是否运行?} CHECK1 -->|否| FIX1[启动服务<br>systemctl start chronyd] CHECK1 -->|是| CHECK2{ntpd 与 chronyd<br>是否冲突?} CHECK2 -->|是| FIX2[停用 ntpd<br>启用 chronyd] CHECK2 -->|否| CHECK3{UDP 123 端口<br>是否放行?} CHECK3 -->|否| FIX3[放行防火墙<br>firewall-cmd --add-service=ntp] CHECK3 -->|是| CHECK4{上游源<br>是否可达?} CHECK4 -->|否| FIX4[检查网络<br>ping/nc 测试上游] CHECK4 -->|是| CHECK5{allow 配置<br>是否允许客户端?} CHECK5 -->|否| FIX5[添加 allow 规则] CHECK5 -->|是| CHECK6{local stratum<br>是否配置?} CHECK6 -->|否| FIX6[添加 local stratum 10] CHECK6 -->|是| CHECK7{时区是否一致?} CHECK7 -->|否| FIX7[timedatectl set-timezone] CHECK7 -->|是| CHECK8{偏移量是否过大?} CHECK8 -->|是| FIX8[手动步进<br>chronyc makestep] CHECK8 -->|否| DONE[检查日志<br>journalctl -u chronyd] FIX1 --> RECHECK[重新检查] FIX2 --> RECHECK FIX3 --> RECHECK FIX4 --> RECHECK FIX5 --> RECHECK FIX6 --> RECHECK FIX7 --> RECHECK FIX8 --> RECHECK RECHECK --> CHECK1

高级排查技巧

# 1. 抓包分析 NTP 报文
tcpdump -i eth0 udp port 123 -vv
# 2. 查看 chronyd 的详细运行日志
chronyc -m tracking sources sourcestats
# 3. 检查是否有其他进程占用 UDP 123
ss -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'

九、参考资料#


参考#

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

Linux 服务器时间同步
https://blog.souloss.com/posts/tools/linux-time-sync/
作者
Souloss
发布于
2020-05-30
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时