
Ubuntu 开启 NTP 时间同步这件事说简单也简单一条timedatectl set-ntp true好像就能收工说麻烦也真的麻烦服务器日志时间对不上、双系统进 Windows 再回 Ubuntu 差 8 小时、虚拟机一挂起就漂走、内网摄像机无法自动校时这些问题背后都跟时间同步有关。我前后在 Ubuntu 桌面、Ubuntu Server、虚拟机、双系统、WSL 以及内网服务端场景里折腾过很多次最后发现真正稳的做法不是“随便挑一个公共 NTP 服务器写进去”而是先搞清楚 Ubuntu 当前用的是什么时间同步组件再决定用 systemd-timesyncd、chrony 还是更专业的 PTP。这篇内容围绕 Ubuntu、NTP、时间同步三个核心点展开适合刚装完 Ubuntu 的新手、负责几台服务器运维的人、需要给局域网摄像机和开发板校时的人也适合在 VMware、VirtualBox、双系统、WSL 里写代码的人。我会把系统时钟、硬件时钟、时区的关系讲清楚再把 systemd-timesyncd 和 chrony 两种主流方案拆开写包含配置文件、命令、参数解释、防火墙放行、排错顺序和常见问题速查表。你不需要从头啃 NTP 协议文档照着做就能让 Ubuntu 的时间自动校准也能在局域网里搭出一个可用的 NTP 服务端。1. 先把时间同步的三个概念掰开系统时钟、硬件时钟、时区1.1 系统时钟与硬件时钟一个在内存里跑一个在主板上睡Ubuntu 里经常提“时间”但它其实至少分两层系统时钟和硬件时钟。系统时钟由内核维护存在内存里平时date、timedatectl看到的都是它硬件时钟通常叫 RTC在主板上靠纽扣电池维持关机后还在走。NTP 同步主要校准的是系统时钟然后通过rtcsync或hwclock把结果写回硬件时钟。很多人只看了date输出正常就以为万事大吉结果一重启时间又乱根本原因是硬件时钟没有同步或者硬件时钟被设置成了本地时间而不是 UTC。这里有个特别容易踩的坑Linux 传统上把硬件时钟当 UTC 看待Windows 默认把硬件时钟当本地时间看待。Ubuntu 和 Windows 双系统装在同一个机器上两边对 RTC 的理解不一致就会出现进 Windows 正常、回 Ubuntu 差 8 小时或者反过来。解决思路不是每次手动date -s而是统一 RTC 标准。把 Ubuntu 设为使用 UTC 硬件时钟通常更符合服务器习惯命令是sudo timedatectl set-local-rtc 0如果你更想让 Windows 那边保持默认也可以让 Ubuntu 把 RTC 当本地时间但我个人建议服务器和长期运行的机器统一用 UTC日志、数据库、容器编排都少很多麻烦。NTP 同步的过程也不是“每隔几秒硬改一次时间”。直接猛跳系统时钟会让依赖时间连续性的程序出问题比如数据库事务、日志排序、证书校验、定时任务。所以 chrony 这类实现会先慢慢调整频率让系统时钟“快一点”或“慢一点”地追上正确时间只有偏差特别大、或者刚启动时才允许步进跳变。这个区别在配置文件里体现为makestep参数后面会详细说。理解这一点你看到“同步状态正常但时间还有一点偏差”时就不会慌因为它可能正在 slew 调整。1.2 时区设置错了NTP 再准也白搭NTP 传输的是 UTC 时间Ubuntu 拿到 UTC 后再根据系统时区转换成你看到的本地时间。所以时区错了NTP 再准也没用。比如你明明在 UTC8系统时区却是 UTC那date永远慢 8 小时反过来设成 UTC-5时间又会快 13 小时。检查时区最直接的是timedatectl输出里的Time zone一行会显示类似Asia/Shanghai (CST, 0800)。如果不是你所在时区可以用sudo timedatectl set-timezone Asia/Shanghai改掉。改时区不会改系统时钟的绝对时间它改的是显示规则。但很多人顺序搞反先手动把date -s改成“看起来正确”的本地时间再把时区一改结果绝对时间又错了。正确顺序是先确认时区再确认系统时钟是否同步最后看硬件时钟。尤其是在新装的 Ubuntu 系统里安装向导如果时区选错后面所有时间都会带着错误偏移。虚拟机安装 Ubuntu 时也常见这个问题宿主和虚拟机时区不一致校准前先统一。还有一个细节/etc/localtime和/etc/timezone是时区配置文件timedatectl会帮你管理不建议自己手动复制文件。有些老教程会让你ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime这本身没错但配合timedatectl时容易状态不一致。能用timedatectl set-timezone就用它输出明确回滚也简单。1.3 为什么 NTP 不是“每隔几秒对一次表”那么简单NTP 的目标是让你和上游服务器保持在同一时间尺度上而不是每次都把时间硬跳到和上游一模一样。网络有延迟、服务器有抖动、系统时钟晶振有漂移所以 NTP 客户端会做一系列估算往返延迟、时间偏差、频偏、抖动。chrony 还会记录时钟漂移率写进driftfile下次启动时先按这个漂移率补偿再去找上游继续微调。这样即使网络短时间断开时间也不会立刻崩掉。这也是为什么我不推荐在生产服务器上用*/5 * * * * ntpdate这种定时硬校时。ntpdate在很多新系统里已经默认不装因为它会让时间跳变而且和正在运行的 NTP 服务冲突。现代 Ubuntu 桌面和 Server 基本都自带了 systemd-timesyncd或者推荐 chrony。你要做的是启用正确的服务而不是叠加一堆定时任务互相打架。多个时间同步服务同时跑是非常典型的“越修越乱”来源。另外NTP 用 UDP 123 端口。客户端默认用 123 作为源端口去访问上游 123 端口服务端则监听 123。防火墙如果只放行了 TCP或者只允许了出站 HTTP/HTTPSNTP 就会失败。虚拟机、云服务器、公司内网还可能有额外的安全策略导致 UDP 123 出不去。排查同步问题时这一步必须单独确认不能只看服务状态。2. 动手前先体检确认 Ubuntu 现在的时间状态2.1 三条命令看清时间、时区、同步服务在改任何配置之前先跑这三条命令date、timedatectl、systemctl status systemd-timesyncd。date看当前系统时钟timedatectl看时区、NTP 服务是否启用、系统时钟是否已同步systemctl status看具体服务在不在跑。一个典型的健康输出里System clock synchronized: yes和NTP service: active是我们要的结果。如果NTP service: inactive说明自动同步没开如果 synchronized 是 no可能是服务没跑、网络不通、上游不可达或者刚启动还没完成首次同步。timedatectl还会显示RTC in local TZ。如果是no说明硬件时钟按 UTC 解释如果是yes说明按本地时间解释。双系统用户要重点看这一行。有人只盯着System clock synchronized却忽略了RTC in local TZ结果每次重启都差几个小时。我的建议是服务器、虚拟机、长期开机的开发机统一让 RTC 用 UTC只有确实要和默认 Windows 行为妥协时才考虑 local TZ。systemctl status systemd-timesyncd的输出里会带最近一次同步的服务器地址、时间戳和状态。如果服务根本没安装会提示 Unit 找不到。Ubuntu Desktop 和 Ubuntu Server 通常默认带 systemd-timesyncd但有些最小化安装、容器镜像、定制镜像会裁掉。另一种情况是你后来装了 chronysystemd-timesyncd 被停用或屏蔽。体检的目的就是避免“以为在用 A实际在跑 B”。2.2 判断当前系统在用 systemd-timesyncd 还是 chronysystemctl status systemd-timesyncd和systemctl status chrony两个都跑一下。哪个 active 就以哪个为主。不要同时启用两个客户端服务它们都会尝试调整系统时钟虽然不一定立刻冲突但日志会变得很难看排错时也容易误判。Ubuntu 上 chrony 安装后通常会接管时间同步有些版本会自动停用 systemd-timesyncd有些版本则需要你手动处理。最稳妥的做法是二选一明确停用另一个。如果你看到chronyd在跑配置文件通常在/etc/chrony/chrony.conf。如果你看到systemd-timesyncd在跑配置文件在/etc/systemd/timesyncd.conf。这两个文件的语法完全不同不要互相复制粘贴。systemd-timesyncd 的配置很轻量主要就是NTP和FallbackNTPchrony 的配置则支持pool、server、allow、local stratum、makestep等更丰富的指令。有一个常见误区只在/etc/systemd/timesyncd.conf里写了 NTP 服务器却没有确认timedatectl set-ntp true。配置文件只是告诉服务“找谁同步”timedatectl控制的是“是否允许自动同步”。如果 NTP 服务是 inactive配置文件写得再漂亮也没用。所以顺序是先选服务再改配置再启用服务最后验证。2.3 网络和 UDP 123 端口先通不通NTP 走 UDP 123。你可以先用ss -lunp | grep 123看本机有没有服务监听 123如果只是客户端不一定监听 123但出站必须能到上游 123。测试上游可达性可以用chronyc或ntpdate -q但新系统可能没有 ntpdate。更通用的方式是先ping ntp.aliyun.com看域名解析和基本连通性再用nc -u -z -v ntp.aliyun.com 123或nmap -sU -p 123 ntp.aliyun.com测 UDP。注意 UDP 测试结果不如 TCP 直观没有响应不代表一定不通但至少能帮你发现 DNS、路由、防火墙层面的明显问题。如果你在公司内网或云服务器上UDP 123 出站被限制很常见。有些环境只允许内网 NTP 服务器不允许直接访问公共 NTP。这时正确做法是找内网 NTP 源或者在一台能出网的 Ubuntu 上搭 chrony 服务端其他机器指向它。云厂商通常也提供内网 NTP 地址具体以你使用的平台文档为准。不要在每台机器上写一堆公共地址硬碰运气内网分层更可控。防火墙方面Ubuntu 的 ufw 如果开启了服务端要放行123/udp。客户端出站通常默认放行但如果 ufw 规则很严也要检查出站策略。命令是sudo ufw status verbose。服务端给内网提供 NTP 时我会用sudo ufw allow from 192.168.1.0/24 to any port 123 proto udp这种方式限制来源而不是直接sudo ufw allow 123/udp对全网开放。时间服务器虽然风险不高但能收窄来源就收窄。2.4 虚拟机、双系统、WSL 的特殊体检项虚拟机安装 Ubuntu 时时间同步有三层宿主时间、虚拟机增强工具时间同步、Ubuntu 内部 NTP。VMware Tools 或 VirtualBox Guest Additions 可能会在挂起恢复后帮你同步时间也可能和 Ubuntu 的 NTP 服务互相抢方向盘。我的经验是让虚拟机内部 NTP 正常工作同时关闭增强工具里的强制时间同步或者只在挂起恢复后允许它校一次。否则日志里会出现时间被外部工具突然改动的记录。双系统用户体检时要重点看 RTC 设置。进 Ubuntu 后跑timedatectl看RTC in local TZ是 yes 还是 no。如果你希望 Windows 和 Ubuntu 都不差 8 小时要么让 Windows 使用 UTC 硬件时钟要么让 Ubuntu 使用本地时间硬件时钟。两种方案都能用但团队统一时最好选一种不然换一台机器就蒙。服务器一般没有 Windows 双系统问题但虚拟机模板复制后时区错乱很常见克隆完先统一时区。WSL 里的 Ubuntu 时间同步更特殊。WSL 和 Windows 宿主共享内核时间通常不需要你在 WSL 里跑完整 NTP 服务。较新的 WSL 支持 systemd但时间来源仍受宿主影响。如果 WSL 里时间漂了先看 Windows 宿主时间是否正常再重启 WSL 实例往往比在 WSL 里装 chrony 更有效。如果你在 WSL 里开发、跑容器、看日志时间差几分钟就会让构建缓存和证书校验出问题所以宿主时间必须先准。开发板挂载 Ubuntu、Ubuntu 开发 Zephyr 这类场景也一样交叉编译环境的时间不准可能影响文件时间戳和签名。3. 桌面和轻量服务器首选用 systemd-timesyncd 开启 NTP3.1 安装、启用并设置自动同步Ubuntu 桌面版和大多数 Server 安装都自带 systemd-timesyncd。先确认包在不在dpkg -l | grep systemd-timesyncd。如果没有安装命令是sudo apt update sudo apt install systemd-timesyncd -y。安装后启用并立即启动sudo systemctl enable --now systemd-timesyncd。然后关键一步是打开自动同步开关sudo timedatectl set-ntp true。这两步经常被混淆systemctl enable --now是让服务跑起来timedatectl set-ntp true是告诉 systemd 允许 NTP 同步。完成之后再看timedatectl理想输出是$ timedatectl Local time: 四 2025-01-16 10:30:00 CST Universal time: 四 2025-01-16 02:30:00 UTC RTC time: 四 2025-01-16 02:30:00 Time zone: Asia/Shanghai (CST, 0800) System clock synchronized: yes NTP service: active RTC in local TZ: noSystem clock synchronized: yes可能需要等几秒到几十秒。如果一直是 no先别急着改配置按后面的排查顺序看服务日志。NTP service: active说明 systemd 层面已经允许同步但不代表已经同步成功。RTC in local TZ: no是我推荐的服务器设置。桌面用户如果和 Windows 双系统可以按需调整。3.2 配置 /etc/systemd/timesyncd.confNTP 和 FallbackNTP 怎么写systemd-timesyncd 的配置文件很简洁。用sudo nano /etc/systemd/timesyncd.conf打开常见内容如下[Time] NTPntp.aliyun.com cn.pool.ntp.org FallbackNTPntp.ubuntu.com time.google.com RootDistanceMaxSec5 PollIntervalMinSec32 PollIntervalMaxSec2048NTP是首选上游可以写多个用空格分隔。FallbackNTP是首选都不可用时的备用。RootDistanceMaxSec表示允许的最大根距离默认 5 秒一般够用。PollIntervalMinSec和PollIntervalMaxSec控制轮询间隔默认值已经比较合理除非你有特殊需求否则不建议乱改。公共 NTP 服务尽量写域名而不是固定 IP域名后面可以换 IP服务端调度也更灵活。选上游时有个原则优先选网络近的、稳定的。国内环境常用ntp.aliyun.com、cn.pool.ntp.org、ntp.tencent.com等如果你有内网 NTP 服务器优先写内网地址。不要一次写十几个公共服务器客户端不会因此更准反而增加网络抖动。两到四个上游足够。FallbackNTP可以留系统默认也可以换成你信任的地址。改完配置后重启服务sudo systemctl restart systemd-timesyncd。然后看状态systemctl status systemd-timesyncd --no-pager。如果日志里显示Contacted time server或Initial synchronization说明已经在工作。配置文件里不要用 chrony 的语法比如pool、iburstsystemd-timesyncd 不认。看到别人写server ntp.aliyun.com iburst就照抄进来服务会直接报错。3.3 重启服务并验证同步结果验证同步不能只看服务 active。依次跑sudo systemctl restart systemd-timesyncd timedatectl timedatectl show-timesync --all journalctl -u systemd-timesyncd -n 50 --no-pagertimedatectl show-timesync --all会输出ServerName、ServerAddress、PollIntervalUSec、NTPMessage等字段。看到ServerName有值说明已经选中了上游。journalctl里能看到时间同步的详细过程包括解析域名、连接服务器、调整时钟。如果只看到Starting Network Time Synchronization...但没有后续可能是网络还没就绪或者 UDP 123 被挡了。有时候timedatectl显示 synchronized 是 yes但show-timesync里ServerName为空。这可能是刚刚同步完成但状态还没刷新等一会儿再看。也有可能是系统时钟被其他工具校正过但 timesyncd 本身没有完成一次完整同步。排错时以日志和show-timesync为准不要只凭一个字段下结论。重启服务后至少等 30 秒再判断。3.4 手动强制校时与日志查看systemd-timesyncd 没有 chrony 那种makestep手动命令但你可以通过重启服务触发一次新的同步。如果偏差特别大比如差了几小时systemd-timesyncd 通常会直接步进因为初始偏差超过阈值。手动临时校时可以用sudo date -s 2025-01-16 10:30:00但这只是应急改完还要让 NTP 接管。更稳妥的是先确认时区再重启 timesyncd让它自己拉回来。手动改时间容易忘记时区也容易和硬件时钟脱节。日志查看重点是这几类信息Resolved看域名解析Connecting看网络连接Contacted看是否联系上服务器Adjtime看调整量。如果看到Failed to send NTP request通常是网络或防火墙问题如果看到No suitable server可能是配置的域名不可达或返回异常。Ubuntu 的日志时间本身可能因为时间不准而看起来混乱这时候可以先用journalctl --since 10 min ago缩小范围。还有一个细节systemd-timesyncd的同步状态会写入/run/systemd/timesync/synchronized之类的运行时文件重启后重新判断。不要为了“强制同步”去删这些文件没意义。要看真实状态用timedatectl和show-timesync。如果你在容器里看到 NTP 服务先确认容器有没有权限调整宿主机时间绝大多数容器不应该自己跑 NTP 客户端时间由宿主机统一提供。3.5 这个方案的适用边界和注意事项systemd-timesyncd 适合桌面、笔记本、轻量服务器、只想自动校时的普通用户。它轻量、默认集成、配置简单和 systemd 网络等待机制配合好。但它也有边界它主要做客户端不能作为 NTP 服务端给别的设备提供时间功能比 chrony 少不支持复杂的访问控制、本地 stratum、漂移文件管理对网络频繁中断的场景chrony 通常更稳。如果你要给海康摄像机、开发板、其他服务器提供校时直接在 Ubuntu 上用 systemd-timesyncd 不够需要换 chrony 或额外服务。另一个注意点是不要同时启用 chrony 和 systemd-timesyncd。如果你决定用 chrony先sudo systemctl disable --now systemd-timesyncd必要时sudo systemctl mask systemd-timesyncd防止被依赖拉起。反过来如果你只想用 timesyncd就卸载或停用 chrony。Ubuntu 上时间同步服务冲突的表现不一定是报错可能是两个服务轮流改时间日志里看到相近时间点多次调整排查起来很烦。最后timedatectl set-ntp true在部分定制系统里可能被策略覆盖。如果执行后NTP service还是 inactive检查是否有其他配置管理工具接管了时间服务。桌面用户很少遇到服务器自动化环境可能遇到。我的建议是在变更前记录一份timedatectl和两个服务状态的输出改完后再对比出问题好回滚。4. 长期跑服务器更推荐chrony 客户端配置与内网 NTP 服务4.1 安装 chrony 并处理与 timesyncd 的冲突服务器、长期开机的开发机、需要做内网时间源的 Ubuntu我更推荐 chrony。安装命令sudo apt update sudo apt install chrony -y安装过程中apt 可能会提示你处理/etc/chrony/chrony.conf的配置冲突。如果你之前改过先备份原文件sudo cp /etc/chrony/chrony.conf /etc/chrony/chrony.conf.bak。安装完成后先停用 systemd-timesyncdsudo systemctl disable --now systemd-timesyncd sudo systemctl mask systemd-timesyncdmask不是必须但能防止其他服务依赖把它拉起来。然后启用 chronysudo systemctl enable --now chrony检查状态systemctl status chrony --no-pager。如果 chrony 启动失败常见原因是配置文件语法错误、UDP 123 被占用、或者旧 NTP 服务还在跑。用sudo ss -lunp | grep 123看谁占着 123。chrony 客户端不一定监听 123但如果要做服务端必须监听。chronyd和ntpd不要同时跑。4.2 chrony.conf 关键参数逐行说明chrony 的配置文件在/etc/chrony/chrony.conf。一个适合 Ubuntu 客户端加内网服务端的配置可以这样写# 上游时间源iburst 表示启动时快速发几个包加快首次同步 pool ntp.aliyun.com iburst server ntp.tencent.com iburst server cn.pool.ntp.org iburst # 记录时钟漂移率重启后能更快收敛 driftfile /var/lib/chrony/chrony.drift # 把系统时间同步到硬件时钟 rtcsync # 前三次校时如果偏差超过 1 秒直接步进之后只用 slewing 慢调 makestep 1.0 3 # 允许内网网段作为客户端来同步 allow 192.168.1.0/24 # 当所有上游都不可用时本机仍以 stratum 10 对外提供时间 local stratum 10 # 日志目录排错时很有用 logdir /var/log/chronypool和server的区别pool表示一组服务器chrony 会从中选几个server指定单个服务器。iburst很重要它让 chrony 启动时快速发送多个请求而不是慢慢等轮询间隔首次同步从几分钟缩短到几秒。driftfile记录晶振漂移长期运行后时间会更稳。rtcsync在 Linux 上会定期把系统时间同步到 RTC双系统用户要注意 RTC 标准是否一致。makestep 1.0 3是很多人关心的参数。它的意思是在启动后的前三次时钟更新中如果偏差超过 1 秒就直接步进调整三次之后即使偏差很大也只做 slewing不再跳变。这样既能让刚启动的服务器快速校准又能避免运行中时间突然跳变影响业务。如果你的服务器对时间连续性要求极高可以把3改成0只在启动阶段允许步进但首次同步可能会很慢。反过来如果只是测试机想随时强制步进可以用chronyc makestep手动触发。allow 192.168.1.0/24是服务端配置。只有写了allowchrony 才会响应这个网段的客户端请求。local stratum 10表示当上游全部失联时本机仍然以 stratum 10 对外服务。stratum 越小越接近源头10 是一个常用的“本地兜底”层级。注意local stratum不是让你伪造时间而是在上游不可用时维持一个可用的时间源避免内网设备完全失去校时能力。上游恢复后chrony 会自动回到正常层级。4.3 启动、放行防火墙、验证 sources 和 tracking改完配置后重启 chronysudo systemctl restart chrony sudo systemctl status chrony --no-pager如果这台 Ubuntu 还要给内网提供 NTP 服务放行 UDP 123sudo ufw allow from 192.168.1.0/24 to any port 123 proto udp sudo ufw reload验证客户端同步状态最常用的是chronyc sources -v chronyc tracking chronyc sourcestats -vchronyc sources -v会列出上游服务器前面的符号很关键。^*表示当前选中的最佳同步源^表示备选源^-表示被排除但可用的源^?表示连接失败或还没判定。看到^*才说明有明确的主同步源。chronyc tracking会显示Reference ID、Stratum、System time、Last offset、RMS offset、Frequency等。System time是当前偏差刚开始可能几百毫秒稳定后会降到毫秒甚至微秒级。如果是服务端还要确认它监听 123sudo ss -lunp | grep 123。看到chronyd监听0.0.0.0:123或具体网卡地址就对了。然后用另一台机器测试chronyc -h 192.168.1.10 sources或配置客户端指向它。也可以用ntpdate -q 192.168.1.10但新系统可能没有 ntpdate。chrony 自带的chronyc更可靠。服务端日志在/var/log/chrony/下排错时看tracking.log、measurements.log。4.4 把 Ubuntu 变成局域网 NTP 服务器给摄像机等设备校时很多内网设备只支持 NTP 客户端比如海康摄像机、录像机、开发板、旧服务器、Windows Server 2008 等。它们的校时步骤通常类似进入网络设置或时间设置选择 NTP 同步填写 NTP 服务器地址端口 123时区选对保存后等待。你在一台稳定的 Ubuntu 上搭好 chrony 服务端把这些设备的 NTP 地址指向 Ubuntu 的局域网 IP就能统一内网时间。海康摄像机时间同步步骤里最关键的不是点哪个菜单而是摄像机能不能访问到 Ubuntu 的 UDP 123以及摄像机自己的时区是否设置正确。服务器地址不要填公网域名填 Ubuntu 的局域网 IP例如192.168.1.10。如果 Ubuntu 有多个网卡确认摄像机所在网段能路由到对应地址。防火墙只放行摄像机网段比如allow 192.168.1.0/24。如果摄像机时间还是不对先看时区很多摄像机默认时区是 UTC8但如果你的 Ubuntu 服务端返回 UTC摄像机自己换算时区错就会差小时。NTP 本身不传时区只传 UTC所以每个客户端都要自己设对时区。Ubuntu 作为内网 NTP 服务端时上游可以选择公共 NTP 或更上级的内网 NTP。不要把它当成绝对时间源除非你有 GPS 或原子钟。它只是把上游时间转发给内网并做本地兜底。如果内网完全隔离没有上游可以用local stratum 10让 Ubuntu 自己维持时间但长期看晶振会漂重要环境还是要有可靠上游。对于普通办公网、摄像机、开发板chrony 客户端加服务端的方式已经足够。4.5 chrony 调优参数iburst、makestep、rtcsync、local stratumiburst适合所有客户端尤其是虚拟机启动后时间偏差大的场景。它不影响长期精度只是加快初始同步。makestep 1.0 3适合大多数服务器对时间连续性极度敏感的业务可以收紧到makestep 0.1 3或只在启动时允许。但要注意阈值越小越容易触发步进日志里的时间跳变会更多。没有绝对最优只有适合你业务容忍度的值。rtcsync在 Linux 上启用内核的 11 分钟模式定期把系统时间同步到 RTC。它比每次手动hwclock -w更省心。但双系统用户要确保 RTC 标准一致。如果你的 Ubuntu 用 UTCWindows 也用 UTC那没问题如果 Windows 用本地时间Ubuntu 每次rtcsync后Windows 看到的时间就可能差 8 小时。解决方式是二选一别让两边各按各的理解走。local stratum 10是服务端兜底客户端不需要写。allow也是服务端配置客户端写了没用。bindaddress可以限制 chrony 监听哪个地址多网卡服务器可以只在内网网卡上提供服务。maxdistance、maxslewrate属于更细的调优普通场景不要乱动。我的经验是先把上游选对、防火墙放行、服务端 allow 写好时间同步就能稳定调优参数等遇到具体问题再改不要一开始就抄一堆网上配置。4.6 什么时候该考虑 PTP 而不是 NTPNTP 的典型精度是毫秒级局域网内做好可以到亚毫秒但受网络和软件时间戳限制很难稳定到微秒以下。PTP 即精确时间协议配合支持硬件时间戳的网卡和交换机可以达到亚微秒甚至纳秒级。工业控制、金融交易、测试测量、音视频同步等场景会考虑 PTP。普通服务器日志、数据库、摄像机校时、开发环境NTP 完全够用。不要因为看到“PTP 时间同步”这个词就觉得 NTP 不行选型要看业务精度需求。PTP 需要网络设备配合配置也更复杂。Ubuntu 上可以用linuxptp等工具但前提是硬件支持。很多虚拟机、普通家用网卡、普通交换机不适合跑 PTP。我的建议是先问业务到底需要多准。如果只是日志排序、证书校验、定时任务NTP 毫秒级已经足够如果设备说明书明确要求 PTP再单独规划。把 NTP 和 PTP 混在一台机器上跑需要非常小心时钟源之间可能互相干扰。5. 常见故障排查从“同步不上”到“时间乱跳”5.1 排查顺序先看服务再看网络再看上游时间同步不生效最忌讳一上来就改配置文件。我的排查顺序是第一步timedatectl和systemctl status确认哪个服务在跑、NTP 是否启用第二步journalctl或 chrony 日志看服务有没有报错第三步ss -lunp | grep 123看端口和进程第四步测网络DNS、路由、UDP 123 是否可达第五步看上游服务器是否可用换一个上游对比第六步看时区和 RTC 设置。按这个顺序走大多数问题能在十分钟内定位。如果服务 active 但 synchronized 是 no重点看日志里的“联系不上”还是“没有合适服务器”。journalctl -u systemd-timesyncd -n 100 --no-pager和journalctl -u chrony -n 100 --no-pager能给出明确线索。chrony 用户还要看chronyc sources -v如果全是^?说明上游都没连上如果有一个^*但tracking里 offset 很大可能刚启动等一会儿再观察。5.2 timedatectl 显示 no 的八种原因第一种NTP 服务没启用NTP service: inactive执行sudo timedatectl set-ntp true。第二种服务没安装或没启动检查systemctl status systemd-timesyncd。第三种DNS 解析失败配置的 NTP 域名解析不了换 IP 或检查/etc/resolv.conf。第四种UDP 123 被防火墙挡住检查 ufw、云安全组、公司网络策略。第五种上游服务器不可达换ntp.aliyun.com、cn.pool.ntp.org测试。第六种系统刚启动网络还没就绪等几十秒再看。第七种时间和时区错得太离谱服务还没完成首次同步。第八种有另一个时间服务或虚拟机工具在抢着改时间停用冲突服务再观察。还有一种容易忽略timedatectl set-ntp true执行成功但系统使用了只读文件系统或容器环境运行时状态写不进去。容器里通常不应该自己跑 NTP时间由宿主机提供。如果你在 Docker 容器里看到时间不对优先检查容器是否共享宿主时间而不是在容器里装 chrony。Kubernetes 环境同理节点时间同步才是重点。5.3 chronyc sources 里的符号怎么读chronyc sources -v的输出里M列表示模式S列表示状态*表示当前最佳源表示备选-表示被排除?表示未连接或未判定x表示认为是错误源。看到^*最放心。如果只有^说明有可用源但还没选为主源通常再等一会儿。如果全是^?检查网络、DNS、防火墙和上游地址。chronyc tracking里的Last offset是最近一次测量的偏差RMS offset是长期均方根偏差Frequency是本地时钟频率偏差单位 ppm。Stratum是层级越小越接近源头。Reference ID是上游标识。刚开始System time可能是几百毫秒稳定后应该降到几毫秒以内。如果长期几百毫秒可能是上游太远、网络抖动大或者你选了一个不稳定的公共服务器。5.4 时间跳变、漂移和日志线索时间跳变一般发生在makestep触发时尤其是启动后前三次同步。日志里会写System clock was stepped by ...。这是正常的但如果你在业务高峰期看到跳变就要调整makestep策略。时间漂移则是慢慢偏离chrony 会通过调整频率补偿。如果漂移很大可能是硬件时钟晶振问题、虚拟机挂起恢复、或者负载太高影响计时。虚拟机里时间漂移尤其常见挂起再恢复后偏差可能很大需要让 chrony 做一次 makestep。日志线索方面systemd-timesyncd 看journalctl -u systemd-timesyncdchrony 看/var/log/chrony/tracking.log、measurements.log、statistics.log。如果tracking.log里 offset 一直很大先换上游如果 offset 周期性变大变小可能是网络拥塞如果 frequency 异常高可能是时钟硬件或虚拟化问题。日志时间本身不准时可以用journalctl --since和--until缩小范围。5.5 常见问题速查表现象可能原因排查命令处理System clock synchronized: noNTP 未启用、服务未跑、网络不通timedatectl、systemctl status systemd-timesyncd启用服务timedatectl set-ntp trueNTP service: inactive自动同步开关关闭timedatectlsudo timedatectl set-ntp true时间差 8 小时时区错误或 RTC 标准冲突timedatectl、date设置Asia/Shanghai统一 RTC 为 UTC重启后时间恢复错误硬件时钟未同步timedatectl、hwclock --show启用rtcsync或手动hwclock -wchrony 全是^?DNS、UDP 123、上游不可达chronyc sources -v、nc -u -z换上游检查防火墙和网络服务端不响应其他机器未写allow或防火墙没放行ss -lunpgrep 123、ufw status虚拟机时间漂移挂起恢复、增强工具冲突chronyc tracking允许 chrony makestep关闭外部强制同步双系统时间差 8 小时Windows 和 Ubuntu 对 RTC 理解不同timedatectl看RTC in local TZ统一为 UTC 或本地时间二选一WSL 时间漂移宿主时间不准或 WSL 挂起Windows 时间设置校准宿主重启 WSL容器内时间不对容器不应自己跑 NTPdate、cat /etc/localtime检查宿主机和容器时间共享6. 实操心得与几条硬建议6.1 不要一上来就 date -s先看同步状态我见过太多人时间不对就date -s改完看起来好了过一会儿又漂了然后开始怀疑 NTP 坏了。实际上date -s只是改了系统时钟没有解决时区、硬件时钟、同步服务的问题。正确做法是先看timedatectl确认时区、NTP 开关、RTC 标准再看服务日志。真要手动校时也只在紧急情况下用并且之后必须让 NTP 服务接管。否则手工设置的时间会随着晶振漂移再次偏离问题只是被暂时掩盖。另一个坏习惯是同时装多个时间服务。systemd-timesyncd、chrony、ntpd不要一起跑。选一个停用其他。Ubuntu 默认用 timesyncd你装了 chrony 后最好明确停用 timesyncd并检查systemctl status chrony。如果两个都 active日志里会看到反复调整排错难度翻倍。服务器上时间服务属于基础服务配置要干净不要留互相冲突的组件。6.2 公共 NTP 服务器怎么选内网怎么分层公共 NTP 服务器不要贪多。写两到四个可靠的就够优先选网络近的。国内常用ntp.aliyun.com、ntp.tencent.com、cn.pool.ntp.org等。企业内网最好自建一层 NTP一台能访问上游的 Ubuntu 跑 chrony 服务端其他服务器和网络设备指向它它再向上游同步。这样出口流量少内网设备校时统一排查也简单。摄像机、录像机、开发板、旧 Windows Server 都可以作为客户端指向这台 Ubuntu。分层时注意 stratum 概念。直接同步公网的服务器是 stratum 2 或 3 左右内网客户端同步它会变成 stratum 3 或 4。层级不是越少越好而是要可控。完全隔离的内网可以用local stratum 10兜底但它不是原子钟长期精度有限。重要环境还是要有可靠上游或者专用的时间源设备。普通办公环境用公共上游加内网 chrony 服务端已经能满足需求。6.3 把时间检查加入日常巡检时间同步不是配完就一劳永逸。虚拟机挂起、网络切换、防火墙变更、系统大版本升级都可能影响它。我习惯在巡检脚本里加几条timedatectl看 synchronizedchronyc tracking看 offsetsystemctl is-active chrony或systemd-timesyncd看服务状态ss -lunp | grep 123看服务端监听。对于内网 NTP 服务端再加一条检查chronyc clients看有没有客户端异常。发现偏移变大再处理比等业务报错要主动。如果你管理多台 Ubuntu可以用配置管理工具统一时间配置但不要把所有机器都指到同一个公共上游。至少两台内网 NTP 服务器做冗余客户端配置主备。systemd-timesyncd 支持NTP和FallbackNTPchrony 支持多个server或pool。冗余不是写越多越好而是选两三个稳定源让客户端自己能选。这样一台上游维护或故障时间同步不会中断。6.4 记录一次完整的校时过程最后分享一次我常用的完整流程适合新装 Ubuntu 或接手一台时间不准的机器# 1. 看现状 date timedatectl systemctl status systemd-timesyncd --no-pager || true systemctl status chrony --no-pager || true # 2. 设时区 sudo timedatectl set-timezone Asia/Shanghai # 3. 如果选 systemd-timesyncd sudo systemctl enable --now systemd-timesyncd sudo timedatectl set-ntp true sudo systemctl restart systemd-timesyncd timedatectl # 4. 如果选 chrony sudo apt update sudo apt install chrony -y sudo systemctl disable --now systemd-timesyncd sudo systemctl mask systemd-timesyncd sudo systemctl enable --now chrony sudo systemctl restart chrony chronyc sources -v chronyc tracking # 5. 如果要做内网服务端 sudo ufw allow from 192.168.1.0/24 to any port 123 proto udp sudo ss -lunp | grep 123 chronyc clients这套流程我在 Ubuntu 20.04、22.04、24.04 上都用过桌面和 Server 都适用。关键不是命令多复杂而是每一步都知道为什么做。先时区再服务再配置再验证最后做服务端放行。遇到时间不对先按排查顺序走不要乱改参数。时间同步稳定后日志、证书、数据库、定时任务都会少很多莫名其妙的毛病。