天天看點

chronyd的那些事

寫在前面

每個人的環境都不一樣,是以生産環境操作前一定要在你的測試環境中仔細驗證後再操作。

以下内容純屬個人了解,并沒有對錯,隻是參考,盜版不糾,才能有限,希望不誤人子弟為好。

以下屬于個人實驗,實際運用當中需要結合實際需求,參考有風險,實施需謹慎。

文檔資訊

屬性 内容
文檔名稱 Linux時間管理
文檔狀态 修訂中
作者 [email protected]
說明 目的是如何設計時間管理,而不是單純的說安裝和使用,網上一堆

文檔變更記錄

版本編号 日期 說明
V1.0 2022年4月12 建立
V1.1 2022年6月9日 補充,修訂内容
V1.2 2022年6月17日 驗證并組織語言,使文檔更有邏輯與合理性
v1.3

最近接觸了k8s叢集,etcd叢集等等,發現叢集内如果時間不同步,會出現一些意想不到的問題。

是以這裡主要讨論下叢集下的時間同步問題,本文的基礎是以RockyLinux 8為基礎。你可能會使用ntpd,ntpdate這些工具進行時間同步,但是Centos 8系列中,這些工具已經被淘汰了,在基礎倉庫裡無法找到了,

而且Centos 7也有chrony,是以這裡着重介紹Chrony來實作叢集内的時間同步。

這裡希望閱讀完這篇文檔,能夠幫助解決2個問題:

  1. 我該如何設計時間叢集
  2. 實際應用需要注意哪些問題

參考

官方文檔:

​​https://chrony.tuxfamily.org/​​

​​https://chrony.tuxfamily.org/faq.html​​

從chrony的官方文檔可以有一些常見的問題解答,不過國内無法通路。

巨人的肩膀:

​​https://help.aliyun.com/document_detail/92704.html​​

​​https://datatracker.ietf.org/doc/html/rfc1305​​

​​https://yfeng9186.gitee.io/blog/2020/2/linux-%E6%97%B6%E9%97%B4%E5%90%8C%E6%AD%A5%E4%B9%8Bchronyd​​

除了以上的連結,還有萬能的網際網路,如果侵權了,可以通過上方文檔的郵箱聯系我。

環境

本文檔的實驗環境,是在本地PC上模拟,不是雲主機,如果是其他環境請自行測試

名稱 版本 備注
Vmware Workstation 16.1.2 build-17966106
Rokcy Linux release 8.5 (Green Obsidian)
chrony 4.1

基礎概念

時間管理的主要的兩個目的:

  1. 對外,保證本地的時間和國際通用時間保持同步,通過NTP協定與時間源同步
  2. 對内,保證系統時間和硬體時間保持同步

首先我們先了解一下Linux中和時間有關的一些簡單的概念,這些便于以下内容的展開

系統時間:會發現一些比如Universal time,system time,都表示是系統核心進行的處理,和硬體無關

UTC:整個地球分為二十四時區,每個時區都有自己的本地時間,在國際無線電通信場合,為了統一起見,使用一個統一的時間,稱為通用協調時(UTC:Universal Time Coordinated)

時區:這裡自己可以去網上搜一下,有詳細的展開,主要是我們中國使用的是CST,系統預設不是,但是我們通常都是配置CST,是以需要注意一下。

硬體時間(RTC): The Hardware Clock也可以叫real time clock也就是RTC,一般pc和伺服器等裝置都有一個和系統無關的小程式,通常是cmos電池維持其運作,不受伺服器和作業系統的開啟關閉影響,我們可以通過bios或者開機後通過系統設定進行校正。

NTP協定

​​https://zh.wikipedia.org/wiki/%E7%B6%B2%E8%B7%AF%E6%99%82%E9%96%93%E5%8D%94%E5%AE%9A​​

chronyd的那些事

啥也不說了,佩服去吧。别說設計了,我看都看不懂NTP的算法,哈哈。

知其然知其是以然,無法更為詳細的解釋chrony同步時間的一個算法,所裡這裡隻能對其現象進行一些實驗。

