问题

问题

在我的主机上,我使用 libvirt 和 KVM 客户机。当主机关闭时,libvirt 会暂停客户机。当主机启动时,libvirt 会恢复客户机。问题是,如果客户机被暂停并在 24 小时后恢复,那么客户机时间就是 24 小时前。

我认为问题可能出在时钟源上,但它已经设置为“kvm-clock”。

$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
kvm-clock tsc hpet acpi_pm 

$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
kvm-clock

答案1

问题

我遇到了同样的问题,但还没有找到好的解决办法。以下是我找到的:

问题是恢复后,客户机上的系统和硬件时钟时间不同:

root@guest:~# date; hwclock
Sat Oct 11 13:09:38 UTC 2014
Sat Oct 11 13:10:42 2014  -0.454380 seconds

在主持人方面,他们一致同意:

root@four:~# date; hwclock
Sat Oct 11 13:11:35 UTC 2014
Sat Oct 11 13:11:36 2014  -1.000372 seconds

解决方案是hwclock --hctosys在客户机恢复后在其上运行。但是,我还没有找到仅在客户机系统上进行更改的方法,因为客户机不会注意到它已暂停并恢复。

QEmu 访客代理

可以运行一个名为QEmu 访客代理在客户机上,并从主机通知从客户机硬件时钟更新客户机系统时钟。但是,该页面提到访客代理使主机和访客容易受到攻击由于 JSON 解析器的问题,彼此之间无法通信(至少我相信受影响的代码也在主机上运行,​​但我不确定)。无论如何,下面介绍如何进行设置:

  1. 按照libvirt 维基百科(也可以看看libvirt 域格式文档)。

  2. 串行通道可用后,在客户机上安装并启动 QEmu Guest Agent。(Debian:。apt-get install --no-install-recommends qemu-guest-agent

  3. 通过暂停、等待和恢复来触发时钟偏移。然后在主机上运行以下命令来更正它:virsh qemu-agent-command backup '{"execute":"guest-set-time"}'使用的 wiki 页面virsh qemu-agent-command不支持,但我还没有找到任何其他可以完成该工作的命令。

guest-set-time我发现了两篇关于在 libvirt 中自动执行从暂停到恢复的调用的讨论:

然而,据我所知,尚未有任何举措实施。

我找到了有关如何向客户代理提交命令的信息stoney-cloud.org 的维基

我也尝试过tickpolicy="catchup"设置libvirt 定时器配置但这并不能解决问题。

网络时间协议 (NTP)

使用代理的替代方法是使用 ntp 守护程序或定期从 cron 作业调用 ntpdate。我不推荐后者,因为它会导致时间倒退,这可能会使程序(例如,Dovecot IMAP 服务器不会尝试处理时间回溯并可以终止)。

我尝试了以下 ntp 守护进程:

  • openntpd:在我的测试中,时间校正速度非常慢,大约为每 60 分钟 2 秒。时间偏移量为 120 秒。此外,openntpd如果时间偏移量太大,则会抛出错误,在我的测试中,在这种情况下完全无法纠正时间。 openntpd 的优点:可以在 chroot 中以普通用户身份运行。

  • 慢性的:在我的测试中,30 分钟内纠正了 120 秒的时间偏移。chrony 可以配置为以普通用户身份运行。未实现 chroot 支持。可以为每个 NTP 服务器配置 NTP 服务器轮询间隔。

  • systemd-timesyncd:在我的测试中,在 30 秒内更正了 120 秒的时间偏移。默认情况下以普通用户身份运行。但是,NTP 服务器的轮询间隔最多增加到 2048 秒,因此在最坏的情况下,直到恢复后 34 分钟才会检测到暂停/恢复。这似乎无法配置。此外,我观察到 timesyncd 将时间向后移动,这会导致与在 cron 中调用 ntpdate 相同的问题(参见上文)。

chrony 解决了这个问题。Openntpd 不太合适,因为它的修正率太低,而且似乎不可配置。systemd-timesyncd 也不能完全解决问题,因为它的轮询间隔不可配置。

我测试了以下 Debian 版本的 NTP 守护进程:openntpd 20080406p-10、chrony 1.30-1 和 systemd 215-5+b1。

答案2

客户机上的许多虚拟化主机操作都可能导致暂停 - 恢复。这将对客户机上的系统时钟产生负面影响。例如,克隆虚拟机会导致克隆过程中暂停。之后的客户机时钟会落后。要让 NTP 同步时钟,您需要重新启动客户机 - 当然,这在所有情况下都不是一个好的解决方案。或者,您可以重新启动客户机中的 ntpd,但这也不是最佳选择。理想情况下,需要有一个事件(虚拟机恢复)可用,您可以选择使用该事件对客户机进行此类更正。

在花了一些时间研究这个问题后,我决定直接使用主机时钟作为 CentOS 7 客户操作系统系统时钟的参考。

我决定每 15 分钟通过 crontab 从客户机的硬件时钟设置客户机系统时钟,而不是在客户机中运行 ntpd。客户机的硬件时钟反映了虚拟化主机上的时间,而虚拟化主机上的时间由在虚拟化主机上运行的 ntpd 控制。这为我提供了客户机操作系统中的可靠时间。最糟糕的情况是,在恢复客户机后,时钟可能会关闭长达 15 分钟,然后才能同步到正确的时间。

# crontab -e

0,15,30,45 * * * * /sbin/hwclock --hctosys

最好在客户机上设置一个事件,以便在客户机恢复时启动时间同步,但显然这是不可能的。crontab 方法是一种解决方法,它每 15 分钟进行一次 hwclock 调用。它可以完成工作,但不如我希望的那么优雅。

答案3

libvirt 支持客户机时间同步,自2015. 在 Debian Stretch 中,稍后查找SYNC_TIME选项/etc/default/libvirt-guests

# If non-zero, try to sync guest time on domain resume. Be aware, that
# this requires guest agent with support for time synchronization
# running in the guest. For instance, qemu-ga doesn't support guest time
# synchronization on Windows guests, but Linux ones. By default, this
# functionality is turned off.
#SYNC_TIME=1

您可以使用以下方法从主机系统内部测试时间同步:

virsh qemu-agent-command INSERT_YOUR_DOMAIN_HERE '{"execute":"guest-set-time"}'

此命令应{"return":{}}在成功时返回。

答案4

从 Linux 内核 4.11 开始有PTP-KVM(精确时间协议 - 内核虚拟机):点对点相当于网络时间协议 (NTP),但精度更高,适用于本地网络。Linux 主机系统将其当前时间导出到任何客户系统,以便高效读取/dev/ptp_kvm(或/dev/ptp0)。 慢性的能够在虚拟机内部使用它:

modprobe ptp_kvm
echo ptp_kvm >/etc/modules-load.d/ptp_kvm.conf
apt-get install chrony
echo "refclock PHC /dev/ptp0 poll 2" >/etc/chrony/conf.d/ptp.conf
systemctl restart chronyd

作为必要条件,主机上的时间也必须同步。

您可能还希望makestep 10 -根据您愿意容忍的差异进行配置:对于此示例,低于 10 秒的差异将通过加快 VM 时钟来进行调整,而更大的差异将导致所有(不良)后果。

我在RedHat 文档,所以向他们表示敬意。

相关内容