本文描述了如何配置並運行 chrony,這是一個對漫遊友好的 NTP 客戶端和服務端實現,專為不常在線的系統環境設計。
安裝
配置
最小的可用配置(使用了 IP 而不是域名)如下:
/etc/chrony.conf
server 1.2.3.4 offline server 5.6.7.8 offline server 9.10.11.12 offline driftfile /var/lib/chrony/drift rtconutc # 該選項會同步 RTC 時間,但不跟蹤 RTC 偏移。建議的替代值為 rtcfile,詳情可參考下文的「RTC 選項」。 rtcsync
更多信息請查閱 /usr/share/doc/chrony/README
,它對你現有的問題都提供了指向。在網上也可以找到相關文檔。另外也請查看手冊:chronyc(1),chrony.conf(5) 和 chronyd(8)。
NTP 伺服器
在 /etc/chrony.conf
中定義的第一項就是設備要連接到的伺服器地址。
NTP 伺服器處於一分層結構中,其中的每一層被稱作 strata:被認定為獨立時鐘源的設備作為 stratum 0 時間源;直接連接到 stratum 0 的設備為 stratum 1 時間源;連接到 stratum 1 的為 stratum 2 時間源,以此類推。
但請注意,伺服器的層級並不能作為其準確度或可靠性的依據。通常來說,stratum 2 伺服器被用於時間同步;如果你還不知道要連到哪個伺服器,那建議使用 pool.ntp.org 的伺服器(備用連結),然後根據你的物理位置選擇伺服器池。
下一行告知 chrony 從 NTP 池中選擇 4 個源(chrony 使用其特定方式處理伺服器池,以防止混淆其服務端測偏移跟蹤),然後在啟動時使用 burst 特性:
pool 2.arch.pool.ntp.org iburst maxsources 4
離線設備
如果你的設備在啟動時不會連到網絡,那建議使用其 offline 選項。它會讓 Chrony 在沒有被告知的情況下不要嘗試連接到伺服器。
pool 2.arch.pool.ntp.org iburst maxsources 4 offline
另外,由於在完成連接前 DNS 解析都將不可用,建議使用 IP 地址而不是域名,或者在 /etc/hosts
中將域名固定到對應的 IP 地址。
使用 NTS 伺服器
從 4.0 版本開始 [1],chrony 支持使用 Network Time Security (NTS) 網絡時間安全機制,這是 NTP 的安全加密變種。如需使用該功能,請添加一個啟用 NTS 的伺服器,然後在結尾添加 nts
,例如:
server time.cloudflare.com iburst nts
可以在這裡查看支持 NTS 的伺服器列表。
實時時鐘
在系統啟動時,會從硬體實時時鐘(RTC)讀取初始時間,並用其設定系統時間,然後在 chrony 守護進程啟動後的幾分鐘內進行一次同步。如果硬體時間脫離同步,那初始系統時間將可能會和真實時間相差數分鐘。Chrony.conf 有三種不同機制來處理 RTC:
- 第一種是
rtcsync
,它會簡單地定期將當前時間寫入到 RTC。這也是 ntpd 選用的方式,但會關閉 RTC 偏移跟蹤:這對於間斷運行的桌面環境很不利,該環境下會依賴 RTC 進行大量計時工作。 - 第二種是
rtcautotrim
,它會在 RTC 時間偏移超過一定量後進行複寫。該方式可與rtcfile
搭配,它會啟用 RTC 誤差跟蹤。 - 最後一種是不操控 RTC,但會將其誤差和偏移記錄到
rtcfile
。RTC 時間會一直有誤差,但系統時間會保持正常,因為 chrony 記錄了其具體的偏移量。chronyc 下的rtctrim
命令還是可以按需同步 RTC:
# chronyc chronyc> trimrtc 200 OK chronyc> quit
rtcsync
和 rtcfile
不能同時使用。另外 rtcfile
會阻止如 hwclock
和 timedatectl
之類的工具訪問 RTC,詳細信息請參考 chrony.conf(5) § System clock。另外,rtconutc
描述了 RTC 是否以 UTC 時間運行。
案例:間斷運行的桌面環境
間斷運行的桌面環境將需要使用 rtcfile
來跟蹤 RTC 誤差。裝有 Arch Linux 連續運行 5 年的設備上 RTC 可累計有 300 秒的誤差,如果使用以上的配置,在重啟後 chrony 會需要很長一段時間來調整時間偏移。如果改用如下配置:
/etc/sysconfig
文件夾,需要手動創建。/etc/sysconfig/chronyd
OPTIONS='-r -s'
/etc/chrony.conf
dumpdir /var/lib/chrony rtcfile /var/lib/chrony/rtc
有意思的是,RTC 還是會有誤差,但在每次重啟之後,chrony 都會調整 RTC 的累計誤差,就算系統剛剛啟動,其時間還能和 NTP 接近同步。
RTC 仍留存誤差的原因是我們忘了添加 rtcautotrim
一行到配置中,它會讓 chrony 調整 RTC 時間。如果加上了這一行,那 RTC 和系統時間都將變正確。
其它有意思的選項
有用的選項:
-
makestep
:允許 chrony 單次大量調整時間,而不是頻繁多次調整。可能會對運行中程序造成影響,但有助於修正大量偏移。makestep 0.1 3
可能會更適用於經常離線的系統:只有開頭三次調整會是階躍性的,因此影響僅限於系統啟動時段。
精確性:
-
server
和pool
:xleave
和presend
可能會在沒有兼容性成本的情況下提升精確度。 -
hwtimestamp
:有些網卡會給它的包添加時間戳以測量網絡棧的延遲。使用hwtimestamp *
可用啟用該功能,對於不支持的網卡將不起任何效果。 -
tempcomp
:跟蹤軟體時鐘偏移(通常由主板晶振溫度變化導致)和溫度傳感器間的關係,適用於要求極致精確度的環境。
用法
啟動 chronyd
軟體包提供了 chronyd.service
,具體信息請參考 systemd。
告知 chronyd 網絡連接已可用
如果你連接到了網絡,執行:
# chronyc chronyc> online 200 OK chronyc> exit
你也可以使用 activity
選項來查看狀態:
# chronyc activity 200 OK 3 sources online 0 sources offline 0 sources doing burst (return to online) 0 sources doing burst (return to offline) 0 sources with unknown address
Chrony 應該已經連接到配置的時間伺服器了,並根據需要更新了你的時鐘。使用如下命令告知 chrony 你已經斷開網絡:
# chronyc offline 200 OK # chronyc activity 200 OK 0 sources online 3 sources offline 0 sources doing burst (return to online) 0 sources doing burst (return to offline) 0 sources with unknown address
在線/離線狀態可由 networkmanager包 和 connman包 的調度服務自動處理,詳情請參考下文。
檢查已配置的 NTP 伺服器
如需查看 chrony 正在使用的 NTP 伺服器和其精度,可使用 chronyc -N 'sources -a -v'
:
$ chronyc -N 'sources -a -v' .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current best, '+' = combined, '-' = not combined, | / 'x' = may be in error, '~' = too variable, '?' = unusable. || .- 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 =============================================================================== ^+ ptbnts1.ptb.de 1 6 377 50 -38us[ -13us] +/- 8723us ^* ptbnts2.ptb.de 1 6 377 49 +2061ns[ +27us] +/- 7538us ^+ nts.ntp.se 2 6 377 51 +594us[ +619us] +/- 15ms ^+ nts.sth1.ntp.se 2 6 377 51 +655us[ +680us] +/- 15ms ^+ nts.sth2.ntp.se 2 6 377 53 +991us[+1016us] +/- 15ms ^+ time.cloudflare.com 3 6 377 49 -1250us[-1250us] +/- 10ms
網絡狀態通知
如果你在 chrony.conf
中為你的池配置了 offline 選項,需要將網絡狀態變更告知 chrony。
你可以使用 chronyc 來通知 chrony,也可以使用你的網絡配置管理器對應的調度服務。
NetworkManager
chronyd 可以通過 NetworkManager 調度腳本隨網絡連接狀態進入在線/離線狀態。創建一個軟連結來使用上游分發的 NetworkManager 調度腳本:
ln -s /usr/share/doc/chrony/examples/chrony.nm-dispatcher.onoffline /etc/NetworkManager/dispatcher.d/20-chrony-onoffline.sh
你也可以選擇安裝 networkmanager-dispatcher-chronyAUR。
netctl
從 AUR 安裝 netctl-dispatcher-chronyAUR。這會為 netctl 添加一個鉤子,隨任意網絡連接自動運行。
dhcpcd
創建如下鉤子:
/etc/dhcpcd.exit-hook
if $if_up; then chronyc online elif $if_down; then chronyc offline fi
詳情可參考 dhcpcd-run-hooks(8)。