Linux 时间同步:NTP 与 chrony
Linux 时间同步:NTP 与 chrony
目录
- 为什么需要时间同步
- Linux 的时间系统基础:系统时钟与硬件时钟
- NTP 协议原理:如何对时
- chrony 与 ntpd:为什么现代用 chrony
- 软件包安装
- chrony 服务端配置
- chrony 客户端配置
- 验证与排错:如何判断时间已同步
- 时区与硬件时钟:date、timedatectl、hwclock
- 常见坑与最佳实践
- 实战:搭建最小时间同步架构
- 总结与延伸
- 参考资料
为什么需要时间同步
在谈“怎么同步”之前,先明确“为什么要同步”。现代分布式系统、安全体系与日常运维都高度依赖所有机器时间一致。若一台机器时间偏差过大,会引发一系列看似无关、实则为“时间错乱”的故障。
时间不同步会导致的问题
| 场景 | 时间偏差引发的后果 |
|---|---|
| HTTPS / TLS 证书校验 | 证书有“生效期/失效期”,机器时间若超前或落后,浏览器/客户端会误判证书“未生效”或“已过期”,报 certificate has expired 或 not yet valid |
| 日志审计与排障 | 多机日志时间戳不一致,排障时无法按时间轴对齐,grep 到的事件无法对应;安全审计(合规)要求时钟可追溯 |
| Kerberos / AD 认证 | Kerberos 票据带时间戳,客户端与服务端时钟偏差超过容差(通常 5 分钟)即被拒绝,报 clock skew too great |
| 数据库事务与复制 | 主从复制、事务时间戳、慢查询定位依赖一致时钟;跨节点时间错乱会破坏顺序一致性 |
| cron / 定时任务 | 定时任务按本地时间触发,节点时钟不一致会导致任务触发时刻不一致 |
| NFS 文件时间戳 | 文件 mtime 由写它的客户端时钟决定;客户端时钟错乱会导致文件时间戳“穿越”,影响增量备份(如 rsync、tar 依赖 mtime)与构建系统(make 依赖源文件比目标文件新) |
| 分布式共识 / 消息排序 | 依赖时间戳排序的系统(如部分日志聚合、事件溯源)在时钟不一致时产生乱序 |
一句话:“时间”在单机上是常识,在多机上是基础设施。 一台机器对时不准,可能拖垮整条业务链。因此,运维的基线操作之一就是:所有服务器接入统一的时间源,并持续校准。
时间同步的两个层面
严格说,“时间同步”在 Linux 上包含两个层面:
- 系统时钟(system clock / wall clock):由内核维护,即
date显示的“当前时间”,是进程、日志、文件时间戳实际使用的时钟。 - 硬件时钟(hardware clock / RTC,Real-Time Clock):由主板电池供电的时钟,关机后仍能走时,开机时内核读取它初始化系统时钟。
时间同步工具(NTP/chrony)主要校准的是系统时钟;而硬件时钟与系统时钟之间如何互相回写,属于“时区与硬件时钟”管理(第 8 章详述)。此处先建立“系统时钟 + 硬件时钟”双时钟的认知,后面的原理都建立在系统时钟上。
一、Linux 的时间系统基础:系统时钟与硬件时钟
理解时间同步前,先弄清 Linux 里“时间”是怎么存放和读取的。
1.1 两个时钟:system clock 与 hardware clock
Linux 中有两个独立的“时钟”:
- 系统时钟(system clock):运行于内核中的软件时钟,以 自 1970-01-01 00:00:00 UTC 起经过的秒数(Unix 时间戳) 计数。
date、stat、日志时间戳、mtime等使用的都是它。 - 硬件时钟(hardware clock / RTC):主板上的独立时钟芯片,靠 CR2032 纽扣电池 供电,关机后继续走时。开机时由内核(或引导阶段)读取它来初始化系统时钟;关机时也可把系统时钟写回 RTC。
系统时钟是“软件维护的真身”,硬件时钟是“断电后的备份”。两者要分开看待:NTP/chrony 同步的是系统时钟;
hwclock命令负责系统时钟与硬件时钟之间的读写。
1.2 时区(timezone)与 UTC
系统时钟在内部一律按 UTC(协调世界时) 计数,所谓“时区”只是展示层:把同一个 UTC 时刻换算成不同地区的本地时间。因此:
- 同步的是 UTC 时刻,与显示时区无关;换时区不影响“时间对不对”,只影响“显示成几点”。
- 时间同步的本质是让所有机器的 UTC 时刻一致,而不是“让所有机器显示同一时刻”的时区概念。
1.3 查看与手动设置时间
先学会用 timedatectl 和 date 查看当前时间状态(timedatectl 是 systemd 提供的时间管理命令,RHEL/Rocky 9 默认自带):
# 查看时间、时区、NTP 同步状态
timedatectl
# 输出示例(关键字段)
# Local time: Fri 2025-06-13 14:32:05 CST
# Universal time: Fri 2025-06-13 06:32:05 UTC
# RTC time: Fri 2025-06-13 06:32:05
# Time zone: Asia/Shanghai (CST, +0800)
# System clock synchronized: yes <- 是否已与 NTP 同步
# NTP service: active <- NTP 服务是否开启
# RTC in local TZ: no <- 硬件时钟是否存本地时间(建议 no,存 UTC)
date # 查看当前系统时间(本地时区)
date -u # 查看 UTC 时间
date '+%Y-%m-%d %H:%M:%S' # 自定义格式
System clock synchronized: yes 与 NTP service: active 是判断“机器是否在正常对时”的直接窗口,第 7 章会结合 chronyc 细讲。
二、NTP 协议原理:如何对时
2.1 NTP 是什么
NTP(Network Time Protocol,网络时间协议) 是一种用于在网络上同步计算机时钟的应用层协议,基于 UDP,默认端口 123。它允许客户端从一台或多台“时间服务器”获取精确的 UTC 时间,并估算网络往返延迟与时钟偏移,从而校准本地系统时钟。
端口记忆:NTP 用 UDP 123。客户端与服务端都监听/使用该端口,防火墙需放行(呼应前面《防火墙》那篇)。
2.2 时间服务器层级:Stratum
NTP 采用分层(stratum)架构,层数表示“与最权威时间源的距离”:
| Stratum 层级 | 说明 |
|---|---|
| Stratum 0 | 原子钟、GPS 授时等权威硬件时间源,不直接对外服务,通过串口/专用接口给 stratum 1 服务器 |
| Stratum 1 | 直接连接 stratum 0 的高精度时间服务器(如 NIST、中国国家授时中心等),对公众提供 NTP 服务 |
| Stratum 2 | 从 stratum 1 同步的服务器,是大多数企业/机房服务器的上游 |
| Stratum 3+ | 逐级向下,层数越大精度越差、距离权威源越远 |
层数越低(数字越小)越接近权威源、精度越高。客户端会优先选择 stratum 层级更低、且网络延迟更优的服务器。一台 NTP 服务器自身的 stratum 由它“从谁同步”决定——如果它直接同步 stratum 1,那它就是 stratum 2。
2.3 校时机制:往返延迟与时钟偏移
NTP 并不简单“问一次就改一次”。它通过多次采样,用如下四个时间戳估算网络延迟与本地时钟偏移:
t0:客户端发送请求的时刻;t1:服务器收到请求的时刻;t2:服务器发出响应的时刻;t3:客户端收到响应的时刻。
于是:
网络往返延迟 = (t3 - t0) - (t2 - t1)
本地时钟偏移 = ((t1 - t0) + (t2 - t3)) / 2
客户端用偏移量来校正自己的系统时钟。由于每次都同步一次只估算一次延迟,NTP 客户端通常会多次采样并取中位数/加权,剔除网络抖动明显异常的样本,得到更稳的偏移估计。这就是 NTP 能比单纯“读一次服务器时间”精准得多的原因。
2.4 两种校时策略:跟随(slew)与步进(step)
校准系统时钟时,有两种截然不同的策略,影响面也完全不同:
- 步进(step,直接跳变):检测到偏差后直接把时钟调到目标值。速度快,但会让时间发生“瞬时跳跃”,可能导致依赖单调递增时间的程序(如日志时间戳回退、数据库 WAL、某些统计)出现异常。
- 跟随 / 微调(slew,频偏微调):不直接跳,而是微调时钟走速,让本地时钟逐渐追上目标。时间保持单调、平滑,但收敛慢,适用于偏差不大的情况。
chrony 的策略:偏差较大(默认阈值 1000 秒,即超过 16 分 40 秒)时采用 step,偏差较小时采用 slew。
chronyd还能在启动时按需 step。这个“大偏差 step、小偏差 slew”的取舍,既保证快速对齐,又避免频繁跳变伤及应用。
2.5 几个关键术语
- source(时间源):客户端同步的对象,可以是远程 NTP 服务器或本地硬件时钟。
- poll(轮询间隔):客户端每次请求 NTP 服务器的间隔(秒),chrony 会自动在
minpoll/maxpoll之间调整,同步越稳定间隔越长,以节省带宽。 - reachability(可达性):最近一段时间内对某服务器的成功请求占比,
chronyc sources中Reach列用八进制表示。 - offset(偏移):本地时钟与时间源之间的差距;
chronyc tracking直接显示当前偏移。
原理讲清楚后,进入工具层面:现代 Linux 用 chrony 而非经典 ntpd,原因见下章。
三、chrony 与 ntpd:为什么现代用 chrony
3.1 经典 NTP 守护进程:ntpd
历史上 Linux 用 ntpd(由 NTP 项目提供)作为 NTP 守护进程。它的主要特点:
- 客户端模式从上游服务器同步;也可配置为服务器给下游提供时间。
- 通过 adjtime 系统调用 做频偏微调(slew),长期保持精度。
- 会周期性写入 driftfile(频率漂移文件)记录时钟频率误差,重启后继续补偿。
ntpd 工作良好,但在现代场景下面临几个短板(见 3.3)。
3.2 chrony:现代替代实现
chrony 是 Richard Curnow 等开发的现代化 NTP 实现,由 chronyd(守护进程) 与 chronyc(命令行控制/监控客户端) 两部分组成。它是 RHEL/CentOS/Rocky 7 及以后、Fedora、Ubuntu(18.04+ 默认)、SUSE、Debian 等主流发行版的默认 NTP 实现。
chronyd 在后台持续运行:既作为客户端从时间源同步,也可作为服务器给局域网其他机器授时。chronyc 则用于交互式查询状态、手动触发同步、添加/删除时间源等运维操作。
3.3 为什么要用 chrony 取代 ntpd
chrony 相对 ntpd 的核心优势(也是 Red Hat / 各发行版默认切换的理由):
| 维度 | chrony | ntpd 的短板 |
|---|---|---|
| 对不稳定网络的适应性 | 轮询间隔可在 0.5 秒到几分钟间动态调整,网络抖动时仍能快速收敛、保持高精度 | 轮询间隔调整粗、固定,对高抖动网络收敛慢 |
| 同步速度 | 启动后几秒内即可完成首次同步(配合 iburst 更明显) |
冷启动后往往需要较长“爬坡”时间 |
| 间歇性联网 / 虚拟机 | 特别优化了频繁休眠、挂起恢复、虚拟机时钟漂移场景;rtcsync 定期把系统时钟写回 RTC |
对休眠/挂起/虚拟机时钟处理较弱 |
| 时钟大步进 | 可配置在启动时或偏差超阈值时 step,收敛快且安全 | 大步进行为配置复杂 |
| 参考时钟(refclock) | 支持从本地 GPS/PPS 等硬件源授时 | 支持但配置较繁琐 |
| 资源占用与维护 | 代码轻量、单进程、维护活跃 | 相对更重,项目维护节奏较慢 |
一句话:chrony 更快、更稳、更适应现代(虚拟机/容器/不稳定网络)环境,因此成为各家发行版默认。对绝大多数运维场景,直接用 chrony 即可。
软件包安装
chrony 是独立的系统服务包,Minimal 安装的 Rocky/RHEL 可能未预装。使用前先确认并安装。
4.1 相关软件包
| 包 | 提供 | 说明 |
|---|---|---|
chrony |
chronyd 守护进程、chronyc 客户端 |
主包,装它即可(RHEL/Rocky 配置文件为 /etc/chrony.conf,Debian/Ubuntu 为 /etc/chrony/chrony.conf) |
systemd-timesyncd |
systemd-timesyncd 服务(可选) |
systemd 内置的轻量 NTP 客户端;装了 chrony 后建议二选一,避免冲突 |
经典 ntpd 由
ntp包提供,若系统装的是它,可先卸载再装 chrony,避免两个 NTP 守护进程抢 123 端口:RHEL/Rocky 用sudo dnf remove ntp,Debian/Ubuntu 用sudo apt remove ntp。
4.2 检查是否已安装
rpm -q chrony # 查看 chrony 包是否安装
which chronyd chronyc # 查看命令是否存在
systemctl status chronyd # 查看服务是否在运行
4.3 安装与启动
# ---- RHEL / Rocky / CentOS ----
sudo dnf install -y chrony
# ---- Debian / Ubuntu ----
sudo apt update && sudo apt install -y chrony
# 启动并设置开机自启(两系服务名不同)
sudo systemctl enable --now chronyd # RHEL/Rocky
sudo systemctl enable --now chrony # Debian/Ubuntu
# 确认状态
systemctl status chronyd # RHEL/Rocky
systemctl status chrony # Debian/Ubuntu
安装并启动后,chronyd 会读取配置文件开始工作(RHEL/Rocky 为 /etc/chrony.conf,Debian/Ubuntu 为 /etc/chrony/chrony.conf)。第 5、6 章分别讲怎么把它配成服务端与客户端。
RHEL 系与 Debian/Ubuntu 系差异汇总:
项目 RHEL / Rocky / CentOS Debian / Ubuntu 包管理器/安装 dnf install chronyapt install chrony配置文件 /etc/chrony.conf/etc/chrony/chrony.confsystemd 服务名 chronydchronydriftfile/logdir /var/lib/chrony/drift、/var/log/chrony与 RHEL 相同(由包默认配置) 卸载 ntpd dnf remove ntpapt remove ntp配置指令本身(
pool/server/allow/local stratum/makestep/rtcsync)两系完全一致,仅文件路径与服务名不同。下文示例以 RHEL/Rocky 为主,Debian/Ubuntu 只需把配置写入/etc/chrony/chrony.conf并把服务操作中的chronyd换成chrony。
4.4 配置文件与默认参数详解
装好 chrony 后,真正决定“它怎么工作”的是配置文件。很多新手只记得“配置在 /etc 下面”,却搞不清 RHEL 与 Debian/Ubuntu 的路径差异、目录里每个文件是干什么的,以及自带默认配置里那些参数是什么意思。这一节把三件事讲透:路径、目录结构、默认参数。
4.4.1 配置路径为什么不同:单文件 vs 目录
chrony 的配置核心指令完全相同,只是不同发行版把它放在不同位置:
| 发行版 | 主配置文件 | 说明 |
|---|---|---|
| RHEL / Rocky / CentOS / Fedora | /etc/chrony.conf |
单文件,直接放在 /etc/ 下 |
| Debian / Ubuntu | /etc/chrony/chrony.conf |
放在 /etc/chrony/ 目录内的主文件 |
两者都叫 chrony.conf,但一个在 /etc/ 根下、一个在 /etc/chrony/ 子目录里。这纯粹是发行版打包习惯不同:RHEL 系坚持“一个服务一个顶层配置文件”,Debian 系则习惯“一个服务一个配置目录”,把主配置和相关密钥、片段都收进目录里。
记忆点:RHEL =
/etc/chrony.conf;Debian/Ubuntu =/etc/chrony/chrony.conf。改配置前先用rpm -q chrony/dpkg -l chrony或直接ls /etc/chrony*确认你手上的是哪种。
4.4.2 /etc/chrony/ 目录里都有什么
在 Debian/Ubuntu(以及较新的 RHEL 系)上,配置不止一个文件。常见的组成:
| 路径 / 文件 | 作用 |
|---|---|
/etc/chrony.conf(RHEL)或 /etc/chrony/chrony.conf(Debian/Ubuntu) |
主配置文件:时间源、同步策略、权限等核心指令都在这里 |
/etc/chrony/conf.d/*.conf(Debian/Ubuntu) |
drop-in 片段目录:把附加配置拆成小文件放这里,主配置会 include 进来,便于按场景分层管理 |
/etc/chrony/sources.d/*.sources(新版本) |
时间源片段目录:每个片段文件单独定义一组 pool/server,用 confdir/sourcedir 引入,适合“按来源拆分” |
/etc/chrony.keys(RHEL)或 /etc/chrony/chrony.keys(Debian/Ubuntu) |
NTP 认证密钥文件:启用 key 认证(防伪造时间源)时存放密钥,日常用不到可不管 |
/var/lib/chrony/drift |
driftfile(频率漂移文件):chronyd 把测量到的“本机晶振频率偏差”写入这里,重启后读取并继续补偿,保证精度不因重启而丢失 |
/var/log/chrony |
logdir(日志目录):配合 log 指令存放 chronyd 的测量/统计日志 |
核心理解:主配置管“同步谁、怎么同步”;driftfile 管“记住频率偏差”;logdir 管“日志落盘”;keys/conf.d 是可选的高级拆分。日常运维最常改的就是主配置与 driftfile 两处。
4.4.3 默认配置长什么样 + 每行什么意思
下面用 RHEL/Rocky 9 自带的默认 /etc/chrony.conf 为例(较新版本的真实默认内容,配置会随发行版/小版本略有出入,以你机器上的实际为准)。生效(未注释)的指令其实就几行,其余是默认注释掉的模板:
# 上游时间源:从 Rocky 公共 NTP 池同步,iburst 加速首次同步
pool 2.rocky.pool.ntp.org iburst
# 使用 DHCP 下发的 NTP 服务器(若网卡走 DHCP 且服务器下发了 NTP 地址)
sourcedir /run/chrony-dhcp
# 频率漂移文件:记录本机时钟频率偏差,重启后继续补偿(保持精度)
driftfile /var/lib/chrony/drift
# 偏差超过 1 秒且仅在前 3 次更新内时允许 step(跳变),之后一律 slew(平滑微调)
makestep 1.0 3
# 定期把系统时钟写回硬件时钟(RTC),关机后仍保持大致准确
rtcsync
# 存放 NTS(加密认证时间同步)密钥与 cookie 的目录
ntsdumpdir /var/lib/chrony
# 日志目录(默认未启用日志,需配合 log 指令)
logdir /var/log/chrony
# ---- 以下为默认注释掉的可选指令(取消注释即启用)----
#hwtimestamp * # 硬件时间戳(需网卡支持 PTP/硬件时间戳)
#minsources 2 # 至少需要几个可选源才允许调整时钟
#allow 192.168.0.0/16 # 允许哪些网段查询本机时间(授时用,见第 5 章)
#local stratum 10 # 无上游时用本地时钟授时的兜底(见 5.4)
#authselectmode require # 所有时间源都要求认证(NTS 或 key)
#keyfile /etc/chrony.keys # NTP 认证密钥文件
#leapsecmode slew # 用 slew 方式插入/删除闰秒
#leapseclist /usr/share/zoneinfo/leap-seconds.list # 从 tz 库读取闰秒表
#log measurements statistics tracking # 记录哪些日志
要点:RHEL 默认真正生效的是
pool、sourcedir /run/chrony-dhcp、driftfile、makestep 1.0 3、rtcsync、ntsdumpdir、logdir等行;#开头的都是模板,按需取消注释即可(#allow、#local stratum在第 5 章服务端用到)。改配置时把需要的行取消注释或修改即可。
Ubuntu 新版(22.04 之后)的默认 /etc/chrony/chrony.conf 更“模块化”:NTP 池已从主配置移走,改放到 sources.d/ 片段文件里,主配置只管引入目录、认证、日志与同步策略。下面是较新 Ubuntu 的真实默认配置全文:
# 使用 DHCP 下发的 NTP 服务器(走 DHCP 且服务器下发了 NTP 地址才会用到)
sourcedir /run/chrony-dhcp
# 引入 /etc/chrony/sources.d 下的时间源片段(Ubuntu 的 NTP 池就在这里)
sourcedir /etc/chrony/sources.d
# NTP 认证密钥文件(默认未启用认证)
keyfile /etc/chrony/chrony.keys
# 频率漂移文件:记录时钟频率偏差,重启后继续补偿
driftfile /var/lib/chrony/chrony.drift
# 存放 NTS(加密认证时间同步)密钥与 cookie 的目录
ntsdumpdir /var/lib/chrony
# 日志目录(默认未启用日志,需配合 log 指令)
logdir /var/log/chrony
# 拒绝偏差超 100 ppm 的异常样本,避免坏源带偏时钟
maxupdateskew 100.0
# 定期把系统时钟写回硬件时钟(RTC)
rtcsync
# 偏差超过 1 秒且仅在前 3 次更新内时 step(跳变),之后一律 slew(平滑微调)
makestep 1 3
# 从系统 tz 数据库读取闰秒 / TAI-UTC 偏移(用闰秒抹平源时需注释掉)
leapseclist /usr/share/zoneinfo/leap-seconds.list
# 引入 /etc/chrony/conf.d 下的附加配置片段
confdir /etc/chrony/conf.d
# ---- 以下为默认注释掉的可选指令(取消注释即启用)----
#log tracking measurements statistics # 开启日志记录(默认未开启)
说明:上面是 Ubuntu 默认配置里**实际生效(未注释)**的指令。Ubuntu 的默认配置大多已生效,注释掉的模板较少(如日志默认未开启)。
几点与旧版的差异和说明:
- 上游池移到了
sources.d/:注释第一行说明pool已迁到/etc/chrony/sources.d/ubuntu-ntp-pools.sources,主配置不再直接写pool。所以改上游时既改主配置、也可能要改sources.d/里的片段文件(详见 4.4.2)。 - 两个
sourcedir:/run/chrony-dhcp(DHCP 下发的源)与/etc/chrony/sources.d(NTP 池片段)。要“只用指定源”,这两行都需要处理(见 6.4.3)。 keyfile /etc/chrony/chrony.keys:NTP 认证密钥文件(默认未启用认证)。ntsdumpdir /var/lib/chrony:存放 NTS(Network Time Security,加密认证的时间同步扩展)密钥与 cookie 的目录。maxupdateskew 100.0:拒绝偏差超 100 ppm 的异常样本,避免坏源带偏时钟。leapseclist:从系统 tz 数据库读取 TAI-UTC 偏移与闰秒表;若用的是“闰秒抹平(leap-smear)”时间源需注释掉。makestep 1 3与rtcsync:与 RHEL 含义相同(见上表)。
改配置最小化:RHEL 直接改
/etc/chrony.conf的上游行即可;Ubuntu 除了主配置,还要留意sources.d/片段与sourcedir引入。本章表格与示例用于讲清每条指令的作用。
各关键指令的含义(两系通用):
| 指令 | 作用 |
|---|---|
pool / server |
指定同步的上游:pool 是一组服务器(域名下多 IP),server 是单台明确服务器 |
iburst |
启动时连发 4 个快速请求,几秒内完成首次同步,强烈建议加 |
driftfile 路径 |
频率漂移文件路径,chronyd 据此“记住”时钟走速偏差,重启不丢精度 |
makestep 阈值 次数 |
偏差超“阈值”秒且“在前 N 次更新内”时允许 step(跳变),否则 slew(平滑微调) |
rtcsync |
定期把系统时钟写回 RTC,缓解断电重启后时间回跳 |
logdir 路径 |
日志目录;配合 log measurements statistics tracking 决定记录哪些日志 |
keyfile 路径 |
NTP 认证密钥文件(默认注释,未启用认证可不设) |
maxupdateskew 100.0 |
允许的最大时钟更新偏差(ppm),超过则认为源异常,避免一次坏样本带偏 |
allow 网段 |
允许哪些网段的客户端查询本机时间(服务端授时用,见第 5 章) |
local stratum N |
无上游时用本地时钟对外授时的兜底声明(见 5.4) |
改动最小化的建议:日常只需在默认配置基础上**替换/追加上游行(
pool/server)**即可,其余参数一般保持发行版默认就好。第 5、6 章就是在默认配置之上改上游和allow。
4.4.4 国内时间服务器(中国网络环境建议)
默认配置里的 2.rocky.pool.ntp.org、ntp.ubuntu.com 都是国外时间源。在国内网络(尤其无国际出口优化的机房、内网)直连它们往往延迟高、偶发丢包、首次同步慢,甚至 Reach 长期不稳。若你的服务器在中国大陆网络环境,建议改用国内时间服务器。
常用国内 NTP 服务器:
| 提供方 | 服务器地址 | 说明 |
|---|---|---|
| 阿里云 | ntp.aliyun.com |
主地址,还有 ntp1/ntp2/ntp3.aliyun.com 可作冗余 |
| 腾讯云 | ntp.tencent.com |
腾讯云公共 NTP |
| 国内 NTP 池 | cn.pool.ntp.org |
面向国内用户的 NTP 池,自动选择就近节点 |
| 国家授时中心 NTSC | ntp.ntsc.ac.cn |
中国科学院国家授时中心,权威源,精度高 |
为什么推荐国内源:延迟更低、丢包更少、首次同步更快;且在国内合规环境下可访问性/稳定性更好。阿里云
ntp.aliyun.com、国家授时中心ntp.ntsc.ac.cn是最常用也最稳的两个,建议至少配置其中两个做冗余。
国内源替代块(可直接把下面内容替换掉主配置里的上游行;其余行保持默认即可):
# 国内时间服务器(替换原 pool 行即可;多配几个做冗余)
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp.tencent.com iburst
server cn.pool.ntp.org iburst
server ntp.ntsc.ac.cn iburst
这里用
server是因为国内源都是明确的单台/单域名,逐个列出便于看到每个源的状态;也可按需删减为 2~3 个。配置后用第 7 章的方法(chronyc sources -v看^*)验证是否连上国内源。
五、chrony 服务端配置
所谓“服务端”,是指这台机器作为时间提供者,向局域网内其他客户端提供时间。企业常用做法:内网一台服务器从公共 NTP 服务器(或上级时间服务器)同步,同时开放给内网客户端,让内网机器都指向它,避免每台机器都直连外网。
5.1 服务端角色拆解
一台 chrony“服务端”同时干两件事:
- 作为客户端:从上游时间源同步(
pool/server指令,见 5.2)——先保证自己时间是对的,才有资格给别人授时。 - 作为服务器:响应内网客户端的 NTP 查询(
allow指令 + 防火墙放行,见 5.3)。
5.2 配置上游时间源:pool 与 server
/etc/chrony.conf 中用 server 或 pool 指定同步对象。二者区别:
server:指定一台具体的时间服务器,可精确控制轮询参数。pool:指定一组服务器(一个域名背后多个 IP,如pool.ntp.org),chrony 自动从中选择并维护多台连接,兼顾冗余与负载均衡。
Rocky 默认配置示例(/etc/chrony.conf 头部):
# 使用公共 NTP 服务器池(可改成内网上级时间服务器)
pool 2.rocky.pool.ntp.org iburst
国内网络环境建议换成国内时间服务器(阿里云、腾讯云、国家授时中心等),具体地址与可直接复制的国内源替代块见 4.4.4 国内时间服务器。
关键选项说明:
iburst:启动时连续发送 4 个快速请求,几秒内完成首次同步,强烈建议加上。minpoll N/maxpoll N:轮询间隔的下限/上限(2^N秒)。默认minpoll 3(8 秒)/maxpoll 6(64 秒),chrony 会自动调整。对公共服务器建议保留默认,避免过于频繁被限流。burst:每轮询周期内额外多发几个请求,用于快速提升精度。
若内网有更优的上级时间服务器,可优先指向它并指定 iburst:
server 192.168.1.10 iburst # 指向内网上级时间服务器
pool 2.rocky.pool.ntp.org iburst # 可再保留公共池作备份
5.3 开放给客户端:allow 指令
chronyd 默认只同步、不对外授时。要让内网客户端能查询它,需在配置中添加 allow(允许的客户端网段)与 deny(拒绝)指令:
# 允许整个内网网段访问本机时间服务
allow 192.168.1.0/24
# 也可以只允许单台
# allow 192.168.1.50
# 允许所有(慎用,只建议在隔离内网)
# allow all
# 默认 deny 不需要写,chronyd 默认拒绝未在 allow 中的主机
5.4 无上游时:本地时钟作为兜底(local stratum)
如果这台服务器完全无法访问任何外网时间源(隔离内网、无外网),可以让 chronyd 对外宣称自己的时间“可信”,从而作为内网的权威源:
# 让本机在无法同步到任何上游时,仍以本地时钟对外授时
local stratum 10
# 即便本机不同步任何上游,也按“有 10 个同步源”的逻辑继续服务
# local stratum 10 还附带一个效果:允许本机在离线上游时对外提供时间
local stratum 10的效果:当本机长时间无法同步到任何上游时,仍允许 chronyd 用本地时钟对外服务,并把自己声明为 stratum 10。这样内网客户端至少有一个“相对一致”的时间来源,避免完全失同步。若本机能正常访问上游,则无需(也不应)配置此行——正常同步时本机自动成为正确的更高层服务器。
5.5 完整服务端配置示例
一个典型的内网 chrony 服务端 /etc/chrony.conf:
# 上游:内网上级,并保留公共池作备份
server 10.0.0.2 iburst
pool 2.rocky.pool.ntp.org iburst
# 向内网客户端授时
allow 192.168.1.0/24
# 若完全无外网,取消下面这行注释作为兜底
# local stratum 10
# 让漂移文件与日志目录可写
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
# 定期把系统时钟写回硬件时钟(RTC),关机后仍能保持大致准确
rtcsync
5.6 防火墙放行 UDP 123
NTP 用 UDP 123。服务端放行该端口,客户端才能连上(客户端通常无需额外放行入站):
# ---- firewalld(Rocky/RHEL 默认)----
sudo firewall-cmd --permanent --add-service=ntp
sudo firewall-cmd --reload
sudo firewall-cmd --list-services
# ---- ufw(Debian/Ubuntu 默认)----
sudo ufw allow 123/udp
sudo ufw status
ntp是 firewalld 预定义服务别名,对应 UDP 123;配置完记得--reload。Debian/Ubuntu 默认用 ufw,直接用sudo ufw allow 123/udp放行。
六、chrony 客户端配置
客户端是绝大多数机器的角色:只从服务器同步,不对外授时。配置极简。
6.1 指向时间服务器
在 /etc/chrony.conf 中把上游指向内网 chrony 服务端(或公共 NTP 服务器)即可:
# 指向内网 chrony 服务端
server 192.168.1.10 iburst
# 多台上游做冗余,chrony 会自动选举最佳源
server 192.168.1.11 iburst
# 或者用公共池
# pool 2.rocky.pool.ntp.org iburst
6.2 多服务器冗余与选举
chrony 会同时维护多个时间源,并动态选举最优的一个作为主同步源:
- 客户端同时与所有配置的
server/pool通信,采样各源的时钟偏移。 - 采用类似 NTP 的筛选算法,剔除异常(偏离多数)的源,从剩余的“幸存者”中结合 stratum 层级、抖动(jitter)、往返延迟 综合选出最佳源。
- 主源掉线时自动切换/重新选举到其他源,保证连续性。
配置多台上游(或一个 pool)就是实现冗余与高可用的最简单方式。
6.3 客户端完整配置示例
一个典型客户端 /etc/chrony.conf:
# 上游:内网两台服务端做冗余
server 192.168.1.10 iburst
server 192.168.1.11 iburst
# 客户端不对外授时,无需 allow
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
rtcsync
6.4 让客户端只用指定的服务器
有时你希望客户端只从自己指定的时间源同步,绝不连别的(比如公司内网有统一 chrony 服务器、或安全/合规要求只信任特定授时源)。这并不需要特殊指令——chrony 只会连接配置里写了的上游,所以关键在两点:只配置你要的地址,以及清掉系统自带的默认上游。
6.4.1 只配置你要的 server
以“客户端只从内网 192.168.1.10 同步”为例:
# /etc/chrony.conf (客户端)——只写这一台,不写 pool、不写其他 server
server 192.168.1.10 iburst
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
rtcsync
只配一台是单点。生产上“只用指定服务器”通常不是只配一台,而是配置 2~3 台你自己指定的服务器(如自己的两台内网主备)做冗余,避免单点失同步。配置几个
server就只会连几个,你指定的集合之外它一概不碰。
6.4.2 清掉系统默认上游
有些发行版默认配置自带公共池(如 pool 2.rocky.pool.ntp.org、pool ntp.ubuntu.com)或 drop-in 片段目录。要“只用自己指定的”,必须删掉/注释掉这些默认行,最省事的是直接重写整个配置文件(RHEL 为 /etc/chrony.conf;Debian/Ubuntu 为 /etc/chrony/chrony.conf,并把 /etc/chrony/conf.d/、/etc/chrony/sources.d/ 里多余的默认片段一并清理)。
6.4.3 关掉 DHCP 注入(容易被忽略)
Ubuntu 默认配置里有 sourcedir /run/chrony-dhcp:若网卡走 DHCP 且 DHCP 服务器下发了 NTP 地址,chrony 会额外采用它们——导致“你以为只用自己的,实际混进了别的源”。要严格只用指定源,就注释掉这一行(见 4.4.3 的 Ubuntu 默认配置)。
6.4.4 防火墙强制兜底(推荐)
配置文件只能管“chrony 主动连谁”,管不了“它万一连别的”。要从网络层强制只能用指定源,就在防火墙上只放行到那台服务器的出站 UDP 123:
# firewalld(Rocky/RHEL)——只允许出站到 192.168.1.10 的 UDP 123
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p udp --dport 123 -d 192.168.1.10 -j ACCEPT
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p udp --dport 123 -j DROP
sudo firewall-cmd --reload
这样即使配置文件写错、被误改了上游,客户端也连不上指定的服务器之外——配置 + 防火墙双重兜底,比单靠配置文件更可靠。
6.4.5 验证确实“只用指定源”
sudo systemctl restart chronyd # 重启生效
chronyc sources -v # 应只列出你指定的地址
chronyc tracking # Reference ID 应是指定的那台
chronyc sources -v输出应只有你配置的地址,且第一行以^*(正在同步)开头;若出现公共池等未配置的源,说明有默认上游或 DHCP 注入没清干净。- 结合 6.4.4 的防火墙规则,即使配置被误改,也连不上别的源。
6.5 配置生效与启停
改完配置需要重启 chronyd 使其生效:
sudo systemctl restart chronyd
systemctl status chronyd # 确认正常
也可用
chronyc reload sources让 chronyd 在不重启的情况下重新加载时间源配置,适合线上热更新(第 7 章介绍 chronyc 时提)。
至此,服务端与客户端的标准配置都已给出。但“配完不一定对”——下一章讲如何验证同步确实生效,以及常见排错。
改完配置需要重启 chronyd 使其生效:
sudo systemctl restart chronyd
systemctl status chronyd # 确认正常
也可用
chronyc reload sources让 chronyd 在不重启的情况下重新加载时间源配置,适合线上热更新(第 7 章介绍 chronyc 时提)。
至此,服务端与客户端的标准配置都已给出。但“配完不一定对”——下一章讲如何验证同步确实生效,以及常见排错。
七、验证与排错:如何判断时间已同步
配置完成后,最要紧的是确认同步确实生效。chrony 提供 chronyc 命令与 timedatectl 双重验证入口。
7.1 chronyc sources:查看时间源
chronyc sources 列出所有配置的时间源及其状态(-v 显示列头解释):
chronyc sources -v
输出示例及列含义:
.-- Source mode '^' = server, '=' = peer, '#' = local clock
/ .-- Source state '*' = current synced, '+' = combined, '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = too variable
|| .- xxxx [ yyyy ] +/- zzzz
|| / .- xxxx = elapsed time
|| | / .- yyyy = interval since last sample
|| | | / .- zzzz = interval until next sample
|| | | |
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 192.168.1.10 2 6 377 21 -124us[ -124us] +/- 7ms
^+ 192.168.1.11 3 6 377 21 -115us[-3788us] +/- 8ms
判读要点:
^(server) 表示这是服务器类型源;*开头表示当前正使用的同步源(最关键,出现^*即表示已选中并同步)。+表示该源可用、作为备选参与综合;-表示可用但暂未参与综合;?表示不可达。- Stratum 列:上游服务器的层级,越低越好。
- Reach 列:八进制表示的“最近 8 次请求成功率”,
377表示 8/8 全成功(0b11111111);若长期为 0 则说明连不上该源。 - Last sample:最近一次采样的偏差与误差范围,单位通常
us(微秒)或ms(毫秒)。
7.2 chronyc tracking:查看同步详情
chronyc tracking 显示 chronyd 当前正在跟随的时钟的详细信息:
chronyc tracking
输出示例及关键字段:
Reference ID : C0A8010A (192.168.1.10) # 当前跟随的源
Stratum : 2 # 本机当前的 stratum
Ref time (UTC) : Fri Jun 13 06:12:05 2025
System time : 0.000000123 seconds slow of NTP time # 当前系统时间偏差
Last offset : -0.000000512 seconds # 上一次校正的偏移
RMS offset : 0.000000234 seconds # 偏移的均方根(长期稳定性)
Frequency : 9.123 ppm slow # 本机时钟频率偏差(ppm)
Leap status : Normal
判读要点:
- Stratum:本机当前所处层级(服务端从 stratum 2 上游同步,本机即 stratum 3)。
- System time / Last offset:系统时间与 NTP 时间的偏差,接近 0(秒级/毫秒级)说明同步良好。
- Frequency:本机晶振频率偏差(ppm),长期稳定说明校准到位。
- Leap status:
Normal表示正常;Insert leap/Delete leap表示闰秒处理中(极少见)。
7.3 timedatectl 确认同步
timedatectl 是另一道直观确认:
timedatectl
当以下两行出现时,说明系统正在被 chrony 正常同步:
System clock synchronized: yes
NTP service: active
注意:
NTP service: active表示有 NTP 服务在运行(此处即 chronyd);System clock synchronized: yes表示确实已同步成功。若前者 active 而后者 no,通常意味着还没连上时间源(见排错)。
7.4 常见排错
现象 1:chronyc sources 全部 ?(不可达),System clock synchronized: no
排查步骤:
# 1. 测试 UDP 123 是否可达上游(需装有 nc/nmap)
nc -vzu 192.168.1.10 123
# 2. 检查防火墙是否放行 UDP 123(客户端出站通常无需,服务端入站需放行)
sudo firewall-cmd --list-services
# 3. 确认上游 DNS 可解析、网络通
ping -c3 192.168.1.10
# 4. 查看 chronyd 日志
journalctl -u chronyd --since '10 minutes ago'
若日志出现 Source ... unreachable,多为网络/防火墙/DNS 问题。
现象 2:chronyc sources 有源但 Reach 为 0 或很低
说明近期请求大多失败(网络抖动、被上游限流、minpoll 太小)。通常等待几个轮询周期即可恢复;若持续,可调大 minpoll 或更换上游。
现象 3:时间偏差巨大(分钟级/小时级),chronyd 一直不对齐
检查 makestep 配置。chronyd 默认只在启动时允许大步进(step);运行中若偏差未超阈值,会采用 slew 缓慢追赶。若偏差非常大且希望立即对齐,可手动触发 step:
sudo chronyc makestep # 立即把系统时间步进到 NTP 时间
也可在配置中允许运行中大步进(慎用,会影响应用):
# 偏差超过 1000 秒时 step,且前 10 次更新后仍允许 step
makestep 1000 10
现象 4:System clock synchronized: no 但 chronyc sources 正常
可能 chronyd 已正常但 systemd 未识别,或另一个 NTP 客户端(如 systemd-timesyncd)在竞争。确认只有一个 NTP 守护进程在跑,必要时禁用 timesyncd:
sudo systemctl disable --now systemd-timesyncd
7.5 手动同步与即时操作
# 立即进行一次大步进(把系统时间直接调到 NTP 时间)
sudo chronyc makestep
# 查看所有时间源(不输出版本列头)
chronyc sources
# 查看 chronyd 可用的交互命令帮助
chronyc help
八、时区与硬件时钟:date、timedatectl、hwclock
时间同步解决“UTC 对不对”,而时区解决“显示成几点”,硬件时钟解决“关机后还记不记得时间”。三者要一起管理。
8.1 设置时区
# 查看当前时区
timedatectl
# 列出所有可用时区
timedatectl list-timezones
# 设置时区(示例:中国标准时间)
sudo timedatectl set-timezone Asia/Shanghai
# 或者手动方式
sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
Asia/Shanghai 是中国大陆标准时区(UTC+8,无夏令时)。容器/云主机常用 timedatectl set-timezone,某些最小化镜像需先 tzdata 包。
8.2 手动设置时间
手动设时间会断开自动同步,仅作临时/特殊用途:
# 关闭自动同步后才能手动设
sudo timedatectl set-ntp false
sudo timedatectl set-time '2025-06-13 14:00:00'
# 重新开启自动同步
sudo timedatectl set-ntp true
set-ntp true会启用系统配置的 NTP 同步服务。在装了 chrony 的 Rocky 上,它会确保 chronyd 处于启用状态。日常应保持set-ntp true,不要手动乱改。
8.3 硬件时钟(RTC)与 hwclock
硬件时钟由 hwclock 命令读写:
# 查看硬件时钟
hwclock
# 把系统时钟写回硬件时钟
sudo hwclock --systohc
# 把硬件时钟读到系统时钟
sudo hwclock --hctosys
关键决策:RTC 存 UTC 还是本地时间?
- 建议存 UTC(
timedatectl中RTC in local TZ: no):系统启动时按“RTC 即 UTC”初始化系统时钟,再换算时区。这样切时区只影响显示,不影响底层时间,多系统共存也一致。 - 若曾设为本地时间(
RTC in local TZ: yes),可能与 DST 夏令时冲突,一般不建议。
设置 RTC 存 UTC:
sudo timedatectl set-local-rtc false # false = RTC 存 UTC(推荐)
chrony 的
rtcsync指令会让 chronyd 定期把系统时钟写回 RTC,使关机后硬件时钟也保持大致准确。
九、常见坑与最佳实践
9.1 常见坑
坑 1:忘了放行防火墙 UDP 123
服务端配了 allow 但客户端连不上——多半是服务端 firewalld 没放行 ntp 服务。放行后要 --reload。
坑 2:多个 NTP 守护进程抢端口
chronyd 与 ntpd(或 systemd-timesyncd)同时运行会争用 UDP 123,导致互相干扰、同步不稳定。同一台机器只保留一个 NTP 客户端/服务。
坑 3:把所有客户端都直连公共 NTP 服务器
每台都直连外网 NTP:一是大量公网请求可能被限流,二是无法统一管理、故障难排查。更优做法是内网一台或多台 chrony 服务端连外网,客户端指向内网服务端。
坑 4:server 与 pool 用错
pool 用于“一组服务器”(域名下多个 IP),server 用于“单台明确服务器”。把内网单台服务器写成 pool 或把公共池写成 server 都会有问题,按需选择。
坑 5:改了配置没重启/没热加载
改 /etc/chrony.conf 后未 systemctl restart chronyd 或 chronyc reload sources,新配置不生效。
坑 6:忽视 rtcsync 导致重启后时间跳回
若不定期把系统时钟写回 RTC,断电重启后系统时钟可能回到旧值,直到再次同步。开启 rtcsync 可缓解。
坑 7:在无外网的隔离内网里没有本地兜底源
隔离内网所有机器都指向一台“自己也无法同步”的服务端,结果全线不同步。此时应给该服务端配 local stratum 作为兜底。
9.2 最佳实践清单
- 统一架构:内网一台(或两台做冗余)chrony 服务端连外网,其余客户端指向内网服务端;客户端不对外授时。
- 上游加
iburst:加速首次同步,几乎零成本。 - 多源冗余:配置 2 台以上上游或使用
pool,chrony 自动选举,单点故障不影响。 - 防火墙精细化:只对需要的网段放行
ntp,客户端尽量只出站不开放入站 123。 - 只保留一个 NTP 实现:chrony 优先,卸载/停用 ntpd 与 systemd-timesyncd。
- 开启
rtcsync:保持 RTC 大致准确,降低重启后的同步压力。 - 常态用
timedatectl/chronyc巡检:把System clock synchronized: yes与chronyc sources的^*纳入监控/巡检脚本。 - 改配置要热更新或重启:线上优先
chronyc reload sources减少中断。
十、实战:搭建最小时间同步架构
把前面所有知识点串起来,完成一个“内网时间同步”的最小闭环:一台服务端连外网并给内网授时,一台客户端从服务端同步。
10.1 拓扑
公共 NTP 服务器 (pool.ntp.org / 2.rocky.pool.ntp.org)
| UDP 123
v
内网 chrony 服务端 192.168.1.10 (stratum 2/3,连外网 + 对内网授时)
| UDP 123
+--------+
| |
内网客户端 A 内网客户端 B
192.168.1.20 192.168.1.30 (都指向 192.168.1.10)
本节命令以 RHEL/Rocky 为准。Debian/Ubuntu 的差异已在第 4 章说明,此处只需做三处替换:
dnf install chrony→apt install chrony、配置文件/etc/chrony.conf→/etc/chrony/chrony.conf、服务操作中的chronyd→chrony;防火墙由firewall-cmd换成ufw allow 123/udp。
10.2 服务端(192.168.1.10)配置
# 1. 安装
sudo dnf install -y chrony
# 2. 配置 /etc/chrony.conf(核心行)
sudo tee /etc/chrony.conf >/dev/null <<'EOF'
server 10.0.0.2 iburst
pool 2.rocky.pool.ntp.org iburst
allow 192.168.1.0/24
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
rtcsync
EOF
# 3. 启动
sudo systemctl enable --now chronyd
# 4. 防火墙放行 UDP 123
sudo firewall-cmd --permanent --add-service=ntp
sudo firewall-cmd --reload
# 5. 验证:应看到 ^* 同步源
chronyc sources -v
timedatectl
10.3 客户端(192.168.1.20)配置
# 1. 安装
sudo dnf install -y chrony
# 2. 配置 /etc/chrony.conf(核心行,只同步、不授时)
sudo tee /etc/chrony.conf >/dev/null <<'EOF'
server 192.168.1.10 iburst
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
rtcsync
EOF
# 3. 启动
sudo systemctl enable --now chronyd
# 4. 验证
chronyc sources -v
timedatectl
10.4 验证结果判读
在客户端上,理想输出应满足:
chronyc sources -v第一行以^*开头,Stratum 为 3(从服务端 stratum 2 再下一级),Reach为 377。timedatectl中System clock synchronized: yes、NTP service: active。chronyc tracking中System time接近 0,Leap status: Normal。
若 ^* 没出现而是 ^?,按 7.4 排查网络/防火墙/DNS。
至此,内网所有客户端都指向同一时间源,多机时间保持一致——这正是第 0 章所述“时间作为基础设施”的落地。
十一、总结与延伸
11.1 本文要点回顾
- 为什么要同步:证书校验、日志、Kerberos、数据库、cron、NFS 等都依赖一致时钟;时间在分布式环境中是基础设施。
- 双时钟模型:系统时钟(软件、被同步)与硬件时钟(RTC、断电备份);chrony 同步系统时钟,
rtcsync/hwclock处理 RTC。 - NTP 原理:UDP 123、stratum 分层、四时间戳算往返延迟与偏移、大偏差 step / 小偏差 slew。
- chrony vs ntpd:chrony 更快、更稳、更适应现代环境,是各发行版默认。
- 配置:服务端 = 上游
pool/server+allow网段 + 防火墙放行 + 可选local stratum;客户端 = 指向服务端 +iburst,多源冗余。 - 验证:
chronyc sources -v(看^*)、chronyc tracking(看偏移/stratum)、timedatectl(看 synchronized/active)。 - 时区与 RTC:
timedatectl set-timezone、hwclock、RTC 存 UTC。
11.2 延伸方向
- 高精度授时(PTP):当普通 NTP(毫秒级)不够用时,数据中心/金融/音视频场景可用 PTP(IEEE 1588),由
linuxptp提供,精度可达亚微秒。 - 参考时钟(refclock):chrony 支持从本地 GPS/PPS 等硬件源授时,用于搭建高精度内网时间源。
- 闰秒处理:了解
leap second及 chrony 对闰秒的策略(如leapsecmode)。 - systemd-timesyncd:对“只需简单同步、不对外授时”的轻量场景,systemd 自带
systemd-timesyncd也是可选方案,但功能弱于 chrony。
掌握 NTP/chrony,是 Linux 运维与构建可靠分布式系统的基础功。后续可结合日志、监控、容器编排等话题继续深入。
参考资料
- chrony 官方文档(含 chrony.conf、chronyc、chronyd 手册):https://chrony-project.org/documentation.html
- chrony.conf(5) 配置文件手册:https://chrony-project.org/doc/latest/chrony.conf.html
- chronyc(1) 命令行客户端手册:https://chrony-project.org/doc/latest/chronyc.html
- chronyd(8) 守护进程手册:https://chrony-project.org/doc/latest/chronyd.html
- chrony 配置示例(官方 examples):https://chrony-project.org/examples.html
- timedatectl(1) 手册(man7):https://man7.org/linux/man-pages/man1/timedatectl.1.html
- date 命令详解(菜鸟教程):https://www.runoob.com/linux/linux-comm-date.html
- Linux 教程总览(菜鸟教程):https://www.runoob.com/linux/linux-tutorial.html
