Rocky Linux 10 搭建 NTP Server 与 Chrony Client:内网授时、离线容灾与生产调优

在单机环境中,系统时间偏差几秒似乎问题不大;但在企业基础设施中,时间错误往往会引发一串很难排查的问题:

  • Kerberos、Active Directory、CAS 或票据认证失败;
  • TLS 证书被判断为尚未生效或已经过期;
  • 数据库主从、分布式锁、选主和事务时间线异常;
  • 日志顺序错乱,无法还原真实故障过程;
  • Kubernetes、etcd、消息队列和定时任务行为异常;
  • 虚拟机快照恢复后出现大幅时间跳变;
  • 审计、计费、订单和结算记录缺少可信时间基线。

Rocky Linux 10 默认使用 chrony 实现 NTP 客户端和服务器能力。其核心组件为:

1
2
3
chronyd:后台守护进程,负责测量、选择时间源并调整系统时钟
chronyc:管理和诊断命令,用于查看 tracking、sources、clients 等状态
/etc/chrony.conf:主配置文件

截至 2026 年 7 月 31 日,Rocky Linux 10 BaseOS 仓库中的 Chrony 版本基线为 4.8-2.el10。本文使用 Chrony 搭建企业内网 NTP Server,并配置 Client、离线容灾、监控和生产调优。

一、NTP、Chrony 与系统时钟

1.1 NTP 是协议,Chrony 是实现

NTP(Network Time Protocol)是网络时间同步协议,默认使用:

1
UDP 123

Chrony 是 NTP 的一种实现,既可以从上游获取时间,也可以向下游提供时间。

flowchart LR
    Upstream[公网或上级 NTP 源] -->|UDP 123| Server[Rocky Linux 10<br/>chronyd NTP Server]
    Server -->|UDP 123| Client1[应用服务器]
    Server -->|UDP 123| Client2[数据库服务器]
    Server -->|UDP 123| Client3[Kubernetes 节点]

1.2 System Clock 与 RTC

Linux 中主要有两套时钟:

时钟 说明
System Clock 内核运行期间使用的软件时钟,应用读取的主要时间来源
RTC / Hardware Clock 主板实时时钟,关机后继续运行,开机时用于初始化系统时间

查看:

1
2
3
4
date
date -u
timedatectl
hwclock --show

推荐让 RTC 保存 UTC:

1
timedatectl set-local-rtc 0

时区只决定显示方式,不改变 NTP 同步的 UTC 基准:

1
timedatectl set-timezone Asia/Shanghai

1.3 Stratum

Stratum 说明
0 原子钟、GPS、北斗、PPS 等参考时钟本身
1 直接连接 Stratum 0 的服务器
2 从 Stratum 1 同步
3 从 Stratum 2 同步
4~15 更下游层级
16 未同步,不可作为有效时间源

Stratum 低不等于一定更准确。Chrony 还会综合延迟、抖动、误差区间和来源一致性进行选择。

二、企业推荐架构

不建议让所有服务器直接访问公网 NTP,而是建立内部授时层:

flowchart TD
    A1[独立上游 NTP 1] --> N1[内部 NTP 1]
    A2[独立上游 NTP 2] --> N1
    A3[独立上游 NTP 3] --> N1
    A4[独立上游 NTP 4] --> N1

    A1 --> N2[内部 NTP 2]
    A2 --> N2
    A3 --> N2
    A4 --> N2

    N1 --> App[业务服务器]
    N2 --> App
    N1 --> DB[数据库服务器]
    N2 --> DB
    N1 --> K8S[Kubernetes 节点]
    N2 --> K8S

优势:

  • 只有内部 NTP Server 访问公网;
  • 客户端配置统一;
  • 降低公网抖动和 DNS 变化影响;
  • 上游切换不需要修改所有客户端;
  • 更容易审计、监控和隔离;
  • 断网时仍可按既定策略维持内部时间。

2.1 至少四个独立上游来源

内部 NTP Server 推荐配置至少四个独立来源:

数量 风险
1 无法判断唯一来源是否错误
2 两个来源冲突时无法判断谁正确
3 可容忍一个错误源,但再失联一个会退化成二选一
4 个以上 更容易形成多数并排除 Falseticker

