1. 为什么你的局域网需要一个“统一钟表”?
你有没有遇到过这样的场景?办公室里几台服务器,日志时间对不上,排查问题像在玩“大家来找茬”,一个报错发生在10:01,另一个相关日志却显示在09:59,就差这两分钟,让你抓耳挠腮半天。或者,实验室里几台做数据采集的设备,因为各自系统时钟的微小漂移,导致采集到的数据时间戳无法严格对齐,后续分析起来麻烦重重。这些问题的根源,往往就是时间不同步。
在计算机的世界里,时间不仅仅是显示在屏幕右下角的一串数字。它是日志记录的基石,是分布式事务的协调者,是加密证书有效性的判官,更是数据一致性的守护神。想象一下,如果银行系统中,记录转账交易时间的A服务器比B服务器快了5秒,那账目可就全乱套了。在局域网内部,虽然不像连接互联网那样对“绝对准确”的北京时间要求苛刻,但确保所有设备拥有一致的“相对时间”至关重要。这就是局域网时间同步要解决的核心问题。
过去,很多人一提到时间同步,就会想到老牌的NTP(Network Time Protocol)和它的经典实现ntpd。ntpd确实很强大,像一位经验丰富但略显古板的老管家,能非常精确地调整时间。但它有个特点:为了追求极致稳定,它调整时钟时倾向于“细水长流”,通过微小的步进来逐渐校正。如果系统时间偏差很大(比如几分钟甚至几小时),它可能会花很长时间才能慢慢追回来。这在某些需要快速对齐的局域网场景下,就显得有点“慢热”了。
而今天我们要聊的Chrony,就像是这位老管家的一位敏捷、现代的接班人。它被设计得更加适合现代的计算环境,特别是在那些系统时钟可能不那么稳定(比如虚拟机经常休眠/恢复)、网络连接可能时断时续的场景下。Chrony 有两个绝活:一是它能更快地校正大的时间偏差;二是它在网络条件不佳时表现更稳健,即使暂时断网,也能依靠自身优秀的时钟模型保持相当精度。对于咱们局域网内部同步来说,Chrony 配置更简单,上手更快,效果也立竿见影,所以它逐渐成为了许多 Linux 发行版的默认时间同步工具。接下来,我就手把手带你,用 Chrony 在局域网里搭建一套属于你自己的“精准时钟体系”。
2. 动手之前:理解 Chrony 的核心组件
在开始敲命令之前,咱们先花几分钟把 Chrony 的核心家当搞清楚,这样后面配置起来心里才有底。Chrony 这套工具,主要就靠两个“兄弟程序”打天下:chronyd和chronyc。你可以把它们理解为一个在后台默默干活的服务员,和一个在前台跟你沟通、让你查看状态的管理员。
chronyd是守护进程,也就是真正的“时间同步引擎”。它以后台服务的形式运行,主要干三件大事:
- 与时间源对话:根据你的配置,去联系指定的 NTP 服务器(比如互联网上的公共时间服务器,或者咱们局域网里自己指定的那台“主时钟”机器),获取准确的时间信息。
- 调整系统时钟:计算本地时钟和时间源之间的偏差和漂移率(可以理解为时钟走快或走慢的趋势),然后以一种平滑的方式去调整内核中的系统时钟。它非常聪明,既能快速纠正大的偏差,又能避免因突然大幅调整时间而导致应用程序出错(比如,让时间一下子跳回10分钟前,正在运行的定时任务可能就混乱了)。
- 提供时间服务:当它被配置为服务器模式时,可以响应局域网内其他客户端机器的时间查询请求,把自己调整好的时间分享出去。
chronyc则是一个命令行客户端工具,是你和chronyd沟通的桥梁。通过它,你可以:
- 查看同步状态:最常用的
chronyc sources -v,可以列出所有配置的时间源及其状态、偏差、层级等详细信息,一眼就知道现在“听谁的”。 - 手动调整:进行一些临时性的操作,比如手动添加一个时间源 (
sources add),或者立即进行一次时间同步 (sources update)。 - 查看统计信息:用
chronyc tracking可以查看当前时钟的校准状态,比如调整频率、剩余误差等。 - 修改配置(运行时):部分配置可以在不重启服务的情况下动态修改。
理解了这两个角色,我们的任务就清晰了:在一台机器上安装并配置chronyd,让它既从外部(或内部)获取精准时间,又扮演局域网内的时间服务器;在其他机器上,也安装chronyd,但配置它们指向我们内部的那台时间服务器。这样,一个以我们指定机器为“时间源头”的局域网同步网络就建立起来了。整个架构非常清晰,接下来我们就进入实战环节。
3. 实战演练:三步搭建局域网 Chrony 时间同步体系
好了,理论铺垫完毕,咱们直接开干。我假设你有一个小型局域网,至少有两台 Linux 机器(物理机或虚拟机均可)。我们将其中一台命名为Server(IP: 192.168.1.100),它将作为我们局域网内的“主时间服务器”;另一台命名为Client(IP: 192.168.1.101),它将从 Server 同步时间。这个架构简单又实用。
3.1 第一步:基础安装与初始配置(两台机器都要做)
无论你打算让这台机器做服务器还是客户端,Chrony 的基础安装都是一样的。现在主流的 Linux 发行版(如 CentOS/RHEL 7/8, Rocky Linux, AlmaLinux, Fedora, Ubuntu 20.04/22.04等)基本都自带了 Chrony。如果没有,安装也非常简单。
在 Server 和 Client 上分别执行:
安装 Chrony:
# 对于 CentOS/RHEL/Rocky Linux/AlmaLinux/Fedora: sudo yum install -y chrony # 对于 Ubuntu/Debian: sudo apt update sudo apt install -y chrony安装命令会同时装上
chronyd服务和chronyc客户端工具。启动并设置开机自启:
sudo systemctl start chronyd sudo systemctl enable chronyd到这里,一个最基本的时间同步客户端就运行起来了。默认情况下,它会去连接发行版预置的公共 NTP 服务器池(如
pool.ntp.org的服务器)。我们可以先看看它的默认状态:chronyc sources -v你应该会看到一个列表,显示它正在和几个远程的 NTP 服务器通信,状态可能是
^*(当前最佳时间源)、^+(可用的良好时间源)等。(可选但推荐)检查当前时间状态:
timedatectl这个命令会输出系统时间、时区以及 NTP 服务是否激活的信息。确认
NTP service: active这一行。
3.2 第二步:配置 Server 作为局域网时间源
现在,我们要把 Server 机器(192.168.1.100)配置成我们局域网内部的时间权威。这意味着它需要做两件事:第一,自己先从一个非常可靠的外部时间源(比如阿里云、腾讯云的 NTP 服务器)同步好时间;第二,允许局域网内的其他机器来向它同步时间。
在 Server (192.168.1.100) 上操作:
编辑 Chrony 的主配置文件:
sudo vim /etc/chrony.conf或者使用你喜欢的其他编辑器,如
nano。修改配置文件内容。我们需要关注几个关键指令:
- 指定上游时间源:找到以
pool或server开头的行。这些行定义了本机去同步时间的外部服务器。为了更稳定快速(特别是在国内),我们可以将其注释或替换为国内的公共 NTP 服务器。例如,添加阿里云的 NTP 服务器:
这里的# 注释掉或替换原有的 pool 行,例如: # pool 2.centos.pool.ntp.org iburst server ntp.aliyun.com iburst server ntp1.aliyun.com iburstiburst参数非常有用,它表示在服务启动初期,会发送一串数据包来快速完成初始同步。 - 允许客户端访问:这是让 Server 成为时间服务器的关键。在文件中添加一行:
这表示允许整个allow 192.168.1.0/24192.168.1.x网段的机器向本机同步时间。如果你想允许所有,可以用allow all,但在生产环境建议限定子网以提高安全性。 - 设置本地时间层级(Stratum):这是一个表示时间源“距离真实权威时间源有多远”的数字。层级越小,越接近原始时钟(如原子钟)。我们从阿里云同步,阿里云服务器可能是 stratum 2,那么我们这台 Server 自然就成为 stratum 3。但有时我们希望明确指定一个层级,特别是当它作为内部主要时间源时。可以添加:
这个local stratum 6local stratum 6指令非常有用。它告诉 chronyd:即使暂时失去所有上游服务器,也允许你以自己的系统时钟作为时间源,并对外宣称自己的层级是6。这能保证在断网时,局域网内依然有一个可用的时间源,避免客户端因找不到源而时间混乱。这正是我们任务要求中“使用系统时间作为时钟源”的实现方式。
一个修改后的配置文件关键部分示例:
# 使用阿里云时间服务器 server ntp.aliyun.com iburst server ntp1.aliyun.com iburst # 允许局域网网段同步 allow 192.168.1.0/24 # 即使失去所有上游源,也以本地时钟作为 stratum 6 的源 local stratum 6 # 其他保持默认,如记录目录、日志等- 指定上游时间源:找到以
保存并退出编辑器,然后重启 chronyd 服务使配置生效:
sudo systemctl restart chronyd验证 Server 配置:
- 查看同步源状态,确认已连接到阿里云服务器:
你应该能看到chronyc sources -vntp.aliyun.com的状态是^*或^+。 - 查看跟踪信息,了解当前的同步精度:
关注chronyc trackingSystem time(与源的时间差)和Last offset(最后一次调整的偏移量),数值越小越好,通常在毫秒级别。 - 检查本机时间是否已同步:
确认时间大致准确,且显示timedatectlNTP service: active。
- 查看同步源状态,确认已连接到阿里云服务器:
3.3 第三步:配置 Client 从 Server 同步时间
现在,我们来配置 Client 机器(192.168.1.101),让它放弃默认的公共 NTP 服务器,转而信任我们局域网内的 Server。
在 Client (192.168.1.101) 上操作:
编辑 Chrony 配置文件:
sudo vim /etc/chrony.conf修改配置文件内容。这一步更简单:
- 注释或删除原有的所有
server或pool行,因为我们不再直接连接外网。 - 添加指向我们内部 Server 的配置行:
这里server 192.168.1.100 iburst192.168.1.100就是我们 Server 的 IP 地址。iburst同样用于快速初始同步。 - (可选)如果 Server 配置了
allow指令但未使用allow all,确保 Client IP 在允许范围内。我们之前配置的是allow 192.168.1.0/24,所以 Client 的 IP 肯定在允许列表里。
修改后的 Client 配置文件关键部分可能像这样:
# 指定局域网内的时间服务器 server 192.168.1.100 iburst # 原有的外部服务器行已被注释或删除 # pool 2.centos.pool.ntp.org iburst- 注释或删除原有的所有
保存退出,并重启 chronyd 服务:
sudo systemctl restart chronyd验证 Client 同步状态:
- 这是最关键的一步。在 Client 上运行:
你期待看到的理想结果是:chronyc sources -v192.168.1.100这个源出现在列表中,并且其状态标志为^*(星号),表示它是当前选中的最佳同步源。Stratum列应该显示为7(因为 Server 是 stratum 6,下游客户端就是 stratum 7)。如果看到^?(表示未连接)或^x(表示错误),就需要排查了。 - 同样可以用
chronyc tracking查看详细的同步指标。 - 对比 Server 和 Client 的时间,可以使用
date命令,或者更精确地,在 Client 上运行chronyc makestep(如果偏差大的话,但通常服务会自动调整)。
- 这是最关键的一步。在 Client 上运行:
4. 验证、监控与故障排查指南
配置完了,怎么知道一切真的在完美运行呢?总不能每次都靠猜。这里我分享几个我常用的验证和监控命令,以及遇到问题时怎么一步步排查。
4.1 核心验证命令
chronyc sources -v:这是你的“仪表盘”。-v参数会输出详细信息。重点关注几列:- M:源的模式。
^*是当前最佳源,^+是合格的备用源,^-是合格的源但未被选中,^?是未连接或状态未知,^x是假时钟源(认为不可信)。 - S:源的状态。
*表示当前同步的源,+表示可接受的源,-表示可接受的源但距离较远,?表示状态未确定。 - Stratum:层级。你的 Client 应该比 Server 的层级大1。
- Poll:轮询间隔(秒)。数字表示2的N次方秒,比如6表示64秒。值会动态调整。
- Reach:可达性寄存器(八进制)。显示最近8次查询的成功/失败情况,
377表示全部成功,是理想状态。 - LastRx:最后一次接收到样本的时间。
- Last sample:最后一次测量的时间偏移量。这个值应该在正负几毫秒到几十毫秒之间波动。
- M:源的模式。
chronyc tracking:查看 chronyd 自身的性能指标。- Reference ID:当前同步的源ID或IP。
- Stratum:本地时钟的层级。
- Ref time (UTC):最后一次从服务器更新时间的时间。
- System time:系统时钟与当前源的偏差。这是关键指标,理想情况是
0.000000000 seconds或一个非常小的值。 - Last offset:最后一次时钟更新的偏移量。
- RMS offset:偏移量的长期平均值。
- Frequency:系统时钟的自然漂移率。即使没有NTP,chrony也会估算你的硬件时钟是偏快还是偏慢(单位是ppm,百万分之一)。
timedatectl status:快速查看系统级的时间与NTP服务状态。确保NTP service: active且System clock synchronized: yes。
4.2 常见问题与排查思路
如果chronyc sources显示状态不是^*,或者Last sample偏差巨大,可以按以下思路排查:
问题:Client 显示
^?(未连接)- 排查网络:首先用
ping 192.168.1.100检查 Client 到 Server 的网络连通性。 - 检查防火墙:这是最常见的坑!NTP 使用UDP 123端口。确保 Server 的防火墙放行了来自 Client 的 UDP 123 端口入站流量,同时 Client 的防火墙也允许出站到 Server UDP 123 端口。
- 对于 firewalld (CentOS/RHEL等):
# 在 Server 上执行 sudo firewall-cmd --permanent --add-service=ntp sudo firewall-cmd --reload - 对于 ufw (Ubuntu):
# 在 Server 上执行 sudo ufw allow from 192.168.1.0/24 to any port 123 proto udp sudo ufw reload
- 对于 firewalld (CentOS/RHEL等):
- 检查 Server 配置:确认 Server 的
/etc/chrony.conf中allow指令是否正确包含了 Client 的网段。 - 检查服务状态:在 Server 上运行
sudo systemctl status chronyd,确保服务正在运行且无报错。
- 排查网络:首先用
问题:时间同步了,但偏差一直比较大(几十到几百毫秒)
- 网络延迟:局域网内通常延迟很小(<1ms),如果偏差大,检查是否有网络拥塞或虚拟机宿主机的负载过高。
- 硬件时钟问题:某些虚拟化环境或老旧硬件时钟不稳定,漂移率 (
Frequency) 值很大。Chrony 能补偿,但需要时间。可以尝试在 Client 配置文件中为 server 行添加minpoll 4 maxpoll 4参数,以更频繁地轮询(4表示16秒),但会增加网络和服务端负载,请酌情使用。 - 多个时间源冲突:检查 Client 配置,确保只配置了 Server 这一个
server行,没有残留的其他外部服务器配置,否则 chrony 可能会在多个源之间纠结。
问题:
chronyc tracking显示System time为0.000000000,但date命令显示的时间就是不对- 检查时区:时间同步只管协调世界时(UTC),显示的时间取决于系统时区设置。用
timedatectl查看Time zone。如果时区不对,可以用sudo timedatectl set-timezone Asia/Shanghai(例如设置为上海时间)来修正。时区不对会导致显示的时间差几个小时。
- 检查时区:时间同步只管协调世界时(UTC),显示的时间取决于系统时区设置。用
4.3 进阶监控与管理
对于需要长期稳定运行的环境,可以考虑:
- 日志查看:Chrony 的日志通常由系统日志服务管理,可以用
sudo journalctl -u chronyd来查看服务日志,排查启动错误或运行时警告。 - 强制同步:如果发现 Client 时间偏差很大(比如几分钟),chrony 默认的平滑调整可能需要很久。这时可以手动强制步进调整(注意:这可能导致正在运行的程序对时间跳变产生异常):
sudo chronyc makestep - 将 chronyc 命令加入监控:你可以编写一个简单的脚本,定期运行
chronyc tracking | grep ‘System time’,提取偏差值,如果超过阈值(比如100毫秒)就发出告警,集成到你的运维监控系统中。
经过以上步骤,你应该已经成功搭建了一个简单可靠的局域网 Chrony 时间同步系统。从我的经验来看,这套方案在几十台机器的小型内网环境中非常稳定,几乎不需要维护。关键就是最初把防火墙规则和配置文件弄对,剩下的就交给 Chrony 默默工作吧。下次再遇到日志时间对不上的问题,你就能从容地指着一台服务器说:“看,咱们整个网络的时间,都跟着它走呢。”