更為深入的解析,我目前還無法做到,是以各位看官見諒。

如下圖是NTP的一個互動過程。

chronyd的那些事
chronyd的那些事
chronyd的那些事

NTP的實作

​​https://www.cnblogs.com/pipci/p/12833228.html​​

上面說了NTP的協定标準,下面就看NTP協定的一些常見的具體實作,

1、以前Linux時間同步基本是使用 ntpdate 和 ntpd 這兩個工具實作的,但是這兩個工具已經很古老了

ntpd是步進式平滑的逐漸調整時間,而ntpdate是斷點式更新時間。是以當時間偏差比較大的時候ntpd同步就會比較慢,是以經常會有人用crontab來配置ntpdate定時的去更新時間。

2、RHEL/CentOS 7.x及以上版本已經将 chrony 作為預設時間同步工具了,本文主要讨論的就是這個

3、其他Linux (如 ubuntu,debian,openSUSE) 使用 systemd-timesyncd 服務。

systemd-timesyncd是斷點式更新時間,也就是時間不同立即更新,這樣會對某些服務産生影響,是以在生産環境盡量不要用,在桌面環境或者是系統剛開機時來進行時間同步還是很好的。timesyncd 替代了 ntpd 的用戶端的部分。預設情況下 timesyncd 會定期檢測并同步時間。它還會在本地存儲更新的時間,以便在系統重新開機時做時間單步調整。systemd-timesyncd隻能作為用戶端,不能作為NTP伺服器,要成為NTP伺服器,可以安裝chrony、ntpd,或者open-ntp。推薦chrony

4、虛拟機,以下是Vmware的時間同步,但是這個需要安裝Vmware tools,這個不是預設安裝的,是以一般不用關心,還有就是Esxi等其他的虛機,也要注意這塊問題。

chronyd的那些事
chronyd的那些事

這裡就不讨論vmware tools的安裝了,我目前的環境暫時用不到。而且即使是虛拟機,主控端也是需要使用上面的一些工具實作時間同步

架構

第一個問題,“我該如何設計時間叢集”,這就是架構問題,比如我的k8s叢集有3個master節點,一堆node節點,我需要保證整個叢集節點的時間一緻性。

首先假設每個節點都可以通路公網,那麼我們直接都從公共ntp伺服器來同步時間。這個時候多個server就是備份,但是要監控主機的公網狀态,如果公網不行了,時間同步就會失敗。

那如果是無法通路公網的情況,就需要在區域網路内自己搭建ntp伺服器,但是一個ntp伺服器不行,一旦挂了,就會出現無法使用的情況,server可以配置多個用于備份,此時需要使用多個主機來部署ntp server,用戶端指定多個ntp server,但是ntp server需要能保證通路公網。否則時間不準确的日志和告警等資訊沒有參考價值。

也就是說必須要ntp server能夠通路公網。此時也需要有監控,否則ntp server無法通路公網提示還提供chrony服務就不合适。

可以把ntp server和etcd叢集放在一起,不浪費資源。

chronyd的那些事

公共NTP伺服器

​​http://www.ntp.org.cn/pool​​

​​https://www.ntppool.org/zh/​​

NTP(network time protocol),通過這個協定,來實作網絡中時間的同步,端口是UDP 123

和dns類似,總是要有個節點作為參考。

中國國家授時中心 NTP伺服器位址是 ntp.ntsc.ac.cn

估計其他公共的NTP伺服器的時間源就是上面的位址,但是我們也不用使用這個作為自己的源,因為這個是在北京,就近原則。過去我經常使用的就是ntp.aliyun.com,但是如果說要配置一個公共ntp伺服器位址,确實不必要,因為有pool這個東西,類似yum倉庫優先使用mirrorlist而不用baseurl一樣。

現在我們隻需要在chrony中配置位址池的位址,而不是server的位址,它會選擇合适的伺服器作為源

chronyd的那些事

clock/hwclock

預設硬體時間是UTC格式的時間,

主要是2個作用把系統時間同步到硬體時間上,或者把硬體時間同步到系統上。

chronyd的那些事