“独立”应尽量包括不同服务商、网络路径、物理基础设施和参考时钟,而不是四个域名最终指向同一组设备。

2.2 两台内部 Server 的边界

两台内部服务器是常见方案,但两者不一致时,客户端没有第三票可判断谁正确。更稳健的方式是:

  • 部署 3~4 台内部服务器;
  • 或 2 台内部服务器加可信备用源;
  • 或引入 GPS/PPS 等独立参考源。

如果只能部署两台,应持续监控二者偏差,并对分歧立即告警。

三、实验环境

角色 主机名 IP
NTP Server 1 ntp01.example.com 192.168.9.10
NTP Server 2 ntp02.example.com 192.168.9.11
Client app01.example.com 192.168.9.20
内网网段 - 192.168.9.0/24

测试环境可配置:

1
2
3
4
5
cat >> /etc/hosts <<'EOF_HOSTS'
192.168.9.10 ntp01.example.com ntp01
192.168.9.11 ntp02.example.com ntp02
192.168.9.20 app01.example.com app01
EOF_HOSTS

生产环境应使用企业 DNS。

四、安装与检查 Chrony

Rocky Linux 10 通常已默认安装:

1
2
3
rpm -q chrony
chronyd -v
chronyc -v

未安装时:

1
dnf install -y chrony

查看文件:

1
rpm -ql chrony

启动:

1
systemctl enable --now chronyd

检查:

1
2
3
4
systemctl status chronyd --no-pager -l
systemctl is-enabled chronyd
systemctl is-active chronyd
journalctl -u chronyd -n 100 --no-pager

Rocky Linux 10 默认配置通常包含:

1
2
3
4
5
6
7
pool 2.rocky.pool.ntp.org iburst
sourcedir /run/chrony-dhcp
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
ntsdumpdir /var/lib/chrony
logdir /var/log/chrony

云厂商、Kickstart 或 NetworkManager 可能改写默认时间源,所以应以实际文件为准:

1
cat /etc/chrony.conf

五、核心配置项

5.1 server 与 pool

固定服务器使用:

1
2
server ntp1.example.net iburst
server 192.0.2.10 iburst

真正会解析到多个地址的池使用:

1
pool 2.rocky.pool.ntp.org iburst maxsources 4

不要对单个 IP 使用 pool

5.2 iburst

1
server ntp01.example.com iburst

初次通信时快速发送一组请求,加快首次同步。它不会让客户端长期高频轮询。

5.3 driftfile

1
driftfile /var/lib/chrony/drift

记录本机时钟变快或变慢的频率偏差。Chrony 重启后可利用它更快稳定。不要把清理 Drift 文件当成常规操作。

5.4 makestep

1
makestep 1.0 3

在最初 3 次时钟更新中,偏差超过 1 秒时允许直接 Step。启动早期通常合理,但运行期间频繁 Step 会破坏日志顺序、数据库时间线、Token 和分布式协议。

5.5 rtcsync

1
rtcsync

让内核定期把已同步的系统时间写入 RTC。

5.6 allow

1
allow 192.168.9.0/24

允许指定网段使用本机 NTP 服务。默认情况下,Chrony 不向任意远程客户端提供时间。

5.7 local

1
local stratum 10

即使没有外部同步源,也继续向客户端提供本地时间。联网生产环境默认不要开启,因为上游全部失效后,本机可能逐渐漂移却仍表现为可用服务器。

5.8 minsources

1
minsources 2

至少有两个可选择来源时才更新本机时钟。它提升正确性,但如果只配置两个来源,其中一个失联,系统会停止更新。

5.9 hwtimestamp

1
hwtimestamp eth0

对支持的 NIC 启用硬件时间戳。它只有在网卡、驱动、交换网络和对端均支持,并且确实有高精度需求时才有价值。

六、搭建联网 NTP Server

ntp01ntp02 上执行。

6.1 备份

1
2
3
cp -a \
/etc/chrony.conf \
"/etc/chrony.conf.bak.$(date +%F-%H%M%S)"

6.2 推荐配置

/etc/chrony.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 上游时间源:生产环境替换为经过验证的独立来源
server ntp1.example.net iburst
server ntp2.example.net iburst
server ntp3.example.net iburst
server ntp4.example.net iburst

