
1. 為什么你的服務器時間總是不準從NTP到Chrony的演進你有沒有遇到過這樣的場景服務器上部署的應用日志時間戳對不上排查問題時發現兩臺機器的時間差了十幾秒數據庫主從同步報錯一查是主庫和從庫的系統時間不一致甚至在做分布式事務或者依賴時間戳的加密認證時因為毫秒級的偏差導致整個流程失敗。這些問題根源往往都指向一個看似不起眼的基礎服務——系統時間同步。在Linux世界里提到時間同步老司機們第一時間會想到ntpdNetwork Time Protocol daemon。它確實是過去幾十年的行業標準像一位德高望重的老教授嚴謹、穩定但配置起來也略顯繁瑣對網絡波動和系統負載的適應性在今天看來有些“遲緩”。而chrony則可以看作是這位老教授培養出的“高徒”它繼承了NTP協議的精髓但在算法和實現上做了大量現代化改進。它更快、更精準尤其在虛擬化、云計算和移動網絡環境下表現突出。現在包括RHEL/CentOS 8、Fedora、Ubuntu等主流發行版都已經將chrony作為默認的時間同步服務。如果你還在用ntpd是時候了解一下這位“后起之秀”了。簡單來說chrony是一個更現代化的NTP協議實現它由兩個核心組件構成chronyd守護進程和chronyc命令行客戶端。chronyd在后臺運行負責與時間服務器通信、計算時間偏差并逐步調整系統時鐘chronyc則讓你可以隨時查詢同步狀態、手動調整或檢查時間源。它的設計目標很明確在保持高精度的同時更快地收斂到正確時間并且對間歇性網絡連接比如筆記本電腦合蓋休眠后喚醒和虛擬機的時鐘漂移有更好的處理能力。2. Chrony 核心工作機制它憑什么比NTPD更“聰明”要理解chrony的配置必須先搞懂它是怎么工作的。這不僅僅是改幾個配置文件參數那么簡單知其所以然才能在出問題時快速定位。2.1 時鐘的“性格”漂移與偏移每個計算機的硬件時鐘Real Time Clock, RTC也就是CMOS時鐘和由內核維護的系統時鐘都不是絕對準確的。它們受溫度、電壓、主板晶體振蕩器精度等因素影響會以一個相對穩定的速率變快或變慢這個速率就是時鐘漂移率clock drift。比如你的服務器時鐘可能每天會慢2秒。而時鐘偏移clock offset指的是當前系統時間與真實時間之間的瞬時差值。ntpd和chronyd的核心任務就是通過持續測量偏移量并估算出漂移率來“馴服”這臺不守時的機器。chrony的算法更激進一些。它采用了一種更復雜的濾波和選擇算法能夠更快地識別并丟棄不可靠的時間源樣本同時更積極地計算漂移率。這意味著在系統啟動后或者時間發生較大偏差時chrony能比ntpd更快地將系統時間調整到正確范圍。2.2 時間源的“選舉”與“信任”chronyd會同時向多個配置的NTP服務器時間源發送請求。它并不簡單地取平均值而是進行一場精密的“選舉”測量與篩選chronyd會持續測量到每個時間源的往返延遲delay和時間偏移offset。它會根據這些測量的穩定性和一致性為每個時間源計算一個“誤差范圍”和“權重”。層級與距離NTP服務器本身是分層的Stratum。Stratum 0是原子鐘、GPS時鐘等絕對時間源Stratum 1是直接連接Stratum 0的服務器Stratum 2從Stratum 1同步以此類推。chrony會優先選擇層級低數字小且網絡延遲小的服務器。真假源檢測這是chrony的一個強項。它通過交叉比對多個時間源能夠有效檢測并拒絕那些提供錯誤時間的“假”服務器可能是配置錯誤或惡意服務器。ntpd在這方面相對脆弱。組合時間最終chronyd會綜合所有“可信”時間源的信息計算出一個最優的“組合時間combined time”并以此為目標來調整本地時鐘。這個過程的細節都記錄在chronyd的內存狀態中我們可以通過chronyc命令來窺探。理解了這個過程你就會明白為什么配置文件里pool、server指令后面可以跟minpoll、maxpoll、iburst這些參數它們直接影響了測量行為的頻率和積極性。2.3 調整方式 “猛藥”還是“溫補”當發現時間偏差時有兩種調整方式步進調整Step如果時間偏差超過一個閾值默認是1000秒chronyd會直接“跳變”時鐘。這就像發現手表慢了半小時直接擰到正確時間。在生產環境中巨大的時間跳變可能導致依賴連續時間的應用如數據庫事務日志出錯所以這個閾值需要謹慎設置。漸進調整Slew如果偏差在閾值之內chronyd會通過加快或減慢系統時鐘的“滴答”頻率讓時間逐漸“滑”到正確位置。這是默認且推薦的方式對應用無感。chrony的漸進調整算法更平滑允許在短時間內補償更大的偏移量這也是它收斂速度快的原因之一。3. 從零開始一份詳盡的Chrony配置指南理論說再多不如動手配一遍。我們假設你正在配置一臺新的CentOS 8或Rocky Linux 8服務器其默認已安裝chrony。3.1 安裝與基礎狀態檢查首先確認chrony是否已安裝并運行# 檢查安裝包 rpm -q chrony # 或使用dnf/yum dnf list installed chrony # 檢查服務狀態 systemctl status chronyd # 如果未安裝則安裝 dnf install -y chrony啟動并設置開機自啟systemctl enable --now chronyd現在用chronyc看看初始狀態chronyc sources -v這個命令會列出所有配置的時間源。初始狀態下它可能使用的是發行版預置的pool.ntp.org池地址。-v參數會顯示詳細信息包括狀態^*表示當前選中的同步源^表示可用的候選源^?表示未連接或狀態未知、層數、精度等。3.2 解剖配置文件/etc/chrony.conf主配置文件/etc/chrony.conf的每一行都至關重要。我們分段解讀。第一部分時間源配置這是核心告訴chronyd向誰同步。# 使用pool指令指向一個NTP服務器池。系統會從池中自動選擇多個服務器。 pool 2.rocky.pool.ntp.org iburst # 或者使用server指令指定具體的服務器。可以指定多個。 server ntp1.aliyun.com iburst server ntp2.aliyun.com iburst server time.cloudflare.com iburst # 如果在內網有自建的、更精確的NTP服務器如連接GPS的硬件時鐘優先使用。 server 192.168.1.100 iburst preferpoolvsserver:pool指向一個域名該域名背后是多個服務器地址可以實現負載均衡和自動故障轉移是推薦做法。server用于指定確定的單個服務器。iburst一個非常重要的選項。當服務啟動或服務器不可達后首次恢復時chronyd會發送一連串通常是4-8個數據包來快速完成初始測量極大加速初始同步過程。建議始終為每個server或pool條目加上iburst。prefer標記為“首選”服務器。chronyd會給予這個源更高的權重但最終選擇仍基于算法。通常用于內網中更穩定、延遲更低的時間源。minpoll和maxpoll定義輪詢間隔的最小和最大值以2的冪秒為單位。默認是minpoll 664秒和maxpoll 101024秒約17分鐘。在網絡穩定、追求高精度的內網環境中可以適當減小maxpoll例如maxpoll 8256秒。注意過于頻繁的查詢可能會被公共NTP服務器視為濫用請尊重上游服務器策略。第二部分時間調整策略# 允許系統時鐘在前1000秒的偏差內進行漸進調整超過則步進調整。 makestep 1000 3 # 啟用RTC硬件時鐘的內核同步。 rtcsyncmakestep 1000 3這是時間校正策略。1000是閾值秒3是前3次更新的限制。意思是在前3次時鐘更新中如果偏差超過1000秒就步進調整之后無論偏差多大都只用漸進調整。生產環境建議如果你的服務器可能因長時間關機產生巨大偏差但又擔心步進調整影響應用可以將閾值調小如makestep 1.0 -1。-1意味著永遠允許步進調整但1.0秒的閾值使得只有非常大的偏差才會觸發步進通常應用能容忍1秒的跳變。更保守的做法是makestep 0.1 -1只允許0.1秒以上的偏差進行步進但這要求服務器時間基本保持在線。rtcsync這個指令讓chronyd定期每11分鐘將系統時間同步到硬件時鐘RTC。這非常重要可以確保服務器重啟后系統時間從一個相對準確的值開始。務必啟用。第三部分訪問控制與網絡# 允許哪些網絡查詢本機時間如果本機想作為NTP服務器 # allow 192.168.1.0/24 # 監聽網絡端口作為服務器時 # bindcmdaddress 0.0.0.0 # local stratum 10默認情況下chronyd只監聽本地回環地址127.0.0.1。如果你需要讓這臺服務器為內網其他機器提供時間服務需要取消注釋并修改allow和bindcmdaddress。local stratum 10當所有配置的外部時間源都不可用時chronyd可以將自己聲明為一個層數為10的本地時間源。這樣內網中其他配置了此服務器為源的客戶端在外部網絡中斷時仍然能在一個小的局域網內保持時間同步雖然可能逐漸漂移。這在隔離網絡中有用。第四部分其他關鍵指令# 指定存儲漂移率記錄的文件。chronyd通過它來記住你的時鐘“通常跑多快/多慢”。 driftfile /var/lib/chrony/drift # 啟用內核的硬件時間戳支持可以大幅提高局域網內時間同步的精度達到亞微秒級。 # 需要網卡和驅動支持。 hwtimestamp * # 記錄客戶端訪問日志如果作為服務器 # logdir /var/log/chronydriftfile這個文件記錄了系統計算出的時鐘漂移率。不要刪除或隨意修改這個文件。chronyd依靠它來在重啟后快速應用已知的漂移率加速收斂。hwtimestamp對于金融交易、高性能計算等對時間精度要求極高的場景這是“神器”。它利用網卡硬件為網絡數據包打上精確的時間戳繞過了操作系統協議棧的延遲。啟用前需確認網卡支持。3.3 配置實戰針對典型場景的配置模板場景一標準公有云服務器目標快速、穩定同步使用國內優質公共NTP源。# /etc/chrony.conf server ntp.aliyun.com iburst server ntp1.tencent.com iburst server cn.pool.ntp.org iburst server time.apple.com iburst # 作為備用質量通常很好 driftfile /var/lib/chrony/drift makestep 1.0 -1 rtcsync keyfile /etc/chrony.keys leapsectz right/UTC logdir /var/log/chrony修改后務必重啟服務systemctl restart chronyd場景二內網時間服務器母鐘假設你有一臺能訪問外網的服務器192.168.1.10要為整個內網192.168.1.0/24提供時間服務。 在這臺服務器上配置# /etc/chrony.conf # 上游源 server ntp.aliyun.com iburst server time.cloudflare.com iburst # 允許內網訪問并聲明自己為第3層服務器如果上游是第2層 allow 192.168.1.0/24 local stratum 3 # 監聽所有網絡接口 bindcmdaddress 0.0.0.0 driftfile /var/lib/chrony/drift makestep 1.0 -1 rtcsync在內網其他客戶端服務器上配置# /etc/chrony.conf server 192.168.1.10 iburst prefer # 指向內網時間服務器并標記為首選 # 可選增加一個外部源作為備份防止母鐘完全失效 server ntp.aliyun.com iburst driftfile /var/lib/chrony/drift makestep 1.0 -1 rtcsync4. 運維與排障用chronyc命令洞察一切配置好了不是結束日常運維和問題排查才是關鍵。chronyc是你的瑞士軍刀。4.1 監控同步狀態你必須知道的幾個命令chronyc tracking查看時間同步的核心指標。chronyc tracking輸出類似Reference ID : C0A8010A (192.168.1.10) # 當前同步的源ID Stratum : 3 # 層數越小越好1最佳 Ref time (UTC) : Thu Apr 10 08:00:00 2024 # 源報告的UTC時間 System time : 0.000123456 seconds fast of NTP time # 系統時間偏移量 Last offset : 0.000123456 seconds # 最后一次測量的偏移 RMS offset : 0.000012345 seconds # 偏移量的長期平均值均方根 Frequency : 16.234 ppm slow # 時鐘漂移率正數表示慢 Residual freq : 0.001 ppm # 剩余頻率誤差 Skew : 0.123 ppm # 頻率誤差的估計界限 Root delay : 0.012345 seconds # 到根時間源的總延遲 Root dispersion : 0.001234 seconds # 到根時間源的累積誤差 Update interval : 64.0 seconds # 最后兩次更新的間隔 Leap status : Normal # 閏秒狀態重點關注Stratum應在合理范圍如1-5System time和Last offset絕對值應非常小理想情況在毫秒甚至微秒級Frequency顯示你的硬件時鐘天生跑得快還是慢。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, ~ time too variable. || .- xxxx [ yyyy ] /- zzzz || Reachability register (octal) -. | xxxx adjusted offset, || Log2(Polling interval) --. | | yyyy measured offset, || \ | | zzzz estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample ^* 192.168.1.10 3 6 377 45 -123us[-456us] /- 12ms ^ time.cloudflare.com 2 6 377 46 456us[789us] /- 9ms ^- ntp.aliyun.com 1 6 377 47 -987us[-321us] /- 15ms第一列符號^*是當前同步源^是好的備用源^-是候選源但未被選中^?表示源不可達或狀態未知。Reachability register (octal)一個8進制的數表示最近8次查詢的成功/失敗歷史成功為1失敗為0。377二進制11 111 111表示最近8次全部成功連接非常健康。0或很小的值表示連接有問題。Last sample-123us[-456us] /- 12ms。第一個數字-123us是調整后的偏移量第二個方括號內的數字-456us是原始測量偏移量/- 12ms是估計誤差。偏移量在毫秒ms甚至微秒us級別是正常的。chronyc sourcestats -v查看時間源的統計信息如偏移、延遲的標準差幫助你判斷源的穩定性。chronyc activity查看有多少時間源在線、離線等概要信息。4.2 手動干預與調試命令手動立即同步chronyc makestep。有時你想立刻糾正時間可以運行此命令。但注意如果偏差超過makestep閾值這會導致步進調整。手動添加/刪除時間源臨時生效重啟服務后失效chronyc add server ntp.newserver.com iburst chronyc delete server ntp.badserver.com檢查NTP服務器是否可達chronyc ntpdata server-ip可以顯示從該服務器獲取的原始NTP數據包信息用于深度調試。4.3 常見問題與排障思路問題1chronyc sources顯示所有源都是^?不可達。檢查網絡ping ntp.aliyun.com是否通防火墻是否放行了UDP 123端口出站對于客戶端出站規則需要允許udp/123。檢查DNS如果使用域名檢查dig ntp.aliyun.com是否能解析。檢查服務狀態systemctl status chronyd確認服務正在運行。問題2時間同步了但偏移量offset始終很大幾十到幾百毫秒。網絡延遲高檢查chronyc tracking中的Root delay。如果超過100ms可能是網絡路徑不佳。嘗試更換延遲更低的時間源。系統負載高在系統負載極高時chronyd進程可能無法獲得足夠的CPU時間來進行精確測量。檢查系統負載uptime和chronyd進程的CPU使用率。虛擬機時鐘問題虛擬機特別是KVM、VMware的虛擬時鐘可能不穩定。確保安裝了VMware Tools或VirtualBox Guest Additions并啟用時間同步功能。對于KVM可以考慮在宿主機和客戶機都使用chrony并配置/etc/chrony.conf中的rtcsync和更積極的makestep參數。有時在虛擬機中需要禁用ntpd或timesyncd避免多個時間服務沖突。問題3chronyc tracking顯示Stratum很大比如16。所有時間源都丟失這意味著chronyd無法與任何配置的上游服務器通信并且local stratum指令也未啟用或生效。它會將自己標記為未同步的層16時鐘。檢查網絡和源配置。local stratum未生效如果你希望在沒有外部源時作為本地源確保配置了local stratum 10或其他數字非16并且allow了客戶端網段。問題4時間同步服務與其他服務沖突。與systemd-timesyncd沖突一些較新的發行版如Ubuntu 16.04默認使用systemd-timesyncd進行輕量級時間同步。如果安裝了chrony務必禁用systemd-timesyncdsystemctl stop systemd-timesyncd systemctl disable systemd-timesyncd。與ntpd沖突兩者不能同時運行。使用systemctl stop ntpd systemctl disable ntpd禁用ntpd。5. 進階話題與生產環境實踐5.1 虛擬化環境下的時間同步挑戰在VMware、KVM、Hyper-V等虛擬化環境中虛擬機的時鐘是個“老大難”問題。虛擬機的時鐘依賴于宿主機的時鐘和CPU的計時器如TSC在虛擬機被調度休眠或宿主負載高時虛擬時鐘容易發生“漂移”甚至“跳變”。最佳實踐組合拳宿主機層面確保宿主機自身的時間同步是精準和穩定的。在宿主機上配置chrony使用可靠的外部源并啟用hwtimestamp如果硬件支持。虛擬機工具務必安裝并運行VMware Tools、VirtualBox Guest Additions或KVM的virtio驅動。這些工具提供了與宿主機時鐘同步的“準虛擬化”接口比純粹模擬的硬件時鐘穩定得多。客戶機配置在虛擬機內chrony配置需要更“激進”。減小maxpoll增加同步頻率例如maxpoll 664秒。調整makestep使用makestep 0.1 -1允許對超過0.1秒的偏差進行步進調整。對于虛擬機小的步進調整亞秒級通常比大的漸進漂移對應用影響更小。禁用其他同步源確保虛擬機內只運行chronyd并禁用任何由虛擬化平臺注入的舊式時間同步如VMware的tp服務。考慮使用chrony的smoothtime功能實驗性它可以嘗試平滑處理來自虛擬化工具的時間更新減少跳變感。5.2 容器與Kubernetes中的時間容器共享宿主機的內核因此也共享系統時鐘。容器內部無法運行chronyd來獨立調整時間。這意味著宿主機時間必須準確所有運行容器的宿主機節點其時間必須通過chrony或其他方式保持高度同步。在K8s集群中這是節點準備的基本要求。容器內應用的處理如果你的容器化應用對時間極其敏感需要考慮在應用層面使用NTP客戶端庫如ntplib直接查詢外部NTP服務器但這會增加復雜性和網絡依賴。更常見的做法是確保宿主機時間可靠并信任它。5.3 閏秒處理閏秒是偶爾被添加到協調世界時UTC中的一秒以補償地球自轉的微小變化。chrony默認知道如何處理閏秒。chronyc tracking輸出中的Leap status字段會顯示狀態Normal、Leap second等。chrony支持兩種處理方式在閏秒時刻通過step跳秒或slew在更長時間內微調時鐘頻率來消化這一秒。現代Linux內核和chrony的默認配合通常是平滑處理。對于金融交易等極端場景需要關注閏秒公告并進行測試。可以通過chronyc leapsectz查看配置的時區閏秒信息。5.4 安全考慮認證chrony支持使用對稱密鑰keyfile進行NTP消息認證防止中間人攻擊或惡意NTP服務器。這在嚴格的內網安全要求中可能需要配置。服務暴露除非必要不要將chronyd綁定到公網IPbindcmdaddress 0.0.0.0。如果作為內網時間服務器使用防火墻嚴格限制訪問源IPallow指令是第一道防線但結合主機防火墻如firewalld或iptables是更佳實踐。6. 從理論到實踐一次完整的時間偏差排查實錄最后分享一個我最近遇到的實際案例。監控報警顯示某臺運行Java應用的服務器其日志時間與日志收集中心的時間存在約5秒的固定偏差。第一步快速確認問題登錄服務器先用date命令查看系統時間同時用curl訪問一個提供精確時間的API如http://worldtimeapi.org/api/timezone/Etc/UTC進行對比確認偏差確實存在。第二步檢查chrony狀態chronyc tracking發現System time顯示5.123456 seconds fast。說明chronyd已經意識到了這5秒的偏差。第三步分析時間源chronyc sources -v發現當前同步源^*的Reach值是177二進制01 111 111表示最近8次中有7次成功有一次失敗。Last sample的誤差/-值較大達到/- 100ms。而另一個備用源^的Reach是377全成功誤差只有/- 10ms。這說明當前選中的源質量不穩定。第四步深入探查與干預為什么chronyd不切換到更好的源運行chronyc sourcestats查看歷史統計發現當前源雖然最近有一次失敗但其歷史測量的偏移標準差Std dev很小而備用源雖然當前延遲低但過去一段時間偏移波動較大。chrony的算法更傾向于長期穩定的源這是合理的但也導致了當前偏差無法快速糾正。第五步手動干預與驗證由于業務對時間敏感我決定手動干預。首先嘗試讓chronyd立即重新評估并同步chronyc makestep。但偏差5秒超過了默認的makestep 1000 3閾值所以它執行了步進調整。應用日志出現了1條關于時間跳變的警告但之后恢復正常。步進調整后再次檢查chronyc tracking偏移量變為微秒級。為了預防未來再次因源質量導致偏差累積我修改了/etc/chrony.conf將不穩定的那個時間源注釋掉。增加了兩個新的、知名的低延遲公共NTP源。將makestep策略改為makestep 0.5 3允許在啟動初期對超過0.5秒的偏差進行步進調整以期更快收斂。重啟chronydsystemctl restart chronyd。觀察幾分鐘后運行chronyc sources -v確認新的源被選中且狀態健康Reach值為377。經驗點chrony的“智能”算法大多數時候是優點但在時間源質量發生微妙變化時它可能“戀舊”。作為運維人員不能完全放任自流需要定期比如通過監控chronyc tracking的偏移量檢查同步狀態。對于關鍵業務服務器配置多個高質量、低延遲、來自不同運營商的時間源是性價比最高的穩定性提升手段。