暗色模式

Linux 时间同步:从 date 到 timedatectl 与 chrony NTP 服务配置

技术教程
2026-08-20
11
0

Linux 时间同步:从 date 到 timedatectl 与 chrony NTP 服务配置

本文要点
  • 时间乱了会出大问题:证书校验、日志排序、分布式数据一致性、cron 调度都会出错,Linux 时间管理是运维基本功。
  • 单个命令速查date 查看/格式化时间,hwclock 管理硬件时钟,timedatectl 查看状态与切换时区,chrony 负责网络时间同步。
  • Ubuntu 24.04 默认用 systemd-timesyncd,它是轻量 NTP 客户端;追求高精度建议换 chrony,配置文件在 /etc/chrony/chrony.conf
  • chronyc 是查询神器chronyc tracking 看同步偏差,chronyc sources -v 看时间源质量,chronyc makestep 立即校正。
  • 同步失败的排查思路:先看 NTP 服务与 123 端口,再看时间源可达性与本地偏移,必要时手动 makestep

时间为什么会乱?为什么要同步?

服务器不像普通人想的那样天生时间准确。CPU 里的时钟晶振会随温度、电压发生漂移,一块普通主板时钟一天可能偏差数秒到数十秒;虚拟机更是依赖宿主机转发的时间,一开机就可能偏了几分钟。

时间偏差在开发与运维中引发的故障五花八门:

  • HTTPS 证书校验失败:证书有生效/过期时间,服务器时间不在有效期内,浏览器直接报"证书无效"。
  • cookie 与 session 失效:登录态按时间过期,时间错乱会导致刚登录就被登出。
  • 日志与监控错乱:多台服务器时间不同,排查崩溃根因时事件顺序对不上。
  • cron 任务错峰来袭:所有机器时间集体漂移后,业务高峰可能被集中触发。
  • 数据库主从与分布式锁误判:TCC、MVCC、Redis 过期等都对时间敏感,轻微偏差可能造成数据不一致。

因此,Linux 运维最基本的动作之一,就是"查看时间、校准时间、配置自动同步"。本文从查看时间的 date,到管理时区的 timedatectl,到最常用的 NTP 实现 chrony,完整串一遍。

用 date 查看与格式化时间

date 是最直接查看系统当前时间(也就是系统的软件时钟)的命令。不带参数直接运行,输出默认格式:

date 与 hwclock 查看系统时间

$ date
Thu Aug 20 20:06:04 CST 2026

默认格式信息齐全但不够程序化。日常更常用的是用 + 加格式化占位符按自己需要的格式输出:

$ date "+%Y-%m-%d %H:%M:%S"      # 2026-08-20 20:06:04
$ date +%s                         # 1787227564(Unix 时间戳)
$ date -u                          # Thu Aug 20 12:06:04 UTC 2026

几个最常用的 % 占位符:

占位符含义示例
%Y四位年份2026
%m两位月份08
%d两位日期20
%H:%M:%S时:分:秒20:06:04
%sUnix 时间戳(从 1970-01-01 00:00:00 UTC 起的秒数)1787227564
%A星期几英文全称Thursday

date -u 显示的是 UTC(世界协调时),它与本地时间相差 8 小时,这正是时区造成的——中国统一使用东八区,CST 表示 China Standard Time。注意这里的 CST 在别处也可能是 Central Standard Time 或 Cuba Standard Time,看到 +0800 偏移才是确认中国时区的关键。

date 默认显示的是软件时钟(system time),由内核维护,开机自硬件时钟初始化。而主板上有电池供电的芯片维持的硬件时钟(RTC,Real-Time Clock),关机也不会丢,用 hwclock 查看:

$ hwclock --show
2026-08-20 20:06:04.607729+08:00

hwclock 在部分精简镜像里没装,用 apt install util-linux-extra 补上。机器正常同步后,建议让系统在关机时把软件时钟写回硬件时钟,保证两者一致。

时区管理与 timedatectl

timedatectl 是 systemd 提供的一体化管理时间与时区的命令,Ubuntu 24.04 自带。不带参数输出当前完整状态:

timedatectl 查看与切换时区

$ timedatectl
               Local time: Thu 2026-08-20 20:07:40 CST
           Universal time: Thu 2026-08-20 12:07:40 UTC
                 RTC time: Thu 2026-08-20 12:07:40
                Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

