Comment garder le temps sur l'invité KVM repris avec libvirt?

18

Sur mon hôte, j'utilise libvirt et un invité KVM. Lorsque l'hôte s'arrête, libvirt suspend l'invité. Lorsque l'hôte démarre, libvirt reprend l'invité. Le problème est, si l'invité est suspendu et repris après 24 heures par exemple, alors le temps d'invité est de 24 heures dans le passé.

Je pensais que le problème venait peut-être de la source d'horloge, mais il était déjà réglé sur "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
la source

Réponses:

11

Le problème

J'ai le même problème et je n'ai pas trouvé de bonne solution. Voici ce que j'ai trouvé:

Le problème est qu'après la reprise, les heures d'horloge système et matérielle sur l'invité sont différentes:

root @ guest: ~ # date; hwclock
Sam.11 oct.13: 09: 38 UTC 2014
Sam.11 oct 13:10:42 2014 -0.454380 secondes

Sur l'hôte, ils conviennent:

root @ four: ~ # date; hwclock
Sam.11 oct 13:11:35 UTC 2014
Sam.11 oct 13:11:36 2014 -1.000372 secondes

La solution serait de s'exécuter hwclock --hctosyssur l'invité après sa reprise. Cependant, je n'ai pas trouvé de moyen de le faire avec des modifications sur le système invité uniquement, car l'invité ne remarque pas qu'il est suspendu et repris.

Agent invité QEmu

Il est possible d'exécuter un logiciel appelé QEmu Guest Agent sur l'invité et de notifier à l'hôte de mettre à jour l'horloge du système invité à partir de l'horloge matérielle de l'invité. Cependant, la page mentionne que l' agent invité rend l'hôte et l'invité vulnérables aux attaques les uns des autres en raison de problèmes avec un analyseur JSON (au moins je pense que le code affecté est également exécuté sur l'hôte, je ne suis pas sûr de cela ). Quoi qu'il en soit, voici comment configurer cela:

  1. Configurez un canal série virtio pour l'agent comme mentionné dans le wiki libvirt (voir aussi la documentation sur le format de domaine libvirt ).

  2. Une fois le canal série disponible, installez et démarrez l'agent invité QEmu sur l'invité. (Debian:. apt-get install --no-install-recommends qemu-guest-agent)

  3. Déclenchez le décalage d'horloge en suspendant, en attendant et en reprenant. Exécutez ensuite la commande suivante sur l'hôte pour la corriger: virsh qemu-agent-command backup '{"execute":"guest-set-time"}'La page wiki qui utilise virsh qemu-agent-commandn'est pas prise en charge , mais je n'ai trouvé aucune autre commande qui fait le travail.

J'ai trouvé deux discussions sur l'automatisation dans libvirt de l'appel à la guest-set-timereprise de la suspension:

Cependant, rien n'a été mis en œuvre pour autant que je sache.

J'ai trouvé des informations sur la façon de soumettre des commandes à l'agent invité sur le wiki de stoney-cloud.org .

J'ai également essayé de définir tickpolicy="catchup"la configuration de la minuterie libvirt mais cela n'a pas résolu le problème.

NTP

Une alternative à l'utilisation de l'agent serait d'utiliser un démon ntp ou d'appeler ntpdate périodiquement à partir d'un travail cron. Je ne recommanderais pas ce dernier, car cela peut faire reculer le temps, ce qui peut perturber les programmes (par exemple, le serveur Dovecot IMAP n'essaie pas de gérer le temps en arrière et peut se terminer).

J'ai essayé les démons ntp suivants:

  • openntpd : Corrige le temps très lentement à un rythme d'environ 2 secondes toutes les 60 minutes dans mon test. Le décalage horaire était de 120 secondes. En outre, openntpd génère une erreur si le décalage horaire est trop important et, dans mon test, ne parvient pas à corriger l'heure dans ce cas. Avantages de openntpd: peut fonctionner en tant qu'utilisateur régulier dans chroot.

  • chrony : corrige un décalage horaire de 120 secondes en 30 minutes dans mon test. chrony peut être configuré pour fonctionner en tant qu'utilisateur normal. le support de chroot n'est pas implémenté. L'intervalle d'interrogation du serveur NTP peut être configuré pour chaque serveur NTP.

  • systemd-timesyncd : corrige un décalage horaire de 120 secondes en 30 secondes dans mon test. S'exécute en tant qu'utilisateur normal par défaut. Cependant, l'intervalle d'interrogation des serveurs NTP augmente jusqu'à 2048 secondes, de sorte qu'une suspension / reprise ne sera détectée que 34 minutes après la reprise dans le pire des cas. Cela ne semble pas être configurable. De plus, j'ai observé que timesyncd recule le temps, ce qui provoque les mêmes problèmes que d'appeler ntpdate dans un cron (voir ci-dessus).

