Wie kann ich mit libvirt Zeit für einen wieder aufgenommenen KVM-Gast gewinnen?

18

Auf meinem Host verwende ich libvirt und einen KVM-Gast. Wenn der Host heruntergefahren wird, hält libvirt den Gast an. Wenn der Host startet, setzt libvirt den Gast fort. Das Problem ist, wenn der Gast zum Beispiel nach 24 Stunden suspendiert und wieder aufgenommen wird, dann liegt die Gastzeit bei 24 Stunden in der Vergangenheit.

Ich dachte, dass das Problem vielleicht bei der Clock-Quelle liegt, aber sie ist bereits auf "kvm-clock" eingestellt.

$ 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
quelle

Antworten:

11

Das Problem

Ich habe das gleiche Problem und habe keine gute Lösung gefunden. Folgendes habe ich gefunden:

Das Problem ist, dass nach dem Fortsetzen die System- und Hardware-Uhrzeiten auf dem Gast unterschiedlich sind:

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

Auf dem Host sind sie sich einig:

root @ four: ~ # date; hwclock
Sa 11.10. 13:11:35 UTC 2014
Sat Okt 11 13:11:36 2014 -1.000372 Sekunden

Die Lösung wäre, hwclock --hctosysauf dem Gast zu laufen, nachdem er wieder aufgenommen wurde. Ich habe jedoch keine Möglichkeit gefunden, dies nur mit Änderungen am Gastsystem zu tun, da der Gast nicht bemerkt, dass es angehalten und fortgesetzt wird.

QEmu Guest Agent

Es besteht die Möglichkeit, auf dem Gast eine Software namens QEmu Guest Agent auszuführen und vom Host zu benachrichtigen, dass die Systemuhr des Gasts von der Hardwareuhr des Gasts aktualisiert werden soll. Auf der Seite wird jedoch erwähnt, dass der Gastagent den Host und den Gast aufgrund von Problemen mit einem JSON-Parser für gegenseitige Angriffe anfällig macht (zumindest glaube ich, dass der betroffene Code auch auf dem Host ausgeführt wird, da bin ich mir nicht sicher ). Wie auch immer, hier ist, wie man das einrichtet:

  1. Richten Sie für den Agenten einen virtuellen seriellen Kanal ein, wie im libvirt-Wiki beschrieben (siehe auch Dokumentation zum libvirt-Domain-Format ).

  2. Nachdem der serielle Kanal verfügbar ist, installieren und starten Sie den QEmu Guest Agent auf dem Gast. (Debian:. apt-get install --no-install-recommends qemu-guest-agent)

  3. Lösen Sie den Zeitversatz durch Anhalten, Warten und Fortsetzen aus. Führen Sie dann den folgenden Befehl auf dem Host aus, um ihn zu korrigieren: virsh qemu-agent-command backup '{"execute":"guest-set-time"}'Die verwendete Wiki-Seite virsh qemu-agent-commandwird nicht unterstützt , aber ich habe keinen anderen Befehl gefunden, der die Aufgabe erledigt.

Ich fand zwei Diskussionen über die Automatisierung des Aufrufs zum guest-set-timeFortsetzen des Suspendierens in libvirt :

Soweit ich sehen konnte, wurde jedoch noch nichts implementiert.

Ich habe im Wiki von stoney-cloud.org Informationen darüber gefunden, wie ich Befehle an den Gastagenten übermitteln kann .

Ich habe auch versucht, tickpolicy="catchup"die libvirt-Timer-Konfiguration einzustellen, aber das hat das Problem nicht gelöst.

NTP

Eine Alternative zur Verwendung des Agenten besteht darin, einen ntp-Daemon zu verwenden oder ntpdate von einem Cron-Job aus regelmäßig aufzurufen. Letzteres würde ich nicht empfehlen, da es dazu führen kann, dass die Zeit nach hinten läuft , was Programme verwirren kann (zum Beispiel versucht der Dovecot IMAP-Server nicht, die Zeit nach hinten zu handhaben und kann terminieren).

Ich habe die folgenden NTP-Daemons ausprobiert:

  • openntpd : Korrigiert die Zeit in meinem Test sehr langsam mit einer Geschwindigkeit von ungefähr 2 Sekunden pro 60 Minuten. Der Zeitversatz betrug 120 Sekunden. Außerdem gibt openntpd einen Fehler aus, wenn der Zeitversatz zu groß ist und in meinem Test die Zeit in diesem Fall nicht vollständig korrigiert werden kann. Vorteile von openntpd: Kann als normaler Benutzer in chroot ausgeführt werden.

  • chronisch : Korrigiert in meinem Test einen Zeitversatz von 120 Sekunden in 30 Minuten. chrony kann so konfiguriert werden, dass es als normaler Benutzer ausgeführt wird. Chroot-Unterstützung ist nicht implementiert. Das NTP-Server-Abfrageintervall kann für jeden NTP-Server konfiguriert werden.

  • systemd-timesyncd : Korrigiert in meinem Test einen Zeitversatz von 120 Sekunden in 30 Sekunden. Läuft standardmäßig als normaler Benutzer. Das Abfrageintervall von NTP-Servern erhöht sich jedoch auf 2048 Sekunden, sodass im schlimmsten Fall eine Unterbrechung / Wiederaufnahme erst 34 Minuten nach der Wiederaufnahme erkannt wird. Dies scheint nicht konfigurierbar zu sein. Außerdem habe ich beobachtet, dass timesyncd die Zeit zurückspringt, was die gleichen Probleme verursacht wie das Aufrufen von ntpdate in einem Cron (siehe oben).