# 固定企业配置时,不再接收 DHCP 注入的 NTP 源
# sourcedir /run/chrony-dhcp

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

# 至少两个可选择来源时才更新本机时间
minsources 2

# 拒绝不确定度过高的频率更新
maxupdateskew 100.0

# 允许内网客户端
allow 192.168.9.0/24

# 多网卡主机可选:只在内网地址提供 NTP
bindaddress 192.168.9.10

# 限制单个源地址的异常请求速率
ratelimit interval 1 burst 16

# 增加客户端状态容量,便于 clients 统计和 xleave
clientloglimit 1048576

ntsdumpdir /var/lib/chrony
logdir /var/log/chrony

# 排障时按需开启,稳定后可关闭
# log measurements statistics tracking

ntp02 将绑定地址改为:

1
bindaddress 192.168.9.11

6.3 不默认开启 local stratum

联网服务器不加入:

1
local stratum 10

这样上游长期失效时,下游能够识别该服务器不再可靠,而不是继续接受漂移时间。

6.4 重启与检查

1
2
systemctl restart chronyd
journalctl -u chronyd -n 200 --no-pager

查看监听:

1
ss -ulnp | grep ':123'

6.5 firewalld

只允许内网网段访问:

1
2
3
4
5
6
7
systemctl enable --now firewalld

firewall-cmd \
--permanent \
--add-rich-rule='rule family="ipv4" source address="192.168.9.0/24" service name="ntp" accept'

firewall-cmd --reload

检查:

1
firewall-cmd --list-rich-rules

firewalld 控制数据包能否到达进程,allow 控制 Chrony 是否响应,两层都应设置。

6.6 SELinux

标准 UDP 123 通常不需要额外 SELinux 配置:

1
2
getenforce
ausearch -m AVC -ts recent

不要为了省事直接关闭 SELinux。

七、配置 Chrony Client

app01 上执行。

7.1 普通企业客户端

1
2
3
cp -a \
/etc/chrony.conf \
"/etc/chrony.conf.bak.$(date +%F-%H%M%S)"

/etc/chrony.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server ntp01.example.com iburst
server ntp02.example.com iburst

# 如果有更多内部时间服务器,应全部配置
# server ntp03.example.com iburst
# server ntp04.example.com iburst

# 固定企业来源时,不使用 DHCP 注入源
# sourcedir /run/chrony-dhcp

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
maxupdateskew 100.0

# 显式禁止本机提供 NTP 服务,只作为客户端
port 0

ntsdumpdir /var/lib/chrony
logdir /var/log/chrony

7.2 严格可靠性客户端

有 4 台内部时间服务器时:

1
2
3
4
5
6
7
8
9
10
11
12
server ntp01.example.com iburst
server ntp02.example.com iburst
server ntp03.example.com iburst
server ntp04.example.com iburst

minsources 2

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
maxupdateskew 100.0
port 0

7.3 启动与首次同步

1
2
systemctl enable --now chronyd
systemctl restart chronyd

需要在维护窗口立即校准时:

1
chronyc makestep

等待偏差小于 10 毫秒,最多检查 60 次:

1
chronyc waitsync 60 0.01

不要在数据库、交易或关键任务运行期间随意 Step。

八、检查同步状态

8.1 timedatectl

1
timedatectl

关注:

1
2
3
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

服务 Active 不代表当前一定已选中有效时间源。

8.2 tracking

1
chronyc tracking

关键字段:

字段 说明
Reference ID 当前选中的来源
Stratum 当前层级
Ref time 最近一次有效更新时间
System time 系统时间与 Chrony 估计时间的剩余差值
Last offset 最近一次偏差
RMS offset 一段时间内偏差均方根
Frequency 本机时钟频率快慢
Skew 频率估计不确定度
Root delay 到参考时钟的累计延迟
Root dispersion 累计误差上界
Leap status 健康时应为 Normal

8.3 sources -v

1
chronyc -n sources -v

状态符号:

符号 含义
^* 当前选中的 NTP Server
^+ 可接受并参与组合的来源
^- 可接受但未参与当前组合
^? 不可达、样本不足或未通过测试
^x Falseticker
^~ 抖动过大
#* 选中的本地参考时钟,如 GPS/PPS

Reach=377 表示最近 8 次请求全部收到响应;长期为 0 说明没有有效回复。

