出自 Arch Linux 中文维基

本文描述了如何配置並運行 chrony,這是一個對漫遊友好的 NTP 客戶端和服務端實現,專為不常在線的系統環境設計。

安裝

安裝 chrony

配置

最小的可用配置(使用了 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
注意: rtcsyncrtcfile 不能同時使用。另外 rtcfile 會阻止如 hwclocktimedatectl 之類的工具訪問 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 可能會更適用於經常離線的系統:只有開頭三次調整會是階躍性的,因此影響僅限於系統啟動時段。

精確性:

  • serverpoolxleavepresend 可能會在沒有兼容性成本的情況下提升精確度。
  • hwtimestamp:有些網卡會給它的包添加時間戳以測量網絡棧的延遲。使用 hwtimestamp * 可用啟用該功能,對於不支持的網卡將不起任何效果。
  • tempcomp:跟蹤軟體時鐘偏移(通常由主板晶振溫度變化導致)和溫度傳感器間的關係,適用於要求極致精確度的環境。

用法

啟動 chronyd

軟體包提供了 chronyd.service,具體信息請參考 systemd

注意:
  • systemd-timesyncd.service 會與 chronyd 產生衝突,所以如果你要啟用 chronyd,需要先將其禁用

告知 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

在線/離線狀態可由 networkmanagerconnman 的調度服務自動處理,詳情請參考下文。

檢查已配置的 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)

參考