如上可以看出來,RTC的時間會和系統時間發生一定的偏差,此時我們可以使用clock指令來手動的同步。一般預設RTC是使用的UTC格式時間,是以和Universal time對比即可。

RTC in local TZ是no的狀态,也不建議修改為yes。

但是會發現RTC和Universal time總是會偏差,不能總是手動clock 吧,懶惰的人類自然是不用的,下面chrony服務配置中有個參數rtcsysnc 每隔11分鐘會把系統時間同步到RTC中去。

hwclock --set --date 來修改rtc時間,以便測試。

chronyd的那些事

timedatectl

chronyd的那些事
chronyd的那些事

可以看出來有顯示上有一定的差別。

​​https://www.freedesktop.org/software/systemd/man/systemd-timedated.service.html#​​

timedatectl就是systemd-timedated.service的用戶端

雖然各種把timedatectl和systemd-timesyncd.service聯系在一起,在RockyLinux8的man timedatectl的example中也有systemd-timesyncd.service聯系,給我造成了一定的誤導。可以參考上面的“ntp實作”

chronyd的那些事

NTP service有兩個狀态active和inactive,可以通過timedatectl set-ntp 來設定。

會把chronyd服務關掉,慎用。不僅僅是停止服務,還會把自啟動關閉。

chronyd的那些事

NTP service: 狀态更新是比較及時的,ntp服務停了,就是inactive,開啟就是active

System clock synchronized:狀态就比較複雜一點,不确定這個是根據什麼檔案等來判斷是yes還是no的。

首先chronyc tracking如果是local 本地源的話,這個狀态一直是no的。如果chronyc sources沒有源,此時也是no,而且如果是local 本地源也會導緻chronyc sources沒有源,如果有源但是沒有狀态是^*的,也是no,

有了^*但是system time這裡不是0的也是no,

說明代表的意思就是在和時間源同步成功的情況下,并且系統時間同步成功,才會顯示yes。

如下圖,因為chrony的makestep 1 1, limit是正值,是以這裡啟動後幾次後,就會是慢慢修訂而不是直接同步。

是以 System clock synchronized 狀态是no,等同步好了,就會變成yes

chronyd的那些事

設定時區

chronyd的那些事

timedatectl list-timezones可以檢視所有的時區

timedatectl set-timezone 然後從上面的Zone選擇一個。就會把/etc/localtime檔案軟連接配接到指定的時區

chronyd的那些事

遇到的問題

問題:timedatectl timesync-status

chronyd的那些事

這個可能安裝桌面環境才需要。

chronyd

模式

server

peer

local

配置

預設配置檔案路徑:/etc/chrony.conf

具體可以man chrony.conf檢視幫助 ,也可以線上幫助,翻譯友善。

​​https://chrony.tuxfamily.org/doc/4.1/chrony.conf.html​​

按功能分為以下部分的配置:

Time sources:設定時間源,例如:server,peer,pool。

Source selection:時間源的選擇

NTP server:主要和作為ntp server相關的參數

Command and monitoring access :主要是和chronyc相關的一些參數

System clock: 和系統時間相關的參數,把同步來的是時間同步到系統時間上去,例如:makestep

Real-time clock (RTC):和rtc相關的一些參數,把同步來的時間同步到硬體時間上去,例如:rtcsync

logging:和chronyd日志相關的參數。

chronyd的那些事

chronyd服務啟動後會啟用2個端口

123/udp 用于提供ntp server 服務

323/udp 用于提供chronyc連接配接的管理端口。

Time sources

​​https://www.ntppool.org/zh/use.html​​

pool/server 用于指定chrony同步時間的時間源,兩個指令可以同時使用

chronyd的那些事

pool <hostname> [option]...

option有個maxsources預設是4,最大16。

如下圖所示,pool是個公益項目,看自己需求,使用預設參數即可。沒必要修改maxsources

chronyd的那些事

server <hostname> [option]... 指令最好配置3個,用于備份,是以本地網絡中最好有3個ntp server。這樣即使1個挂了,還有備份。

iburst表示的是首次同步的時候快速同步,chronyc中可以使用互動式指令,online和offline快速啟用和禁用server。實作這個過程。