8.4 其他命令

1
2
3
chronyc sourcestats -v
chronyc activity
chronyc ntpdata

服务器查看客户端:

1
2
chronyc clients
chronyc serverstats

九、验证客户端确实走内网 NTP

客户端:

1
chronyc -n sources -v

应看到:

1
2
192.168.9.10
192.168.9.11

抓包:

1
2
3
dnf install -y tcpdump

tcpdump -ni any udp port 123

服务端:

1
chronyc clients

NTP 使用 UDP,不能用 telnet IP 123 判断服务是否正常。

十、上游选择与信任策略

优先级建议:

  1. 企业或数据中心提供的高质量 NTP;
  2. 云厂商同区域本地时间服务;
  3. 运营商或经过验证的授时服务;
  4. 公共 NTP Pool;
  5. GPS/PPS 或硬件时间源。

可对一个经过验证、网络质量更好的来源配置:

1
server ntp1.example.net iburst prefer

不要给所有来源都加 prefer

trustrequire 更应谨慎:

1
server secure-time.example.net iburst trust require

只适合经过认证的硬件源、NTS 源或本地 GPS/PPS。不要把普通公网源随意设为绝对可信。

十一、DHCP 与 NetworkManager

Rocky Linux 10 默认可能包含:

1
sourcedir /run/chrony-dhcp

查看 DHCP 注入来源:

1
find /run/chrony-dhcp -maxdepth 1 -type f -print -exec cat {} \;

企业要求固定来源时,应注释该行,否则可能出现手工来源与 DHCP 来源混合。

11.1 Dispatcher 将来源置为 Offline

NetworkManager 会通过 Dispatcher 管理来源 Online/Offline。使用自定义路由、VPN、策略路由或非 NetworkManager 网络时,可能出现来源被置为 Offline 后无法恢复。

需要让 Chrony 始终轮询时,可禁用 Dispatcher:

1
2
3
4
5
6
7
ln -f -s \
/dev/null \
/etc/NetworkManager/dispatcher.d/20-chrony-onoffline

systemctl restart NetworkManager
systemctl restart chronyd
chronyc online

只有确认命中该场景时再执行。

十二、联网失联与离线网络

12.1 联网环境默认策略

联网生产环境不配置 local。上游全部失效后,服务器最终不再被客户端视为可靠来源,并触发监控告警。

这牺牲“永远有源”的表面可用性,换取不向全网分发错误时间。

12.2 单节点离线 Server

完全隔离网络可使用:

1
2
3
4
5
6
7
8
9
10
11
12
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

local stratum 10

allow 192.168.9.0/24
bindaddress 192.168.9.10
ratelimit interval 1 burst 16
clientloglimit 1048576

logdir /var/log/chrony

这种模式保证内部相对一致,但可能逐渐偏离真实 UTC。长期运行应考虑人工校时、GPS、北斗、PPS 或更稳定的硬件时钟。

12.3 多节点 Orphan Mode

多个离线服务器可:

1
2
3
4
5
6
7
8
9
10
server 192.168.9.11 iburst
server 192.168.9.12 iburst
server 192.168.9.13 iburst

local stratum 10 orphan

allow 192.168.9.0/24
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

Orphan Mode 会在同组服务器中选出一个本地参考,失效后由其他节点接管。

离线客户端配置所有内部服务器:

1
2
3
4
server 192.168.9.10 iburst
server 192.168.9.11 iburst
server 192.168.9.12 iburst
server 192.168.9.13 iburst

十三、轮询间隔调优

minpollmaxpoll 使用 2 的指数:

间隔
2 4 秒
3 8 秒
4 16 秒
5 32 秒
6 64 秒
7 128 秒
8 256 秒
9 512 秒
10 1024 秒

WAN 上游通常保持默认即可:

1
server ntp1.example.net iburst

低延迟高精度局域网可考虑:

1
2
server ntp01.example.com iburst minpoll 4 maxpoll 6
server ntp02.example.com iburst minpoll 4 maxpoll 6

即 16~64 秒。

不要让全网客户端每秒轮询。10000 台客户端每秒一次,就是 10000 QPS;不仅浪费资源,还会触发限速并增加网络抖动。

十四、网络质量过滤