字段解读:

  • Local time / Universal time:本地时间与 UTC 时间。
  • RTC time:硬件时钟的时间。这里恰好与 UTC 相同,说明系统把硬件时钟当作 UTC 使用(RTC in local TZ: no),这是服务器推荐配置,跨时区迁移不用改 BIOS 时间。
  • System clock synchronized:系统时钟是否已与 NTP 源同步过。我刚切换过时区且等待同步后,这里立即恢复 yes
  • NTP service:网络时间服务(NTP)是否开启。active 表示自动同步生效。

查看与切换时区

查看系统所有可用时区,数量上千条:

$ timedatectl list-timezones

可以配合 grep 快速过滤:

$ timedatectl list-timezones | grep -E "Asia/Shanghai|Asia/Tokyo|Etc/UTC"
Asia/Shanghai
Asia/Tokyo
Etc/UTC

切换时区用 set-timezone,需要一个 区域/城市 形式的完整名字:

$ timedatectl set-timezone Asia/Shanghai
$ timedatectl set-timezone UTC
$ timedatectl set-timezone Asia/Tokyo

切换立即对全系统生效(不只是某个 shell),无需重启。截图里演示了切换到 UTC 再切回 Asia/Shanghai 的完整过程,切换后再次运行 timedatectl,Local time 与 Universal time 的偏移、Time zone 那一行都会同步变化。

开启与关闭 NTP 自动同步

set-ntp 子命令控制 systemd-timesyncd 服务与 NTP 自动同步的开关:

$ timedatectl set-ntp true     # 开启(默认)
$ timedatectl set-ntp false    # 关闭,需要手动校准

关闭后 System clock synchronized 会变成 no。生产服务器不要关闭自动同步,手动设置时间(timedatectl set-time)也只是临时措施——几次重启、几天漂移后又会被打回原形。

NTP 同步原理:本地时钟如何"对齐"时间服务器

软件时钟同步靠 NTP(Network Time Protocol)。原理可以一句话概括:客户端向 NTP 服务器发送带时间戳的请求,根据往返时延计算出一个"网络延迟补偿",再从服务器返回的时间中扣除这个补偿,得到可信的参考时间。

NTP 服务器按层级(Stratum)分级:

层级说明
Stratum 0原子钟、GPS 等物理授时设备,不直接对外服务
Stratum 1直连 Stratum 0 的服务器,最权威
Stratum 2从 Stratum 1 同步,数量最多
Stratum 3+依此类推,层级越深精度越差

普通客户端直接从 Stratum 2/3 的时间池同步即可,不需要、也不应配置成 Stratum 1——那会给权威源增加无谓负载。

同步不是"拷贝一份当前时间",而是一个持续校正过程:chrony 这类守时软件会持续测量本地时钟与参考时间的偏差,估算出晶振的频率漂移并写入 drift 文件,之后即使网络短暂中断,也能维持较高精度。

chrony:Ubuntu 上更专业的 NTP 实现

Ubuntu 24.04 默认使用 systemd-timesyncd 做轻量 NTP 客户端,对大多数场景够用。但它的可观测性很弱——没有直观查询同步偏差、时间源的接口。真正做时间维护,运维更常用 chronychronyd 守护进程 + chronyc 查询工具),精度可达毫秒级,且支持从多个时间源共同参考。

安装与启用

$ apt install chrony

安装后需要停用默认的 systemd-timesyncd 服务,再启用 chronyd(安装包在 Ubuntu 上会自动停用前者的竞争端口,但手动确认更稳妥):

$ systemctl stop systemd-timesyncd
$ systemctl disable systemd-timesyncd
$ systemctl enable --now chrony
$ systemctl status chrony      # 确认 active (running)

配置时间源

配置文件 /etc/chrony/chrony.conf,Ubuntu 默认内容已经把常用的池配好:

pool ntp.ubuntu.com        iburst maxsources 4
pool 0.ubuntu.pool.ntp.org iburst maxsources 1
pool 1.ubuntu.pool.ntp.org iburst maxsources 1
pool 2.ubuntu.pool.ntp.org iburst maxsources 2

pool 是动态服务器池,会从公共 NTP 池里挑选若干服务器;iburst 让 chronyd 启动后的每个轮询周期立即发送 4 个包完成快速收敛;maxsources 限制一个池最多使用几个源。

也可以单独指定固定服务器:

server time.cloudflare.com iburst
server ntp.aliyun.com      iburst

另外几个值得关注的默认项:

driftfile /var/lib/chrony/chrony.drift   # 记录本地时钟频率漂移
rtcsync                                  # 每 11 分钟把系统时间写回硬件时钟(RTC)
makestep 1 3                             # 前 3 次更新中偏差大于 1 秒时直接跳变校正
maxupdateskew 100.0                      # 频率偏差超过 100ppm 拒绝接受,防止坏源带偏时钟

makestep 1 3 是一个对刚启动、偏差巨大的机器很重要的策略:正常情况 chrony 会缓慢平滑时钟(slew),不引起日志跳跃;但开机偏差超过 1 秒时,在头 3 次更新直接跳变(step)到正确时间——否则要等十几分钟才能"拧"回来。

改完配置后重载生效:

$ systemctl restart chrony

用 chronyc 查询同步状态

chronyc 是 chrony 的查询/控制客户端,最常用的四个子命令:

1. 查看整体同步偏差(tracking)

$ chronyc tracking

输出重点字段:

  • Reference ID / Stratum:当前参考源地址与层级。
  • System time:本地时钟与 NTP 参考时间的当前偏差,如 0.000001697 seconds slow of NTP time(慢了多少秒)。
  • Frequency:本地时钟晶振频率漂移(ppm,百万分之一),稳定后应基本不变。
  • Leap status:闰秒状态,Normal 正常。

2. 查看时间源质量(sources)

$ chronyc sources -v

chronyc 查询 NTP 同步状态与时间源

上图中 sources -v 的输出里,每行是一个候选时间源,看两列即可快速判断同步健康状况:

  • 第一列状态符:^* 表示当前被选中的参考源;^+ 表示可用的组合源;^- 表示不被选中的源;^? 表示不可达/不可用。
  • Stratum:源层级,越低越权威。
  • Reach:可达性(八进制),数值越高(接近 377)表示最近轮询都成功,低到 0 说明源失联。
  • Last sample:最近一次测量得到的偏差。

3. 立即强制校正(makestep)

偏差较大、不想慢慢等平滑收敛时,手动跳变现校:

$ chronyc makestep
200 OK

返回 200 OK 表示本地时钟已立即校正到参考时间。注意它会丢弃当前记录的漂移历史,仅用于快速临时校准,正常运行无需使用。

4. 查看源统计(sourcestats)

$ chronyc sourcestats

显示每个时间源的采样点数、频偏估算与标准差,用于评估时间源稳定性。

排查同步问题的思路

时钟不同步时,按下面的顺序逐步收敛问题:

1. 看服务是否在跑,端口是否监听

$ systemctl status chrony
$ ss -ulnp | grep 123
UNCONN 0 0  127.0.0.1:323 ...   # 这是 chronyc 的控制端口
UNCONN 0 0  192.168.1.10:123 ...# 123 是 NTP 端口

chrony 同时监听 123(NTP 协议)与 323(chronyc 本地控制)。只要你只是同步别人的时间,对外 UDP 端口被防火墙封锁通常会主动显示缺源,但 chrony 本身用本地 UDP 123 收发 NTP 包,若 systemctl is-active chrony 是 active,服务基本正常。

若默认 systemd-timesyncd 与 chrony 并存,两者都想占 123 端口会产生冲突(这是常见故障)——确认只保留一个 NTP 服务。

2. 看时间源是否可达

$ chronyc sources -v

^? 大量出现、Reach 为 0,说明网络到时间池不可达。检查 DNS、到公网 NTP 服务器的 UDP 123 端口连通性(腾讯云/阿里云内网通常有内网 NTP 源,延迟更低更稳)。

3. 看偏差是否收敛

$ chronyc tracking

System time 持续增大说明没同步上;Leap status 不是 Normal 说明参考源异常。偏差在几毫秒内且 Frequency 稳定,即为健康状态。

4. 手动立即校正

$ chronyc makestep
$ date

校准后立即用 date 验证。日常不需要手动执行,交给 chronyd 持续守护即可。

小结

Linux 时间管理可以拆成三个层次:date/hwclock 查看与记录timedatectl 管时区与开关chrony 自动持续同步。记住三个动作就够上手:

  1. timedatectl 看状态与 NTP 开关,timedatectl set-timezone 换时区;
  2. 需要高精度时用 chrony,配置文件 chrony.conf 配 pool/servere + iburstrtcsync 保持硬件时钟同步;
  3. chronyc 三连查:tracking 看偏差、sources -v 看源、makestep 手动校。

时间扰乱的故障 90% 都能靠这三步定位。熟记它们,比背下所有 NTP 配置项实用得多。

发表评论

暂无评论,快来抢沙发吧!