Source selection

如上我們指定了多個server和pool,如何選擇時間源。

這裡就需要時間源選擇算法,核心就是在多個時間源中如何選擇合适的一個時間源

stratumweight distance:stratumweight指令設定當chronyd從可用時間源中選擇同步源時,每一stratum應添加多少同步距離。

預設情況下,該值是0.001秒。這意味着,在選擇同步源的過程中,隻有當時間源距離之間的差異以毫秒為機關時,時間源的stratum才有意義。在chronyd選擇同步時間源時,即使處于stratum低層級的時間源距離更遠,也比另一個處于stratum高層次的時間源更容易被選中。将stratumweight設定為0時,可以使chrongyd選擇時間源時忽略stratum層次。

也就是說假設一個是10層,一個是3層,假設目前3層給的時間是10:00:001,10層給的時間是10:00:002此時看時間小的,不看stratum高的也就是數字小的,如果目前3層給的時間是10:00:009,10層給的是10:00:001,此時選擇哪個source作為時間源呢?

chronyd的那些事

NTP server

allow指令:需要配置,讓chronyd去響應用戶端請求,如果allow後不跟子網或主機位址就是響應所有來自ipv4和ipv6的通路

chronyd的那些事

bindaddress:chrony的ntp服務監聽在哪個ip上

binddevice:chrony的ntp服務監聽在哪個接口port:chrony對外提供ntp server的端口,預設是123,port可以配置為0,表示隻作為ntp client同步時間,不提供ntp server服務。此時如果allow沒配置的話,那麼此時也不需要添加 port 0的指令。

!!!如果allow不開啟的話,port和bindaddress、binddevice沒有意義,因為不會監聽。

local :當本地ntp server的外部的time sources不可用時,可以用本地時間去給内部網絡的用戶端去同步時間。

這句話怎麼了解呢,用人話就是,如下圖,如果我不配置local指令,當無sources源可用的時候,不會啟用local preference mode,無法提供ntp server的服務了。

chronyd的那些事
chronyd的那些事

如果配置了local指令,當chrony的其他源無法同步的時候,才會啟用本地參考模式。否則不會啟用,此時stratum是随着目前同步的時間源的值而變化,而不是配置的值。比如目前chrony同步的是源stratum是2,那麼chrony伺服器的stratum就是3,如果chrony同步的是源stratum是3,那麼chrony伺服器的stratum就是4。如果沒有同步的源了,那麼stratum就是配置的值了。

chronyd的那些事
chronyd的那些事
chronyd的那些事

orphan說是在孤島網絡裡使用,這個一直無法驗證。即使我3台都配置了local stratum 10 orphan,但是都是^X的狀态,不會說去選擇reference id最小的,不知道為何。

​​https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/setting-up-chrony-for-a-system-in-an-isolated-network_using-chrony​​

System clock

把從時間源同步的時間同步到系統時間上。

makestep threshold limit threshold:表示門檻值,系統時間和時間源之間的偏差,機關秒

不受limit的影響,這個是makestep的前提條件,也就是說如果本地和時間源的時間偏差超過多少秒,才會觸發step斷點式更新,直接同步時間。

limit:限制次數,允許chrony啟動後,快速去修正同步多少次,超過次數後則會采用slew time的方式,慢慢的修正,如果相差時間過大,會很慢;如果為負值,則不限制次數,step方式去更新系統時間,

說是步進時鐘(時間跳躍)可以快速修正偏差較大的時間誤差,但是有可能會導緻一些程式異常,是以應當慎用這個選項,但是不使用的話,會導緻時間無法修複。不是更影響程式嗎。

這裡有個問題,為何不把threshold設定小,預設是1s,可以設定0.1s,這樣影響應該就不大了吧。這裡主要是影響程式的時間門檻值不好判定,1s可以避免頻繁的step 修正。當然如果設定為0.1也沒有造成頻繁的step修正的話,也可以設定為0.1s,看你能接受的時間偏差範圍。

makestep 0.1 -1

chronyd的那些事

