¿Cómo mantener el tiempo en el invitado KVM reanudado con libvirt?

18

En mi host estoy usando libvirt y un invitado KVM. Cuando el host se apaga, libvirt suspende al invitado. Cuando el host se está iniciando, libvirt reanuda al invitado. El problema es que si el invitado se suspende y se reanuda después de 24 horas, por ejemplo, entonces el tiempo del invitado es de 24 horas en el pasado.

Pensé que tal vez el problema es con la fuente del reloj, pero ya está configurado en "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
Hristo Hristov
fuente

Respuestas:

11

El problema

Tengo el mismo problema y no he encontrado una buena solución. Esto es lo que encontré:

El problema es que después de reanudar, los tiempos de reloj del sistema y hardware en el invitado son diferentes:

root @ guest: ~ # fecha; hwclock
Sáb 11 oct 13:09:38 UTC 2014
Sáb 11 de octubre 13:10:42 2014 -0.454380 segundos

En el host, están de acuerdo:

raíz @ cuatro: ~ # fecha; hwclock
Sáb 11 de octubre 13:11:35 UTC 2014
Sáb 11 de octubre 13:11:36 2014 -1.000372 segundos

La solución sería ejecutar hwclock --hctosysel invitado después de que se haya reanudado. Sin embargo, no he encontrado una manera de hacer esto solo con cambios en el sistema invitado, ya que el invitado no se da cuenta de que se suspende y se reanuda.

Agente invitado de QEmu

Existe la posibilidad de ejecutar un software llamado QEmu Guest Agent en el invitado y notificar desde el host para actualizar el reloj del sistema invitado desde el reloj de hardware invitado. Sin embargo, la página menciona que el agente invitado hace que el host y el invitado sean vulnerables a los ataques entre sí debido a problemas con un analizador JSON (al menos creo que el código afectado también se ejecuta en el host, no estoy seguro de eso ) De todos modos, aquí está cómo configurar eso:

  1. Configure un canal serie virtio para el agente como se menciona en la wiki de libvirt (consulte también la documentación del formato de dominio de libvirt ).

  2. Una vez que el canal en serie esté disponible, instale e inicie el QEmu Guest Agent en el invitado. (Debian:. apt-get install --no-install-recommends qemu-guest-agent)

  3. Dispare el reloj compensado suspendiendo, esperando y reanudando. Luego ejecute el siguiente comando en el host para corregirlo: virsh qemu-agent-command backup '{"execute":"guest-set-time"}'la página wiki que usa novirsh qemu-agent-command es compatible , pero no he encontrado ningún otro comando que haga el trabajo.

Encontré dos discusiones sobre la automatización dentro de libvirt de la llamada a guest-set-timereanudar desde la suspensión:

Sin embargo, nada se ha implementado todavía por lo que pude ver.

Encontré información sobre cómo enviar comandos al agente invitado en wiki de stoney-cloud.org .

También intenté establecer tickpolicy="catchup"la configuración del temporizador libvirt pero esto no resolvió el problema.

NTP

Una alternativa al uso del agente sería usar un demonio ntp o llamar periódicamente a ntpdate desde un trabajo cron. No recomendaría este último, ya que puede hacer que el tiempo retroceda, lo que puede confundir a los programas (por ejemplo, el servidor Dovecot IMAP no intenta manejar el tiempo que retrocede y puede terminar).

Probé los siguientes demonios ntp:

  • openntpd : corrige el tiempo muy lentamente a una velocidad de aproximadamente 2 segundos por 60 minutos en mi prueba. El tiempo de compensación fue de 120 segundos. Además, openntpd arroja un error si el desplazamiento de tiempo es demasiado grande y, en mi prueba, falla completamente en corregir el tiempo en ese caso. Ventajas de openntpd: puede ejecutarse como usuario normal en chroot.

  • chrony : corrige un desfase de 120 segundos en 30 minutos en mi prueba. chrony se puede configurar para ejecutarse como usuario normal. El soporte chroot no está implementado. El intervalo de sondeo del servidor NTP se puede configurar para cada servidor NTP.

  • systemd-timesyncd : corrige un desplazamiento de tiempo de 120 segundos en 30 segundos en mi prueba. Se ejecuta como usuario normal de forma predeterminada. Sin embargo, el intervalo de sondeo de los servidores NTP aumenta hasta 2048 segundos, por lo que no se detectaría una suspensión / reanudación hasta 34 minutos después de la reanudación en el peor de los casos. Esto no parece ser configurable. Además, he observado que timesyncd retrocede el tiempo, lo que causa los mismos problemas que llamar a ntpdate en un cron (ver arriba).