chrony löst das problem. Openntpd ist nicht geeignet, weil seine Korrekturrate zu niedrig ist und nicht konfigurierbar zu sein scheint. Auch systemd-timesyncd löst das Problem nicht vollständig, da das Abfrageintervall nicht konfigurierbar ist.

Ich habe die folgenden Debian-Versionen der NTP-Dämonen getestet: openntpd 20080406p-10, chrony 1.30-1 und systemd 215-5 + b1.

Mailand
quelle
3

Viele Virtualisierungs-Host-Vorgänge auf dem Gast können zu einer Pause führen. Dies wirkt sich negativ auf die Systemuhr des Gastes aus. Das Klonen einer VM führt beispielsweise zu einer Pause beim Klonen. Die Gästeuhr steht danach hinten. Damit NTP die Uhr synchronisiert, müssen Sie den Gast neu starten - keine gute Lösung für alle Fälle. Alternativ könnte man ntpd im Gast einfach neu starten, aber das ist auch nicht optimal. Idealerweise muss ein Ereignis (wieder aufgenommene VM) verfügbar sein, das Sie optional für diese Art der Korrektur für den Gast verwenden können.

Nachdem ich einige Zeit damit verbracht hatte, dies zu erforschen, entschied ich mich, die Host-Uhr direkt als Referenz für die Systemuhr des CentOS 7-Gastbetriebssystems zu verwenden.

Anstatt ntpd im Gast auszuführen, entschied ich, dass ich alle 15 Minuten über crontab die Systemuhr des Gastes von der Hardwareuhr des Gastes aus einstellte. Die Hardwareuhr des Gasts zeigt die Zeit auf dem Virtualisierungshost an, die über ntpd gesteuert wird, das auf dem Virtualisierungshost ausgeführt wird. Dies bietet mir zuverlässige Zeit im Gastbetriebssystem. Im schlimmsten Fall ist die Uhr möglicherweise bis zu 15 Minuten lang ausgeschaltet, bevor sie nach der Wiederaufnahme des Gastbetriebs zur richtigen Zeit synchronisiert wird.

# crontab -e

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

Es wäre viel besser, ein Ereignis auf dem Gast verfügbar zu haben, das eine Zeitsynchronisierung auslöst, wenn der Gast wieder aufgenommen wird, aber anscheinend ist das nicht verfügbar. Der Crontab-Ansatz ist eine Problemumgehung, da alle 15 Minuten ein Hwclock-Aufruf erfolgt. Es erledigt den Job, aber nicht so elegant, wie ich es gerne hätte.

zman58
quelle
2

kvm-Uhr - Synchronisierungen der Gast Zeit Host Zeit auf Gaststart . Sie sollten den Gast-Client und den NTP-Client verwenden und herunterfahren / starten, anstatt Suspend / Resume zu verwenden.

dyasny
quelle
Ja, ich kann die Synchronisierung beim Start bestätigen, da beim Herunterfahren / Starten des Gasts alles in Ordnung ist. Die Verwendung von ntp ist aus vielen Gründen keine Lösung (es ist eine Problemumgehung, es kommt in Panik, wenn der Zeitunterschied groß ist und der Zugriff auf den Zeitserver erforderlich ist). Ich suche nach einer Möglichkeit, das Problem mit Suspend / Resume zu lösen, da dies eine interessante, nette und standardmäßige Option in libvirt ist.
Hristo Hristov
suspend ist 1) VM-Status in Datei migrieren und 2) zerstören. Wenn Sie aus dem Standby-Modus fortfahren, wird der VM-Status wiederhergestellt (von der Datei zurück in den VM-Speicher migriert). Dieser Status enthält den aktuellen Zeitstempel. Also ja, es ist die Standardeinstellung, aber nein, das Timing spielt immer noch eine Rolle, und die Zeit muss irgendwo herkommen, und hier sollte NTP hereinkommen. Ich bezweifle, dass eine andere Taktquelle hilfreich ist, aber Sie können es mit acpi_pm versuchen.
dyasny
Sie sollten NTP im Gast nicht verwenden .
Brian Cain
4
@Brian Cain Das ist höchst umstritten, insbesondere ohne Erklärung oder Begründung für die Aussage. Um einen Profflink bereitzustellen: docs.redhat.com/docs/en-US/…
dyasny
2

libvirt unterstützt die Zeitsynchronisation von Gästen seit 2015 . Auf Debian Stretch und später suchen Sie nach einer Option SYNC_TIMEin /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

Sie können die Zeitsynchronisierung vom Host-System aus testen mit:

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

Dieser Befehl sollte {"return":{}}bei Erfolg zurückkehren.

Jakob
quelle
0

Ich verwende eine ähnliche Methode für die Synchronisierung der Zeit nach dem Anhalten / Fortsetzen der VM, aber ich denke, es ist besser zu raten, dass die Synchronisierung in die richtige Richtung erfolgen sollte und länger als eine kurze Differenz ist, die durch NTPD behoben werden könnte.

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

PS. Laut dem neuen Änderungsprotokoll von Centos 6.7 könnte dies automatisch mit nur einer kvm-Clock-Quelle erfolgen.

Jan Horacek
quelle