Real-time clock (RTC)

rtcsync:rtcsync指令啟用系統時間定期複制到 RTC 并且chronyd不會嘗試跟蹤其漂移的模式。該指令不能與rtcfile指令一起使用。

前提是,系統時鐘必須是同步的,也就是system clock synchronized是yes的狀态。

在 Linux 上,核心每 11 分鐘執行一次 RTC 複制。

在 macOS 上,當系統時鐘處于同步狀态時, chronyd将每 60 分鐘執行一次 RTC 複制。

在其他系統上,該指令什麼也不做。

遇到的問題:

問題:如下圖所示,沒有生效,11分鐘過去了,rtc依然沒有從 system time同步。

chronyd的那些事

修改rtcsync改為rtcfile,結果出現rtc不可用情況

chronyd的那些事
chronyd的那些事
chronyd的那些事

以為master1是把公網關了,使用的是本地時間做為時間源。是以測試下master2,master2以master1作為時間,修改下master2的rtc時間,看master2會不會在11分鐘的時候更新rtc時間。

chronyd的那些事

果然在11分鐘的時候更新了。

chronyd的那些事

結論就是:

rtcsync同步的關鍵是要系統時鐘同步狀态是yes才可以。

rtcfile啟用後,hwclock無法正常使用。rtcfile和hwclock是互斥的。

日志

logdir定義了chronyd日志的目錄

log 定義日志的檔案,僅僅定義了logdir是沒有用的。

rtc日志,需要配置rtcfile /var/lib/chrony/rtc,當chronyd退出或者其他原因會把便宜儲存到/var/lib/chrony/rtc中,第一次不會生成這個檔案。

rtcsync不能配置,配置了,也不會産生rtc.log

chronyd的那些事

這裡面就想看下chronyd服務自己的一些日志,但是沒有。上面那些日志的格式,都是常人無法了解的資訊。

下面系統日志提示的都是一些終結态的資訊,其中的一些邏輯判斷資訊,這裡沒有。

是以你不知道為啥它就判斷沒有可用的源了,然後就檢測到時間便宜了,然後又選擇到了可用的時間源,然後由修訂了時間。

chronyd的那些事

chronyc

用戶端工具,本地的話建議使用互動式指令,友善,如下help可以看到所有支援的指令

chronyd的那些事

chronyc sources

chronyd的那些事

MS:M代表source mode,一般都是^表示server,配置檔案中指定的也是server

主要是S,source state,

?:代表不可用,

*:代表目前同步的時間源

+/-:

x:

chronyd的那些事

Stratum:表示的是時間源的層級,不是自己的層級。取值範圍是1-15

chronyd的那些事

Poll: 表示對時間源進行輪詢的頻率。Poll 為6,表示每隔2^6=64s(秒)對該時間源輪詢,Poll 為9就是每隔2^9=512s(秒)。chronyd會根據情況自動調整輪詢頻率,是以這裡會看到這個值在變化。

Last sample :

xxxx 【yyyy】 +/- zzzz 可以看到這裡的機關有ns/us/ms/s

1秒(s) =1000毫秒(ms)

1毫秒(ms)=1000微秒 (us)

1微秒(us)=1000納秒 (ns)

這一列顯示了最後一次測量到的本地時間與時間源之間的偏移量。

yyyy表示實際測量的偏移量,。

xxxx的數字顯示的是最初的測量值,經過調整後可以應用到本地時鐘上。‘+/-’符号後的數字顯示的是測量誤差。‘+’表示本地時鐘比時間源快。

zzzz

chronyc tracking

chronyd的那些事

Stratum:這個是相對Reference id的層級,這裡是3,說明Reference id的層級是2,在chronyc sources中看到的這個時間源的stratum值應該是2.

Ref time:就是上次同步的時間源給的時間

Update interval:同步的間隔,64s左右,基本上是chronyc sources中pool的時間,2^6=64s

System time:這個就是本地時間和時間源提供的Ref time之間的差距,這裡是slow of Ntp time也就是比時間源慢了,因為我虛拟機挂機後打開的,因為我makestep的limit是正值,是以它隻能slewing 慢慢的修正。

