寫在前面
每個人的環境都不一樣,是以生産環境操作前一定要在你的測試環境中仔細驗證後再操作。
以下内容純屬個人了解,并沒有對錯,隻是參考,盜版不糾,才能有限,希望不誤人子弟為好。
以下屬于個人實驗,實際運用當中需要結合實際需求,參考有風險,實施需謹慎。
文檔資訊
屬性 | 内容 |
文檔名稱 | 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個問題:
- 我該如何設計時間叢集
- 實際應用需要注意哪些問題
參考
官方文檔:
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 |
基礎概念
時間管理的主要的兩個目的:
- 對外,保證本地的時間和國際通用時間保持同步,通過NTP協定與時間源同步
- 對内,保證系統時間和硬體時間保持同步
首先我們先了解一下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
啥也不說了,佩服去吧。别說設計了,我看都看不懂NTP的算法,哈哈。
知其然知其是以然,無法更為詳細的解釋chrony同步時間的一個算法,所裡這裡隻能對其現象進行一些實驗。
更為深入的解析,我目前還無法做到,是以各位看官見諒。
如下圖是NTP的一個互動過程。
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等其他的虛機,也要注意這塊問題。
這裡就不讨論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叢集放在一起,不浪費資源。
公共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的位址,它會選擇合适的伺服器作為源
clock/hwclock
預設硬體時間是UTC格式的時間,
主要是2個作用把系統時間同步到硬體時間上,或者把硬體時間同步到系統上。
如上可以看出來,RTC的時間會和系統時間發生一定的偏差,此時我們可以使用clock指令來手動的同步。一般預設RTC是使用的UTC格式時間,是以和Universal time對比即可。
RTC in local TZ是no的狀态,也不建議修改為yes。
但是會發現RTC和Universal time總是會偏差,不能總是手動clock 吧,懶惰的人類自然是不用的,下面chrony服務配置中有個參數rtcsysnc 每隔11分鐘會把系統時間同步到RTC中去。
hwclock --set --date 來修改rtc時間,以便測試。
timedatectl
可以看出來有顯示上有一定的差別。
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實作”
NTP service有兩個狀态active和inactive,可以通過timedatectl set-ntp 來設定。
會把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
設定時區
timedatectl list-timezones可以檢視所有的時區
timedatectl set-timezone 然後從上面的Zone選擇一個。就會把/etc/localtime檔案軟連接配接到指定的時區
遇到的問題
問題:timedatectl timesync-status
這個可能安裝桌面環境才需要。
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服務啟動後會啟用2個端口
123/udp 用于提供ntp server 服務
323/udp 用于提供chronyc連接配接的管理端口。
Time sources
https://www.ntppool.org/zh/use.html
pool/server 用于指定chrony同步時間的時間源,兩個指令可以同時使用
pool <hostname> [option]...
option有個maxsources預設是4,最大16。
如下圖所示,pool是個公益項目,看自己需求,使用預設參數即可。沒必要修改maxsources
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作為時間源呢?
NTP server
allow指令:需要配置,讓chronyd去響應用戶端請求,如果allow後不跟子網或主機位址就是響應所有來自ipv4和ipv6的通路
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的服務了。
如果配置了local指令,當chrony的其他源無法同步的時候,才會啟用本地參考模式。否則不會啟用,此時stratum是随着目前同步的時間源的值而變化,而不是配置的值。比如目前chrony同步的是源stratum是2,那麼chrony伺服器的stratum就是3,如果chrony同步的是源stratum是3,那麼chrony伺服器的stratum就是4。如果沒有同步的源了,那麼stratum就是配置的值了。
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
Real-time clock (RTC)
rtcsync:rtcsync指令啟用系統時間定期複制到 RTC 并且chronyd不會嘗試跟蹤其漂移的模式。該指令不能與rtcfile指令一起使用。
前提是,系統時鐘必須是同步的,也就是system clock synchronized是yes的狀态。
在 Linux 上,核心每 11 分鐘執行一次 RTC 複制。
在 macOS 上,當系統時鐘處于同步狀态時, chronyd将每 60 分鐘執行一次 RTC 複制。
在其他系統上,該指令什麼也不做。
遇到的問題:
問題:如下圖所示,沒有生效,11分鐘過去了,rtc依然沒有從 system time同步。
修改rtcsync改為rtcfile,結果出現rtc不可用情況
以為master1是把公網關了,使用的是本地時間做為時間源。是以測試下master2,master2以master1作為時間,修改下master2的rtc時間,看master2會不會在11分鐘的時候更新rtc時間。
果然在11分鐘的時候更新了。
結論就是:
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服務自己的一些日志,但是沒有。上面那些日志的格式,都是常人無法了解的資訊。
下面系統日志提示的都是一些終結态的資訊,其中的一些邏輯判斷資訊,這裡沒有。
是以你不知道為啥它就判斷沒有可用的源了,然後就檢測到時間便宜了,然後又選擇到了可用的時間源,然後由修訂了時間。
chronyc
用戶端工具,本地的話建議使用互動式指令,友善,如下help可以看到所有支援的指令
chronyc sources
MS:M代表source mode,一般都是^表示server,配置檔案中指定的也是server
主要是S,source state,
?:代表不可用,
*:代表目前同步的時間源
+/-:
x:
Stratum:表示的是時間源的層級,不是自己的層級。取值範圍是1-15
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
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
手動同步系統時間。
有一定延遲,說是強制同步系統時間,但是并不是像date -s 一樣系統時間時間直接就變了。
而且會使chrony重新選擇時間源,不知道這個指令的意義是啥,和重新開機chrony有啥差別
chronyd -q 'server ntp.aliyun.com iburst'
還不如在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
遇到的問題
問題:虛拟機挂起後,時間不同步。
這裡可以看到,chronyc tracking的時候,
Ref time是正确的,但是system time并沒有修訂。是以同步時間是沒有問題的,但是沒有把系統的時間給修訂掉。
可以看到時間是慢慢調整,不是跳躍式的調整,此時相差時間太大,無法快速修訂。
通過chronyc makestep快速同步了system clock,但是RTC時間chrony并沒有間隔11分鐘,把系統時間同步到rtc上,手動執行hwclock -w才同步。是以為什麼rtc時間沒同步呢。
這個問題在上面的配置部分,Real time clock部分有解釋。但是為什麼時間同步了,system clock sysnchronized還是沒有變成yes,這裡可能是狀态的一個延遲問題。
問題:chronyc tracking,這裡的ref time是系統的時間,不是時間源的時間。
結論就是:
當makestep threshold limit中,limit是正值的時候,Backward time能躍進的修訂,但是Forward time慢慢修訂。
當是負值的時候,Backward time和Forward time都能躍進的修訂。
“Can't synchronise: no selectable sources” 這個不是關鍵問題,容易誤導人
問題:公網已經斷了,時間同步狀态顯示yes,然後MS的狀态是^*而不是^?
過了一個小時的時間,才判斷時間源無效。此時local stratum 10生效。
因為我master1 時間和其他時間源相差過大,是以這裡是x的狀态,如果我把master2其他源去掉後重新開機
如下圖。就是簡單的區域網路ntp client和server關系。當然備份的考慮,我這裡辦本地的ntp server可以多個。
下面一個問題就是多個ntp server的問題
問題:當叢集的ntp server 外網不可用時,啟用本地參考模式,此時對于用戶端來說,時間源不可用。
當我把其中一個伺服器上的chrony服務停掉後
發的包,181和183reference id封包裡都是127.127.1.1,但是落地顯示不一樣呀。
結論就是:
如果所有ntp server都不能有自己的time source的話,就是不配置server,local preference mode,隻能有一個,local stratum xxx 隻能配置在一個server上,也就是隻能有一個server。是以盡量保證ntp server可以通路internet的時間源,然後選擇一個ntp server配置local stratum用來保底。