低延迟局域网中可以限制最大往返延迟:

1
server ntp01.example.com iburst maxdelay 0.05

表示超过约 50 毫秒的样本不使用。

不要把 LAN 阈值复制到跨地域或公网,否则正常来源可能全部被拒绝。

maxupdateskew

1
maxupdateskew 100.0

当频率估计不确定度过高时,不使用该更新。不要为了快速显示“已同步”就无限放大阈值。

十五、大规模客户端与限速

服务端:

1
ratelimit interval 1 burst 16

可限制单个源 IP 的异常请求。多个客户端经过同一 NAT 时会被视为同一个源地址,应评估共享出口影响。

默认客户端日志容量有限,大规模环境可增加:

1
clientloglimit 16777216

是否需要取决于客户端数量、chronyc clients、Rate Limit 和 Interleaved Mode。

noclientlog 会降低内存占用,但会损失客户端统计并关闭服务端 Interleaved Mode 支持,不能无脑开启。

十六、Chronyc 远程管理安全

NTP 服务端口是 UDP 123;Chronyc 远程命令端口默认是 UDP 323,但默认只绑定回环地址,本地 root 还可使用 Unix Socket。

不要随意配置:

1
2
bindcmdaddress 0.0.0.0
cmdallow all

推荐通过 SSH 登录服务器后执行 chronyc,或让监控 Agent 在本机采集。

必须远程采集时,只允许专用监控节点并只开放必要命令:

1
2
3
4
bindcmdaddress 192.168.9.10
cmdallow 192.168.9.100/32
opencommands tracking sources sourcestats activity serverstats
cmdratelimit interval 2

同时在防火墙限制 UDP 323 来源。

十七、硬件时间戳与高精度

检查 NIC:

1
2
dnf install -y ethtool
ethtool -T eth0

关注:

1
2
3
hardware-transmit
hardware-receive
hardware-raw-clock

启用:

1
hwtimestamp eth0

重启并检查:

1
2
systemctl restart chronyd
chronyc ntpdata

TX timestampingRX timestamping 显示 Hardware 才表示实际使用。

17.1 Interleaved Mode

双方支持时,客户端来源可加入:

1
server ntp01.example.com iburst xleave

它可以提高精度,但依赖服务端保存客户端状态,不适合共享 NAT、状态容量不足或实现不兼容的网络。

17.2 NTP 与 PTP 的边界

如果目标是稳定亚微秒、工业控制、电信同步或高频测量,应评估 PTP、PHC、Boundary Clock、Transparent Clock 和专用网卡。hwtimestamp * 不是 PTP 的平替。

十八、NTS 安全时间

传统 NTP 默认不验证服务器身份。NTS 使用 TLS 建立认证材料,再保护后续 NTP 通信。

客户端示例:

1
server nts.example.net iburst nts

只允许认证来源:

1
authselectmode require

NTS 通常涉及:

1
2
TCP 4460:NTS-KE 密钥协商
UDP 123:NTP 数据

注意:

  • 上游必须支持 NTS;
  • DNS、证书链和系统时间必须合理;
  • authselectmode require 配错后可能完全无法同步;
  • 应使用多个独立 NTS 来源。

Chrony 作为 NTS Server 时可配置:

1
2
3
ntsservercert /etc/pki/tls/certs/ntp.example.com.crt
ntsserverkey /etc/pki/tls/private/ntp.example.com.key
ntsratelimit interval 3 burst 1

并开放 TCP 4460、保护私钥、监控证书有效期。

十九、虚拟机环境

虚拟化平台可能同时提供 VMware Tools、Hyper-V Integration、QEMU Guest Agent 或云 Agent 时间同步。

如果它与 Chrony 同时持续调时:

1
2
3
Chrony Slew
-> Guest Tool 突然 Step
-> Chrony 再反向修正

会造成 Offset 周期性跳变和日志倒退。

建议:

  • Chrony 负责持续时间同步;
  • 虚拟化平台仅在开机、恢复或迁移时一次性校准;
  • 禁用 Guest Tools 的周期性强制调时;
  • 快照恢复后先检查时间,再让数据库和集群服务上线。

检查 Clocksource:

1
2
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
cat /sys/devices/system/clocksource/clocksource0/available_clocksource