如果相差時間過大,那麼slew修訂的時間會巨慢,可以嘗試date -s 先修訂下時間

Frequency、Residual freq、Skew:ppm (part per million)百萬分之一,算法需要的值,反正解釋了我也不了解,就算了吧。

chronyc makestep

chronyd的那些事
chronyd的那些事

手動同步系統時間。

有一定延遲,說是強制同步系統時間,但是并不是像date -s 一樣系統時間時間直接就變了。

而且會使chrony重新選擇時間源,不知道這個指令的意義是啥,和重新開機chrony有啥差別

chronyd -q 'server ntp.aliyun.com iburst'

chronyd的那些事

還不如在chrony啟動前去執行這個指令,但是這玩意有和makestep 1 3裡面的前幾次跳躍式同步也沒啥差別。

執行個體

pool pool.ntp.org iburst 
server ntp.aliyun.com iburst
driftfile /var/lib/chrony/drift
makestep 1 -1
rtcsync
allow 192.168.0.0/16
local stratum 10  //3個server中,隻能配置一個。做保底使用。如果外網斷了,3個都開啟的話,client無法使用它們作為時間源。當然你3個server,3個外網,那都開啟無妨。      
server <chrony1> iburst
server <chrony2> iburst
server <chrony3> iburst
driftfile /var/lib/chrony/drift
makestep 1 -1
rtcsync      

遇到的問題

問題:虛拟機挂起後,時間不同步。

chronyd的那些事

這裡可以看到,chronyc tracking的時候,

Ref time是正确的,但是system time并沒有修訂。是以同步時間是沒有問題的,但是沒有把系統的時間給修訂掉。

chronyd的那些事

可以看到時間是慢慢調整,不是跳躍式的調整,此時相差時間太大,無法快速修訂。

chronyd的那些事

通過chronyc makestep快速同步了system clock,但是RTC時間chrony并沒有間隔11分鐘,把系統時間同步到rtc上,手動執行hwclock -w才同步。是以為什麼rtc時間沒同步呢。

這個問題在上面的配置部分,Real time clock部分有解釋。但是為什麼時間同步了,system clock sysnchronized還是沒有變成yes,這裡可能是狀态的一個延遲問題。

chronyd的那些事

問題:chronyc tracking,這裡的ref time是系統的時間,不是時間源的時間。

chronyd的那些事
chronyd的那些事
chronyd的那些事
chronyd的那些事

結論就是:

當makestep threshold limit中,limit是正值的時候,Backward time能躍進的修訂,但是Forward time慢慢修訂。

當是負值的時候,Backward time和Forward time都能躍進的修訂。

“Can't synchronise: no selectable sources” 這個不是關鍵問題,容易誤導人

問題:公網已經斷了,時間同步狀态顯示yes,然後MS的狀态是^*而不是^?

chronyd的那些事
chronyd的那些事

過了一個小時的時間,才判斷時間源無效。此時local stratum 10生效。

chronyd的那些事
chronyd的那些事

因為我master1 時間和其他時間源相差過大,是以這裡是x的狀态,如果我把master2其他源去掉後重新開機

如下圖。就是簡單的區域網路ntp client和server關系。當然備份的考慮,我這裡辦本地的ntp server可以多個。

下面一個問題就是多個ntp server的問題

chronyd的那些事

問題:當叢集的ntp server 外網不可用時,啟用本地參考模式,此時對于用戶端來說,時間源不可用。

chronyd的那些事

當我把其中一個伺服器上的chrony服務停掉後

chronyd的那些事
chronyd的那些事

發的包,181和183reference id封包裡都是127.127.1.1,但是落地顯示不一樣呀。

chronyd的那些事
chronyd的那些事

結論就是:

如果所有ntp server都不能有自己的time source的話,就是不配置server,local preference mode,隻能有一個,local stratum xxx 隻能配置在一個server上,也就是隻能有一個server。是以盡量保證ntp server可以通路internet的時間源,然後選擇一個ntp server配置local stratum用來保底。

date

進階用法

NTS

繼續閱讀