chrony résout le problème. Openntpd ne convient pas car son taux de correction est trop faible et ne semble pas configurable. systemd-timesyncd ne résout pas non plus entièrement le problème, car son intervalle d'interrogation n'est pas configurable.

J'ai testé les versions Debian suivantes des démons NTP: openntpd 20080406p-10, chrony 1.30-1 et systemd 215-5 + b1.

Milan
la source
3

De nombreuses opérations d'hôte de virtualisation sur l'invité peuvent entraîner une pause - reprise. Cela aura un effet négatif sur l'horloge système de l'invité. Par exemple, le clonage d'une machine virtuelle entraîne une pause lors du clonage. L'horloge d'invité est derrière. Pour que NTP synchronise l'horloge, vous devez ensuite redémarrer l'invité - ce n'est pas une bonne solution dans tous les cas, bien sûr. Alternativement, vous pouvez simplement redémarrer ntpd dans l'invité, mais ce n'est pas optimal non plus. Idéalement, il doit y avoir un événement (reprise de la machine virtuelle) que vous pouvez éventuellement utiliser pour ce type de correction pour l'invité.

Après avoir passé un peu de temps à rechercher cela, j'ai décidé d'utiliser l'horloge hôte directement comme référence pour l'horloge du système d'exploitation invité CentOS 7.

Au lieu d'exécuter ntpd dans l'invité, j'ai décidé que toutes les 15 minutes je définirais, via crontab, l'horloge du système invité à partir de l'horloge matérielle de l'invité. L'horloge matérielle de l'invité reflète l'heure sur l'hôte de virtualisation qui est contrôlée via ntpd s'exécutant sur l'hôte de virtualisation. Cela me donne un temps fiable dans le système d'exploitation invité. Dans le pire des cas, l'horloge peut être désactivée jusqu'à 15 minutes avant d'être synchronisée à l'heure appropriée après la reprise de l'invité.

# crontab -e

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

Il serait préférable d'avoir un événement disponible sur l'invité qui déclencherait une synchronisation de l'heure lorsque l'invité a repris, mais apparemment, cela n'est pas disponible. L'approche crontab est une solution de contournement en ce sens qu'elle effectue un appel hwclock toutes les 15 minutes. Il fait le travail, mais pas aussi élégamment que je le souhaiterais.

zman58
la source
2

kvm-clock synchronise l'heure de l'invité avec l'heure de l'hôte au démarrage de l' invité . Vous devez utiliser et client ntp dans l'invité, et arrêter / démarrer au lieu d'utiliser suspendre / reprendre.

Dyasny
la source
Oui, je peux confirmer qu'il se synchronise au démarrage, car quand je fais un arrêt / démarrage de l'invité, tout va bien. L'utilisation de ntp n'est pas une solution pour de nombreuses raisons (c'est une solution de contournement, elle panique lorsque le décalage horaire est énorme, elle nécessite un accès au serveur de temps). Je cherche un moyen de résoudre le problème avec la suspension / reprise, car c'est une option intéressante, agréable et par défaut dans libvirt.
Hristo Hristov
suspendre est 1) migrer l'état de la machine virtuelle vers un fichier et 2) détruire. Lorsque vous quittez la suspension, l'état de la machine virtuelle est restauré (migré du fichier vers la mémoire de la machine virtuelle). Cet état inclura l'horodatage actuel. Donc oui, c'est par défaut, mais non, le timing est toujours important, et le temps doit venir de quelque part, et c'est là que NTP devrait entrer. Je doute qu'une autre source d'horloge aidera mais vous pouvez essayer avec acpi_pm.
dyasny
Vous ne devez pas utiliser NTP dans l'invité .
Brian Cain,
4
@Brian Cain, cela est très discutable, surtout sans explication ni raisonnement derrière la déclaration. Pour fournir un profflink: docs.redhat.com/docs/en-US/…
dyasny
2

libvirt prend en charge la synchronisation de l'heure des invités depuis 2015 . Sur Debian Stretch et recherchez plus tard l'option SYNC_TIMEdans /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

Vous pouvez tester la synchronisation de l'heure à partir du système hôte avec:

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

Cette commande devrait revenir {"return":{}}en cas de succès.

Jakob
la source
0

J'utilise une manière similaire pour synchroniser le temps après la suspension / reprise de la machine virtuelle, mais je pense qu'il vaut mieux essayer de deviner, qu'il devrait se synchroniser dans la bonne direction et est plus long que la courte différence, qui pourrait être corrigée par NTPD.

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

PS. Le nouveau changelog de centos 6.7 indique que cela pourrait être fait automatiquement avec seulement une source d'horloge d'horloge kvm.

Jan Horacek
la source