没有证据时不要手工切换 Clocksource。

二十、容器与 Kubernetes

普通 Linux 容器共享宿主机内核时钟,因此不要在每个容器中运行 Chrony。

正确方式:

1
宿主机同步时间 -> 容器自动看到同一系统时间

容器中的 TZ/etc/localtime 只影响显示时区,不改变时间基准。

Kubernetes 应监控所有 Node 宿主机之间的偏差。

二十一、日志与监控

排障时可开启:

1
2
log measurements statistics tracking
logdir /var/log/chrony

重启:

1
systemctl restart chronyd

稳定后评估关闭高频日志,避免长期占用磁盘。

建议监控:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Leap status
Stratum
System time offset
Last/RMS offset
Root delay
Root dispersion
Skew
Reach
在线来源数量
可选择来源数量
Falseticker 数量
客户端数量
上游 DNS 和网络可达性
UDP 123 监听

简单健康检查脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat > /usr/local/sbin/check-chrony.sh <<'EOF_SCRIPT'
#!/usr/bin/env bash

set -Eeuo pipefail

TRACKING="$(chronyc tracking)"
SOURCES="$(chronyc sources)"

if ! grep -q 'Leap status.*Normal' <<< "${TRACKING}"; then
echo "CRITICAL: chrony is not synchronized"
echo "${TRACKING}"
exit 2
fi

if ! grep -qE '^[#^]\*' <<< "${SOURCES}"; then
echo "CRITICAL: no selected time source"
echo "${SOURCES}"
exit 2
fi

echo "OK: chrony synchronized"
EOF_SCRIPT

chmod 0755 /usr/local/sbin/check-chrony.sh

生产监控最好采集结构化指标,不要长期依赖文本解析。

二十二、批量配置客户端

22.1 Shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cat > /usr/local/sbin/configure-chrony-client.sh <<'EOF_SCRIPT'
#!/usr/bin/env bash

set -Eeuo pipefail

CONFIG_FILE="/etc/chrony.conf"
BACKUP_FILE="${CONFIG_FILE}.bak.$(date +%F-%H%M%S)"

[[ -f "${CONFIG_FILE}" ]] && cp -a "${CONFIG_FILE}" "${BACKUP_FILE}"

cat > "${CONFIG_FILE}" <<'EOF_CONFIG'
server ntp01.example.com iburst
server ntp02.example.com iburst

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
maxupdateskew 100.0
port 0
ntsdumpdir /var/lib/chrony
logdir /var/log/chrony
EOF_CONFIG

systemctl enable --now chronyd
systemctl restart chronyd

chronyc online
chronyc sources -v
chronyc tracking
EOF_SCRIPT

chmod 0750 /usr/local/sbin/configure-chrony-client.sh

22.2 Ansible

chrony.conf.j2

1
2
3
4
5
6
7
8
9
10
11
{% for server in chrony_servers %}
server {{ server }} iburst
{% endfor %}

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
maxupdateskew 100.0
port 0
ntsdumpdir /var/lib/chrony
logdir /var/log/chrony

Playbook:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- name: Configure chrony clients
hosts: all
become: true

vars:
chrony_servers:
- ntp01.example.com
- ntp02.example.com

tasks:
- name: Install chrony
ansible.builtin.dnf:
name: chrony
state: present

- name: Deploy chrony configuration
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony.conf
owner: root
group: root
mode: "0644"
notify: Restart chronyd

- name: Enable chronyd
ansible.builtin.systemd_service:
name: chronyd
enabled: true
state: started

handlers:
- name: Restart chronyd
ansible.builtin.systemd_service:
name: chronyd
state: restarted

二十三、滚动变更

不要同时重启所有内部 NTP Server:

flowchart LR
    A[修改 ntp02] --> B[验证 ntp02 上游同步]
    B --> C[验证客户端可访问 ntp02]
    C --> D[等待稳定]
    D --> E[修改 ntp01]
    E --> F[验证整个时间层级]

验证:

1
2
3
4
chronyc tracking
chronyc sources -v
chronyc sourcestats -v
ss -ulnp | grep ':123'

二十四、备份与恢复

建议备份:

1
2
3
4
5
6
7
/etc/chrony.conf
/etc/chrony.keys
NTS 证书和私钥
/var/lib/chrony/drift
/var/lib/chrony 中的 NTS 数据
systemd Override
防火墙和监控配置
1
2
3
4
5
6
7
8
9
10
11
mkdir -p /backup/chrony

tar \
--xattrs \
--acls \
-czf "/backup/chrony/chrony-$(date +%F-%H%M%S).tar.gz" \
/etc/chrony.conf \
/etc/chrony.keys \
/var/lib/chrony \
/etc/systemd/system/chronyd.service.d \
2>/dev/null || true

恢复后:

1
2
3
4
5
restorecon -Rv /etc/chrony.conf /etc/chrony.keys /var/lib/chrony
systemctl daemon-reload
systemctl restart chronyd
chronyc sources -v
chronyc tracking

NTS 私钥必须加密备份并限制权限。

二十五、常见故障

25.1 Leap status: Not synchronised

1
2
3
4
chronyc tracking
chronyc sources -v
chronyc activity
journalctl -u chronyd -n 300 --no-pager

常见原因:

  • UDP 123 被阻断;
  • DNS 解析失败;
  • 来源被 NetworkManager 标记 Offline;
  • 不满足 minsources
  • 来源互相冲突;
  • 过滤阈值过严;
  • NTS 证书失败;
  • 虚拟机时间被其他工具修改。

25.2 来源一直是 ^?

1
2
3
getent ahosts ntp01.example.com
ip route get 192.168.9.10
tcpdump -ni any host 192.168.9.10 and udp port 123

服务端:

1
2
3
ss -ulnp | grep ':123'
firewall-cmd --list-all
chronyc clients

25.3 服务端没有监听 123

检查:

1
grep -nE '^[[:space:]]*(allow|port)' /etc/chrony.conf

客户端配置中的:

1
port 0

会禁止服务端监听。

25.4 防火墙已开放但仍不同步

还要检查:

1
allow 192.168.9.0/24

验证访问规则:

1
chronyc accheck 192.168.9.20

25.5 Reach 长期为 0

1
2
chronyc online
chronyc activity

排查请求是否发出、回复是否被丢弃、服务端 allow、NAT 和策略路由。

25.6 Can’t synchronise: no majority

1
2
3
chronyc sources -v
chronyc sourcestats -v
chronyc selectdata

不要马上给其中一个来源加 trust,应先找出异常源、网络非对称、虚拟化调时或上游同源问题。

25.7 偏差很大

1
2
chronyc tracking
chronyc sourcestats -v

启动早期或维护窗口可:

1
chronyc makestep

25.8 重启后又偏差很大

1
2
3
grep -E '^(driftfile|rtcsync)' /etc/chrony.conf
ls -l /var/lib/chrony/drift
hwclock --show

可能是 RTC 电池、RTC 本地时间、快照恢复、宿主机时间、Guest Tools 或 Drift 文件权限问题。

25.9 上游失联后仍向客户端服务

检查是否配置:

1
local stratum 10

联网环境不需要时应删除并重启。

25.10 时间正确但时区不对

1
timedatectl set-timezone Asia/Shanghai

不要通过手工修改系统时钟来修正时区。

25.11 NTS 无法建立

1
2
3
tcpdump -ni any tcp port 4460
chronyc authdata
journalctl -u chronyd -n 300 --no-pager

检查证书链、DNS、系统初始时间和 TCP 4460。

二十六、不要做的事情

26.1 不要用 Cron 执行 date -s

错误方式:

1
* * * * * date -s "$(ssh ntp-server date)"

它会频繁 Step,破坏日志、数据库和分布式协议,并完全绕开 NTP 的质量评估。

26.2 不要同时运行多个调时守护进程

1
2
3
systemctl status chronyd
systemctl status ntpd
systemctl status systemd-timesyncd

同一系统只保留一个主要时间同步服务。

26.3 不要向公网无条件开放 NTP

使用:

1
2
3
4
allow 内网网段
+ firewalld 源地址限制
+ bindaddress 内网地址
+ ratelimit

26.4 不要无条件 local stratum

“客户端永远能同步”不等于“时间永远正确”。

26.5 不要把两个来源当作多数共识

两个来源发生分歧时没有第三票,应监控服务器之间的偏差。

二十七、生产配置汇总