Chrony resuelve el problema. Openntpd no es adecuado porque su tasa de corrección es demasiado baja y no parece ser configurable. systemd-timesyncd tampoco resuelve completamente el problema, porque su intervalo de sondeo no es configurable.

Probé las siguientes versiones de Debian de los demonios NTP: openntpd 20080406p-10, chrony 1.30-1 y systemd 215-5 + b1.

Milán
fuente
3

Muchas operaciones de host de virtualización en el invitado pueden provocar una pausa: reanudar. Esto afectará negativamente el reloj del sistema en el invitado. Por ejemplo, clonar una VM resulta en una pausa mientras se clona. El reloj de invitados después está atrasado. Para que NTP sincronice el reloj, debe reiniciar el invitado; no es una buena solución en todos los casos con seguridad. Alternativa, podría simplemente reiniciar ntpd en el invitado, pero eso tampoco es óptimo. Idealmente, debe haber un evento (VM reanudado) disponible que pueda usar opcionalmente para este tipo de corrección para el invitado.

Después de pasar un tiempo investigando esto, decidí usar el reloj del host directamente como referencia para el reloj del sistema del sistema operativo invitado CentOS 7.

En lugar de ejecutar ntpd en el invitado, decidí que cada 15 minutos establecería, a través de crontab, el reloj del sistema invitado desde el reloj de hardware del invitado. El reloj de hardware del invitado refleja el tiempo en el host de virtualización que se controla a través de ntpd que se ejecuta en el host de virtualización. Esto me proporciona un tiempo confiable en el sistema operativo invitado. En el peor de los casos, el reloj puede estar apagado por hasta 15 minutos antes de sincronizarse con la hora correcta después de reanudar al invitado.

# crontab -e

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

Sería mucho mejor tener un evento disponible en el invitado que iniciaría una sincronización de tiempo cuando se reanudó el invitado, pero aparentemente eso no está disponible. El enfoque crontab es una solución alternativa, ya que realiza una llamada hwclock cada 15 minutos. Hace el trabajo, pero no con tanta elegancia como me gustaría.

zman58
fuente
2

kvm-clock sincroniza la hora del invitado con la hora del host en el inicio del invitado . Debe usar un cliente ntp en el invitado y apagar / iniciar en lugar de usar suspender / reanudar.

dyasny
fuente
Sí, puedo confirmar que se sincroniza al inicio, porque cuando apago / inicio el invitado, todo está bien. Usar ntp no es una solución por muchas razones (es una solución alternativa, entra en pánico cuando la diferencia horaria es enorme, requiere acceso al servidor horario). Estoy buscando una manera de resolver el problema con suspender / reanudar, porque esta es una opción interesante, agradable y predeterminada en libvirt.
Hristo Hristov
suspender es 1) migrar el estado de la VM al archivo y 2) destruir. Cuando reanuda la suspensión, el estado de la VM se restaura (migra del archivo a la memoria de la VM). Este estado incluirá la marca de tiempo actual. Entonces, sí, es el valor predeterminado, pero no, el tiempo sigue siendo importante, y el tiempo tiene que venir de algún lado, y aquí es donde debería entrar NTP. Dudo que otra fuente de reloj ayude, pero puede intentar con acpi_pm.
Dyasny
No debe usar NTP en el invitado .
Brian Cain el
44
@Brian Cain esto es muy discutible, especialmente sin explicación o razonamiento detrás de la declaración. Para proporcionar un enlace proff: docs.redhat.com/docs/en-US/…
dyasny
2

libvirt admite sincronización de tiempo de invitado desde 2015 . En Debian Stretch y luego busque la opción SYNC_TIMEen /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

Puede probar la sincronización horaria desde el sistema host con:

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

Este comando debería volver {"return":{}}al éxito.

Jakob
fuente
0

Utilizo una forma similar para sincronizar el tiempo después de suspender / reanudar VM, pero creo que es mejor tratar de adivinar, que debería sincronizarse en la dirección correcta y es más largo que una pequeña diferencia, que NTPD podría solucionar.

https://gist.github.com/jhrcz/7138803

PD. El nuevo registro de cambios de centos 6.7 dice que esto podría hacerse automáticamente con solo la fuente de reloj kvm-clock.

Jan Horacek
fuente