Azure 中的 Linux VM 時間同步
適用於:✔️ Linux VM ✔️ 彈性擴展集 ✔️ 統一擴展集
時間同步對於安全性和事件相互關聯而言相當重要。 有時候會使用它來進行分散式交易實作。 多個電腦系統之間的時間精確度是透過同步來達成。 同步可能會受到多種因素影響,包括重新開機以及時間來源和擷取時間的電腦之間的網路流量。
Azure 受到執行 Windows Server 2016 之基礎結構的支援。 Windows Server 2016 的演算法經過改善,用來修正時間和調整本機時鐘以便與 UTC 同步。 Windows Server 2016 的準確時間功能大幅改善了 VMICTimeSync 服務控管 VM 與主機以獲得準確時間的方式。 改善功能包括更精確的 VM 開始或 VM 還原初始時間,以及插斷延遲修正。
概觀
電腦時鐘精確度的衡量方式,是依據電腦時鐘與國際標準時間 (UTC) 時間標準的接近程度。 UTC 是由多國的精準原子鐘樣本所定義;原子鐘在 300 年內只會誤差一秒。 但是直接讀取 UTC 需使用專用的硬體。 替代方式為系統將時間伺服器同步為 UTC,並從其他電腦存取以提供延展性和強固性。 每部電腦都有持續運作的時間同步服務,知道需使用哪些時間伺服器,且會定期檢查電腦時鐘是否需要修正,並視需要調整時間。
Azure 主機會與內部 Microsoft 時間伺服器同步,這些時間伺服器會透過 GPS 天線從 Microsoft 所屬的 Stratum 1 裝置擷取時間。 Azure 中的虛擬機器可以依賴其主機將準確的時間 (「主機時間」) 傳遞至 VM,也可以由 VM 直接從時間伺服器取得時間,或結合兩種方式。
在獨立的硬體上,Linux OS 只會在開機時讀取主機硬體時鐘。 之後,則會使用 Linux 核心中的插斷計時器來維護時鐘。 在此設定中,時鐘會隨時間慢慢移動。 在 Azure 上的較新 Linux 發行版本中,VM 可以使用 Linux Integration Services (LIS) 隨附的 VMICTimeSync 提供者,更頻繁地從主機查詢時鐘更新。
虛擬機器與主機的互動也可能會影響時鐘。 進行記憶體保留維修期間,VM 會暫停最多 30 秒。 比方說,維修開始之前 VM 時鐘顯示上午 10:00:00,並持續 28 秒。 VM 繼續執行後,VM 上的時鐘仍會顯示上午 10:00:00,也就是有 28 秒的誤差。 為了修正這個誤差,VMICTimeSync 服務會監視主機上發生的狀況,並更新在 Linux VM 中當日時間時鐘以進行補償。
若沒有時間同步功能,VM 上的時鐘將會累積錯誤。 若只有一部 VM,除非工作負載需要高度精準的計時功能,否則不會造成顯著的影響。 但是在多數情況下,我們都有多部互相連接並使用時間來追蹤交易的 VM,而且整個部署中的時間必須保持一致。 當 VM 之間的時間有所不同,可能會產生下列影響:
- 驗證將會失敗。 Kerberos 這類安全性通訊協定或憑證相依的技術,仰賴整個系統中的時間維持一致。
- 如果記錄 (或其他資料) 認知的時間有所差異,便很難找出當中發生了什麼問題。 同一個事件看起來可能像發生在不同時間,導致難以建立相互關聯。
- 當時鐘有所誤差,計費功能也可能會計算錯誤。
設定選項
時間同步需要時間同步服務在 Linux VM 中執行,以及要同步處理的精確時間資訊來源。 一般而言,ntpd 或 chronyd 會用做時間同步服務,不過也有其他可以使用的開放原始碼時間同步服務。 精確的時間資訊來源可以是透過公用網際網路存取的 Azure 主機或外部時間服務。 如上所述,VMICTimeSync 服務本身不會在 Azure 主機與 Linux VM 之間提供進行中的時間同步,但主機維護暫停之後的情況除外。
在過去,使用 Linux 的大部分Azure Marketplace 映像都是以下列兩種方式之一設定:
- 預設不會執行任何時間同步服務
- ntpd 是以時間同步服務的形式執行,並針對透過網路存取的外部 NTP 時間來源進行同步處理。 例如,Ubuntu 18.04 LTS Marketplace 映像使用 ntp.ubuntu.com。
若要確認 ntpd 正確同步,請執行 ntpq -p
命令。
某些具有 Linux 的 Azure Marketplace 映像會變更為使用 chronyd 做為時間同步服務,而 chronyd 會設定為針對 Azure 主機 (而不是外部 NTP 時間來源) 進行同步處理。 Azure 主機時間通常是最佳的同步處理時間來源,因為其保持精確且可靠,並可以在沒有因透過公用網際網路存取外部 NTP 時間來源所存在的可變網路延遲情況下,進行存取。
VMICTimeSync 會平行使用,並提供兩個功能:
- 在主機維護事件之後立即更新 Linux VM 的當日時間時鐘
- 將 IEEE 1588 精確度時間通訊協定 (PTP) 硬體時鐘來源具現化為 /dev/ptp 裝置,以從 Azure 主機提供精確的當日時間。 可以將 Chronyd 設定為針對這個時間來源進行同步處理 (這是最新 Linux 映像中的預設設定)。 具有核心 4.11 版或更新版本的 Linux 發行版本 (或適用於 RHEL 7 的 3.10.0-693 版或更新版本) 支援 /dev/ptp 裝置。 對於不支援 Azure 主機時間 /dev/ptp 的舊版核心,只能對外部時間來源進行同步處理。
可以變更預設設定。 設定為使用 ntpd 且外部時間來源的較舊映像可以變更為使用 chronyd 和 Azure 主機時間的 /dev/ptp 裝置。 同樣地,可以將透過 /dev/ptp 裝置使用 Azure 主機時間的映像設定為在應用程式或工作負載需要時使用外部 NTP 時間來源。
工具和資源
您可以透過一些基本命令來檢查時間同步設定。 Linux 發行版本的文件會針對設定該發行版本時間同步的最佳方式提供更多詳細資料。
整合服務
檢查是否已載入整合服務 (hv_utils)。
$ sudo lsmod | grep hv_utils
您應該會看到類似如下的內容:
hv_utils 24418 0
hv_vmbus 397185 7 hv_balloon,hyperv_keyboard,hv_netvsc,hid_hyperv,hv_utils,hyperv_fb,hv_storvsc
檢查 PTP 時鐘來源
在新版的 Linux 中,會將對應於 Azure 主機的精確時間通訊協定 (PTP) 時鐘來源當做 VMICTimeSync 提供者的一部分來提供。 在舊版的 Red Hat Enterprise Linux 7.x 上,可下載 Linux Integration Services 並用來安裝已更新的驅動程式。 當 PTP 時鐘來源可供使用時,Linux 裝置的格式為 /dev/ptpx。
查看哪些 PTP 時鐘來源可供使用。
$ ls /sys/class/ptp
在此範例中,傳回的值是 ptp0,因此我們會使用該值來檢查時鐘名稱。 若要驗證裝置,請檢查時鐘名稱。
$ sudo cat /sys/class/ptp/ptp0/clock_name
這應該會傳回表示 Azure 主機的 hyperv
。
在某些 Linux VM 中,您可能會看到列出多部 PTP 裝置。 其中一個範例是針對加速網絡,Mellanox mlx5 驅動程式也會建立 /dev/ptp 裝置。 因為每次 Linux 開機時,初始化順序可能會不同,所以對應至 Azure 主機的 PTP 裝置可能是 /dev/ptp0
或 /dev/ptp1
,因此很難以正確的時鐘來源來設定 chronyd
。 若要解決此問題,最新的 Linux 映像有 udev
規則,可建立與 Azure 主機對應的任何 /dev/ptp
輸入的符號連結 /dev/ptp_hyperv
。 應將 Chrony 一律設定為使用此 /dev/ptp_hyperv
符號連結,而不是 /dev/ptp0
或 /dev/ptp1
。
如果您在未建立 /dev/ptp_hyperv
裝置上發生問題,可以使用 udev
規則和下列步驟進行設定:
注意:大部分的 Linux 發行版本都不應需要此 udev 規則,因為它已在較新版本的 systemd 中進行實作
建立 udev
規則檔案:
$ sudo cat > /etc/udev/rules.d/99-ptp_hyperv.rules << EOF
ACTION!="add", GOTO="ptp_hyperv"
SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK += "ptp_hyperv"
LABEL="ptp_hyperv"
EOF
使用下列項目重新開機虛擬機器或重新載入 udev
規則:
$ sudo udevadm control --reload
$ sudo udevadm trigger --subsystem-match=ptp --action=add
chrony
在 Ubuntu 19.10 或更新版本和 Red Hat Enterprise Linux 8.x 上,chrony 已設定為使用 PTP 來源時鐘。 較舊的 Linux 版本會使用不支援 PTP 來源的網路時間通訊協定精靈 (ntpd),而不是 chrony。 若要在這些版本中啟用 PTP,必須使用下列陳述式,(在 chrony.conf 中) 手動安裝及設定 chrony:
refclock PHC /dev/ptp_hyperv poll 3 dpoll -2 offset 0 stratum 2
如果 /dev/ptp_hyperv 符號連結可用,請加以使用而不是使用 /dev/ptp0,以避免與 Mellanox mlx5 驅動程式所建立的 /dev/ptp 裝置混淆。
階層資訊不會自動從 Azure 主機傳達至 Linux 來賓。 上述設定行會指定將 Azure 主機時間來源視為 Stratum 2,進而讓 Linux 來賓將其本身回報為 Stratum 3。 如果您想要讓 Linux 來賓以不同的方式報告本身,您可以在設定行中變更階層設定。
根據預設,chronyd 會加速或放慢系統時鐘,以修正任何時間漂移。 如果漂移太多,則 chrony 無法修正漂移。 若要克服這個問題,如果漂移超過指定的臨界值,則可以變更 /etc/chrony.conf 中的 makestep
參數,以強制時間同步處理。
makestep 1.0 -1
在這裡,如果漂移大於 1 秒,則 chrony 會強制進行時間更新。 若要套用變更,請重新啟動 chronyd 服務:
$ sudo systemctl restart chronyd && sudo systemctl restart chrony
與 systemd-timesyncd 相關的時間同步訊息
在某些情況下,如果您仍在 syslog 中看到類似如下的訊息,則 systemd-timesyncd 服務可能仍處於啟用狀態,並嘗試在重新開機時進行同步:
systemd-timesyncd[945]: Network configuration changed, trying to establish connection.
Aug 1 12:59:45 vm-name systemd-timesyncd[945]: Network configuration changed, trying to establish connection.
Aug 1 12:59:45 vm-name systemd-timesyncd[945]: Network configuration changed, trying to establish connection.
Aug 1 12:59:45 vm-name systemd-timesyncd[945]: Network configuration changed, trying to establish connection.
Aug 1 12:59:45 vm-name systemd-timesyncd[945]: Network configuration changed, trying to establish connection.
Aug 1 12:59:45 vm-name systemd-timesyncd[945]: Synchronized to time server 185.125.190.56:123 (ntp.ubuntu.com)
您可以透過以下方式將其停用:
$ sudo systemctl disable systemd-timesyncd
在大部分情況下,systemd-timesyncd 會在開機期間嘗試,但一旦 chrony 啟動,其就會覆寫並成為預設的時間同步來源。
如需 Ubuntu 和 NTP 的詳細資訊,請參閱時間同步處理。
如需 Red Hat 和 NTP 的詳細資訊,請參閱設定 NTP。
如需 chrony 的詳細資訊,請參閱使用 chrony。
systemd
在 19.10 之前的 SUSE 和 Ubuntu 版本上,會使用 systemd 設定時間同步。 如需 Ubuntu 的詳細資訊,請參閱時間同步處理。 如需 SUSE 的詳細資訊,請參閱 SUSE Linux Enterprise Server 12 SP3 版本資訊中的第 4.5.8 節。
Cloud-init
使用 cloud-init 來佈建 VM 的映像可以使用 ntp
區段來設定時間同步服務。 cloud-init 安裝 chrony 並將其設定為使用 Ubuntu VM 之 PTP 時鐘來源的範例:
#cloud-config
ntp:
enabled: true
ntp_client: chrony
config:
confpath: /etc/chrony/chrony.conf
packages:
- chrony
service_name: chrony
template: |
## template:jinja
driftfile /var/lib/chrony/chrony.drift
logdir /var/log/chrony
maxupdateskew 100.0
refclock PHC /dev/ptp_hyperv poll 3 dpoll -2 offset 0 stratum 2
makestep 1.0 -1
然後,您可以對上述 cloud-config 進行 base64,以便在 ARM 範本的 osProfile
區段中使用:
[Convert]::ToBase64String((Get-Content -Path ./cloud-config.txt -Encoding Byte))
"osProfile": {
"customData": "I2Nsb3VkLWNvbmZpZwpudHA6CiAgZW5hYmxlZDogdHJ1ZQogIG50cF9jbGllbnQ6IGNocm9ueQogIGNvbmZpZzoKICAgIGNvbmZwYXRoOiAvZXRjL2Nocm9ueS9jaHJvbnkuY29uZgogICAgcGFja2FnZXM6CiAgICAgLSBjaHJvbnkKICAgIHNlcnZpY2VfbmFtZTogY2hyb255CiAgICB0ZW1wbGF0ZTogfAogICAgICAgIyMgdGVtcGxhdGU6amluamEKICAgICAgIGRyaWZ0ZmlsZSAvdmFyL2xpYi9jaHJvbnkvY2hyb255LmRyaWZ0CiAgICAgICBsb2dkaXIgL3Zhci9sb2cvY2hyb255CiAgICAgICBtYXh1cGRhdGVza2V5IDEwMC4wCiAgICAgICByZWZjbG9jayBQSEMgL2Rldi9wdHBfaHlwZXJ2IHBvbGwgMyBkcG9sbCAtMgogICAgICAgbWFrZXN0ZXAgMS4wIC0x"
}
如需 Azure 上 cloud-init 的詳細資訊,請參閱 Azure 中 Linux VM 的 cloud-init 支援概觀。
下一步
如需詳細資訊,請參閱 Windows Server 2016 的準確時間。