在我的主机上,我使用 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 解析器的问题,彼此之间无法通信(至少我相信受影响的代码也在主机上运行,但我不确定)。无论如何,下面介绍如何进行设置:
按照libvirt 维基百科(也可以看看libvirt 域格式文档)。
串行通道可用后,在客户机上安装并启动 QEmu Guest Agent。(Debian:。
apt-get install --no-install-recommends qemu-guest-agent
)通过暂停、等待和恢复来触发时钟偏移。然后在主机上运行以下命令来更正它:
virsh qemu-agent-command backup '{"execute":"guest-set-time"}'
使用的 wiki 页面virsh qemu-agent-command
是不支持,但我还没有找到任何其他可以完成该工作的命令。
guest-set-time
我发现了两篇关于在 libvirt 中自动执行从暂停到恢复的调用的讨论:
- http://thread.gmane.org/gmane.comp.emulators.libvirt/92431(2014 年 2 月)
- http://thread.gmane.org/gmane.comp.emulators.libvirt.user/7051(2014 年 9 月)
然而,据我所知,尚未有任何举措实施。
我找到了有关如何向客户代理提交命令的信息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 文档,所以向他们表示敬意。