27.1 联网 NTP Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server ntp1.example.net iburst
server ntp2.example.net iburst
server ntp3.example.net iburst
server ntp4.example.net iburst

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
minsources 2
maxupdateskew 100.0

allow 192.168.9.0/24
bindaddress 192.168.9.10
ratelimit interval 1 burst 16
clientloglimit 1048576

ntsdumpdir /var/lib/chrony
logdir /var/log/chrony

27.2 普通 Client

1
2
3
4
5
6
7
8
9
10
server ntp01.example.com iburst
server ntp02.example.com iburst

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
maxupdateskew 100.0
port 0
ntsdumpdir /var/lib/chrony
logdir /var/log/chrony

27.3 高精度 LAN Client

1
2
3
4
5
6
7
8
9
10
11
server ntp01.example.com iburst minpoll 4 maxpoll 6 xleave
server ntp02.example.com iburst minpoll 4 maxpoll 6 xleave
server ntp03.example.com iburst minpoll 4 maxpoll 6 xleave
server ntp04.example.com iburst minpoll 4 maxpoll 6 xleave

minsources 2
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
hwtimestamp eth0
port 0

27.4 离线 Orphan Server

1
2
3
4
5
6
7
8
9
10
11
server 192.168.9.11 iburst
server 192.168.9.12 iburst
server 192.168.9.13 iburst

local stratum 10 orphan

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 192.168.9.0/24
ratelimit interval 1 burst 16

二十八、上线检查清单

Server

  • Chrony 已更新;
  • 配置至少四个独立上游来源;
  • sources -v 存在 ^*
  • Leap statusNormal
  • 联网环境未无条件启用 local stratum
  • allow 只放行内网;
  • firewalld 只允许可信网段 UDP 123;
  • 多网卡环境绑定正确地址;
  • Rate Limit 合理;
  • 服务器之间偏差已监控;
  • NTS 证书和私钥权限正确;
  • 日志和磁盘已监控。

Client

  • 只配置内部 NTP;
  • 不需要时禁用 DHCP 注入源;
  • chronyd 开机启动;
  • 存在 ^*
  • Reach 能达到 377
  • Leap statusNormal
  • 没有其他程序持续强制调时;
  • RTC 使用 UTC;
  • 快照恢复流程包含时间检查。

高可用

  • 不依赖单台 Server;
  • 不把两台 Server 当成完整多数判断;
  • 上游来源具备独立性;
  • 变更采用滚动方式;
  • 上游全部失效有告警;
  • 客户端偏差有阈值告警;
  • 离线模式与真实 UTC 的边界明确。

二十九、总结

在 Rocky Linux 10 上搭建 Chrony 时间基础设施,真正重要的不是执行:

1
dnf install chrony

而是建立一套可信的层级:

1
2
3
4
5
独立上游时间源
-> 内部 NTP Server
-> 内部客户端
-> 监控和告警
-> 离线与故障策略

核心原则:

  1. NTP 是协议,Chrony 同时提供客户端和服务器实现;
  2. 内部服务器使用至少四个独立上游来源;
  3. 客户端尽量只访问企业内部 NTP;
  4. iburst 用于初始加速,不是持续高频轮询;
  5. makestep 适合启动早期,不适合运行期间频繁强制跳时;
  6. 联网环境默认不要配置 local stratum
  7. 离线网络可使用 local ... orphan 保持内部一致;
  8. allow、firewalld 和监听地址共同限制访问;
  9. 虚拟机避免 Guest Tools 与 Chrony 同时持续调时;
  10. 有明确精度需求时再缩短 Poll、启用硬件时间戳和 xleave;
  11. 高安全环境可以使用 NTS;
  12. 判断同步不能只看服务 Active,必须检查 trackingsourcesLeap status

时间基础设施平时几乎没有存在感,但认证、数据库、集群和审计都默认它永远正确。把 NTP 配好,属于那种没人鼓掌,却能让未来少开很多故障会议的工作。

参考资料


Rocky Linux 10 搭建 NTP Server 与 Chrony Client:内网授时、离线容灾与生产调优
https://allendericdalexander.github.io/2026/07/31/devops/linux/rocky/rocky-linux-10-ntp-server-chrony-client/
作者
AtLuoFu
发布于
2026年7月31日
许可协议