几台机器的日志对不上时间、HTTPS 突然报"证书尚未生效"、定时任务是空的、数据库主从报时间偏移——这些现象看着毫不相干,但相当一部分的根因是同一个:某台机器的系统时钟偏了。
时间这件事在单机上几乎没人注意,一旦涉及证书、分布式、跨机排查日志,它就会变成那种查一天查不出来的问题。这篇讲清楚三件事:Linux 的时间到底由几部分构成、时间不对会具体怎么坏事、以及一次配好不再管的做法。
一、先分清:Linux 上有两套时间
这是所有校准操作的前提,搞混了会改错地方。
| 叫什么 | 谁在维护 | 怎么看 | |
|---|---|---|---|
| 系统时钟 | 软件时钟 | 内核 | date、timedatectl |
| 硬件时钟 | RTC | 主板上的电池 | hwclock -r |
开机时系统从 RTC 读一个初始值,之后就由内核自己走。断电重启才会再用一次 RTC,所以 RTC 准不准决定了"冷启动那一刻"准不准,平时的精度靠软件时钟的同步机制。
还有第三个变量——时区。内核里存的始终是从 1970 年算起的秒数(UTC),显示出来的本地时间是用时区换算的。所以本地时间变了,可能是时区变了,也可能是时钟真的偏了,这两种情况的处理完全不同。
一条命令能看到全部状态:
timedatectl status输出里重点看这几行:Time zone、NTP service、System clock synchronized、RTC in local TZ。最后这行如果不是no,建议改回来——硬件时钟保持 UTC 是通用做法,阿里云对镜像的要求里也明确写了这一点。
原因不难理解:如果 RTC 按本地时区存,遇到夏令时切换或者跨时区迁移,时间戳会出现重复或跳过的区间,日志顺序会彻底乱掉。统一用 UTC 就没这个问题,什么时候显示都交给时区去换算。
二、时间不准会连带出哪些事
按被发现的概率排:
| 现象 | 为什么会这样 |
|---|---|
| HTTPS 报证书无效、尚未生效 | 证书有效期完全依赖本地时间,偏了几年直接连不上 |
| 多台机器日志串不起来 | 排查跨服务问题时只能靠猜顺序 |
| 定时任务是空的 | cron 按时间触发,时间点被跳过去就不会补 |
| 数据库主从、分布式选举异常 | 复制位点、租约、心跳都带时间窗口 |
| API 签名、一次性口令验证失败 | 这类签名通常带 ±5 分钟的有效窗口 |
| 监控图出现断点或画到未来 | 时间戳回跳会让数据被判定为过期或直接落到时间轴外 |
这里面有一条特别值得记住:时间往回跳比往后再跳更危险。一个正在跑的程序如果依赖单调时间做超时判断,突然发现"现在"比刚才还早,行为就可能错乱。这也是后面选 chrony 的一个理由——它默认就不会用跳变的方式调整时间。
三、云平台镜像其实多半已经配好了
在动手改配置之前,先确认一下是不是真的需要改。这几家的公共镜像都预置了时间同步:
- 阿里云:官方明确说明公共镜像中包含了默认的时间同步配置,基于公共镜像创建的 ECS 会默认运行 Chrony 或 NTP 服务;阿里云的 NTP 服务器不收费。
- 华为云:官方文档写明,使用 x86 类型公共镜像创建的云服务器默认使用 chronyd 进行时间同步,无需配置 NTP 服务器。
- 腾讯云:新购实例同样是配好的,但官方文档专门列了一条常见问题——用自定义镜像创建的云服务器时间不对。
也就是说,一台刚开的机器时间不准,常见原因是下面这几种,而不是"没有配置 NTP":
- 用了自定义镜像,制作过程中同步配置被还原。腾讯云对此有明确解释:这是 Cloud-Init 初始化导致的,需要在制作镜像前处理掉
cloud.cfg里的 NTP 相关配置。 - 改过 DNS。内网 NTP 域名依赖内网 DNS 解析,改了 DNS 同步就断了——这条下面第六节会展开。
- 只是时区不对,看着像差了 8 小时。
- 服务没开机自启动,重启之后就再没同步过。
先过一遍这四条,能省掉很多无谓的配置改动。
四、先排除"差 8 小时":那是时区不是时间
date出来的时间和你手机上的差整 8 小时,第一步应该怀疑时区,而不是同步服务。
timedatectl list-timezones | grep Shanghai # 确认名称 timedatectl set-timezone Asia/Shanghai hwclock -w # 把当前系统时间写回硬件时钟linux服务器修改时区这件事用一条命令就能完成,不需要动同步服务。
改完再date一次。这一步做对了,很多看着像"时间不对"的工单到这儿就结束了。
判断方法其实很直接:偏移量是整小时(尤其是整 8 小时)优先查时区;偏移量是不规则的几分钟到几小时,才是同步问题。
五、chrony 还是 ntpd:看数据说话
这一节回答工具选型。chrony 官方网站上有一份对比测试数据,是把两台机器放在模拟 Linux 环境里跑出来的(单位微秒,100 次模拟的均值与标准差,详见 chrony 官方 comparison 页):
| 测试场景 | 网络抖动 | chrony | ntpd |
|---|---|---|---|
| 长期联网 + 时钟稳定 | 10 μs | 35 ± 8 | 234 ± 46 |
| 长期联网 + 时钟不太稳 | 10 μs | 14 ± 0 | 165 ± 17 |
| 间歇联网(每 24 小时只有 30 分钟能连) | 10 μs | 7273 ± 1744 | 608803 ± 510468 |
前两行是"chrony 更准"的量级差距,第三行是真正的关键:同样是每天只有半小时能联网,chrony 把误差控制在毫秒级,ntpd 已经跑到 0.6 秒量级。
chrony 官方原话列出了它更适合的场景,可以直接对照自己的机器:
- 只有几分钟时间联网
- 网络经常拥塞
- 机器经常关机或挂起
- 时钟本身不太稳(温度变化快,或者是虚拟机)
- 需要在没有硬件参考钟的隔离网络里用 NTP
另外几条跟运维实践直接相关的差异:
- chrony 默认不以跳变方式调整时间,避免打断正在运行的程序;ntpd 要配成不跳变的话得换另一种校时方式,代价是精度下降。
- chrony 能适应的时钟频率偏移范围更大,某些虚拟机里"抽风的时钟"也能拉回来。这条对云服务器尤其重要——虚拟机的时钟本来就不如物理机稳。
- chrony 体积更小、按需唤醒 CPU,对省电也有好处。
还有一个趋势方面的理由:ntp 这个老实现基本已经不再被维护,阿里云官方文档直接给出建议——如果 ECS 实例使用的是 NTP 服务,且业务不依赖 NTP 服务,建议升级为 Chrony。
顺带回答一个常被问到的问题:Ubuntu 上有自带的systemd-timesyncd,能不用 chrony 吗?chrony 官方 FAQ 的建议是可以但优先选 chrony。原因是 timesyncd 不能同时轮询多个服务器,也就无法识别出"时间本身是错的那个服务器"(NTP 术语叫 falseticker),用它配公共 NTP 池是有风险的。
六、一次配好:chrony 的最小可用配置
# Debian / Ubuntu apt update && apt install -y chrony # RHEL / CentOS / Rocky / AlmaLinux yum install -y chrony && systemctl enable --now chronyd配置文件位置要注意:RHEL 系是/etc/chrony.conf,Debian 系是/etc/chrony/chrony.conf。chrony 官方 FAQ 给出的"最小可用客户端配置"是这四行,照抄就够用:
pool <NTP服务器域名> iburst driftfile /var/lib/chrony/drift makestep 1 3 rtcsync每一行都不是摆设:
| 指令 | 作用 |
|---|---|
pool/server | 指定时间源。chrony 官方建议至少配三个,少于三个就无法通过交叉比对识别出时间错误的源 |
iburst | 启动时连发一串请求,加速首次同步,不用等默认的轮询间隔 |
driftfile | 记录本机时钟的漂移速率(每天快多少秒),下次启动直接在这个基础上收敛,省掉重新测量的时间 |
makestep 1 3 | 偏差超过 1 秒时,允许前 3 次更新直接跳变。不加这条,偏差大时 chrony 会慢慢"追",可能要追很久 |
rtcsync | 定期把系统时间写回硬件时钟,这样下次冷启动从 RTC 起步时就已经比较准了 |
改完重启服务,然后用这两条看结果:
chronyc sources -v # 某行前面出现 ^* 表示已选中这个源并同步成功 chronyc tracking # 看 Reference ID、Last offset、Leap status首次同步需要几分钟,别刚配完就下结论。华为云文档里也专门提醒了这一点,chronyc sources -v要等一会儿才会出^*。
如果偏差很大又不想等,可以强制校正一次:
chronyc -a makestep上面这几条连同第六节的配置文件,基本就是日常会用到的 linux服务器时间校准命令全集了——实际操作里不需要记更多。
七、各家云平台的 NTP 服务器地址
做 linux服务器时间同步ntp服务器的配置时,三家的地址都要区分内网和公网(详见阿里云时间同步、腾讯云 NTP 服务概述、华为云 NTP 服务器配置):
| 内网地址 | 公网地址 | |
|---|---|---|
| 阿里云 ECS | ntp.cloud.aliyuncs.com | ntp.aliyun.com、ntp1~ntp7.aliyun.com |
| 腾讯云 CVM | time1~time5.tencentyun.com | ntp.tencent.com、ntp1~ntp5.tencent.com |
| 华为云 ECS | 各区域统一ntp.myhuaweicloud.com | 同上(需配合华为云 DNS) |
四条使用注意:
一、优先用内网域名。阿里云ntp的地址分为内网ntp.cloud.aliyuncs.com和公网ntp.aliyun.com两组,官方文档明确推荐 ECS 使用 VPC 内网域名,“以获得更低的网络延迟”。这不是客气话——NTP 的精度直接受网络抖动影响,第三节那张表里的第一列就是网络抖动,10μs 和 10ms 的结果差了一个数量级。
二、腾讯云的内网域名拼写要照抄。是tencentyun.com,不是tencent。这是腾讯云ntp服务器官方文档上给出的地址,手打很容易写错,写错了的现象是 DNS 解析失败、一个源都连不上。腾讯云另外标注time1~time5.cloud.tencent.com是旧的外网地址,仍可用但建议改用新的。
三、NTP 域名依赖 DNS。这条最容易在大扫除时被踩到:华为云文档明确要求"使用华为云提供的 NTP 服务器时,需和华为云 DNS 服务器配套使用";腾讯云在改 DNS 的影响说明里也写着"影响服务器的时间同步 NTP 功能,该功能依赖内网域名"。所以自己改了/etc/resolv.conf之后发现时间不同步,第一反应应该是查 DNS 而不是查 chrony 配置。
四、华为云不区分区域,各区域都是同一个域名,不需要按 Region 去找对应关系。
如果想知道当前到底同步到哪个源,chronyc tracking输出里的 Reference ID 会告诉你。
八、UDP 123 端口:什么时候才真的需要放行
NTP 用 UDP 123,阿里云文档里有一句"需要在实例安全组的入方向添加安全组规则并放行 UDP 123 端口"。这句话容易被执行过头,它其实要分角色看:
- 只作为客户端(绝大多数情况):机器主动向外发起连接,走的是出方向。主流云厂商的默认安全组对出方向一般是放开的,通常什么都不用配。
- 作为服务给别的机器校时:才需要入方向放行 UDP 123。
看到"要开 123 端口"就去改安全组之前,先确认这台机器扮演的是哪种角色。给内网其他机器做校时汇聚点的那台需要入方向规则,其余机器不用。
验证端口排除不了的话可以从时间序列上看:chronyc sources里源显示?或x(不可达),先查 DNS 能不能解析,再查出方向 UDP 123 通不通。
九、linux服务器怎么和另外一台服务器时间校准
这是集群内网场景的常见问法,解法和单机不一样。
要的是机器之间的一致,不是每台都各自对准外网。正确做法是:
- 指定一两台"时间源"机器,让它正常同步到外网或云内网 NTP
- 其余机器的 chrony 配置指向这台机器,配成
server <内网IP> iburst - 时间源机器上需要加
allow <内网网段>,chronyd 默认不对外提供校时服务,必须显式允许才会打开服务端端口
这么做的好处是两台机器之间的偏差只受内网抖动影响,通常能压到亚毫秒级,比各自同步外网稳定得多。
顺带说一句跨机房的场景:如果两边之间延迟高且抖动大,别指望靠 NTP 把偏差压到微秒级。这种时候要考虑 PTP(精确时间协议),它靠硬件时间戳实现,是另一个量级的方案。
十、时间对不上时的排查顺序
把前面串起来,实际排查就按这五步走,每步结论明确:
1. timedatectl status 看 NTP service 是否为 active、System clock synchronized 是否为 yes 2. timedatectl status 看 Time zone,偏移是整小时先改时区 3. chronyc sources -v 看有没有 ^*,没有则往下查 4. getent hosts <NTP域名> 看 DNS 能不能解析内网域名 5. chronyc tracking 看 Last offset 有多大,判断是否要 makestep一、二两步能解决掉绝大部分"看着不对"的情况。真正卡住的是第三步之后,而那几步的根因通常集中在 DNS 和出方向端口两处。
这也是 linux服务器时间校准这件事里唯一值得记住的顺序——先分现象,再动配置。
回到开头那些现象。linux服务器时间校准这件事本身不难,难的是它出问题时总伪装成别的故障——证书错误、任务不跑、日志顺序离谱。
把顺序记牢就行:先分是时区还是时钟,再看同步服务有没有在跑,最后才去翻配置文件。新开的机器默认多半已经配好了,真正需要动手的是那些用自定义镜像创建的、迁移过来的、或者改过 DNS 的。
chrony 装上之后基本就不需要再管它,driftfile会帮它记住这台机器走快还是走慢,重启也能很快收敛。日常只需要偶尔看一眼chronyc sources -v里那个^*还在不在。
各家提供的 NTP 服务器地址和配置方式会随时调整,实际使用时以官网当期公示的文档为准。