Назад | Перейти на главную страницу

Как сохранить время на возобновленном гостевом KVM с помощью libvirt?

На моем хосте я использую 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

Эта проблема

У меня такая же проблема, и я не нашел хорошего решения. Вот что я нашел:

Проблема в том, что после возобновления системные и аппаратные часы на гостевой системе различаются:

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. Настройте последовательный канал virtio для агента, как указано в libvirt вики (смотрите также документация по формату домена libvirt).

  2. После того, как последовательный канал станет доступен, установите и запустите гостевой агент QEmu на гостевой машине. (Debian: apt-get install --no-install-recommends qemu-guest-agent.)

  3. Запуск смещения часов путем приостановки, ожидания и возобновления. Затем выполните следующую команду на хосте, чтобы исправить это: virsh qemu-agent-command backup '{"execute":"guest-set-time"}' Страница вики, использующая virsh qemu-agent-command является неподдерживаемый, но я не нашел другой команды, которая бы выполняла эту работу.

Я нашел две дискуссии об автоматизации в libvirt вызова guest-set-time при возобновлении работы из приостановки:

Однако, насколько я понял, пока ничего не реализовано.

Я нашел информацию о том, как отправлять команды гостевому агенту на вики сайта stoney-cloud.org.

Я также пробовал установить tickpolicy="catchup" в Конфигурация таймера libvirt но это не решило проблему.

NTP

Альтернативой использованию агента может быть использование демона ntp или периодический вызов ntpdate из задания cron. Я бы не рекомендовал последнее, так как это может привести к тому, что время будет идти назад, что может сбить с толку программы (например, Сервер Dovecot IMAP не пытается обрабатывать время, идущее назад и можно прекратить).

Я пробовал следующие демоны ntp:

  • openntpd: Скорректирует время очень медленно, примерно 2 секунды за 60 минут в моем тесте. Смещение по времени составляло 120 секунд. Также, openntpd выдает ошибку, если смещение времени слишком велико и, в моем тесте, в этом случае совершенно не удается исправить время. Преимущества openntpd: Может работать как обычный пользователь в chroot.

  • хрония: В моем тесте исправлено смещение времени на 120 секунд за 30 минут. chrony можно настроить для работы от имени обычного пользователя. поддержка chroot не реализована. Интервал опроса сервера NTP можно настроить для каждого сервера NTP.

  • systemd-timesyncd: В моем тесте исправлено смещение времени на 120 секунд за 30 секунд. По умолчанию запускается как обычный пользователь. Однако интервал опроса серверов NTP увеличивается до 2048 секунд, так что в худшем случае приостановка / возобновление будет обнаружена только через 34 минуты после возобновления. Это не похоже на настройку. Кроме того, я наблюдал, как timesyncd сдвигает время назад, что вызывает те же проблемы, что и вызов ntpdate в cron (см. Выше).

хроны решают проблему. Openntpd не подходит, потому что его скорость коррекции слишком мала и не кажется настраиваемой. systemd-timesyncd также не решает полностью проблему, потому что его интервал опроса не настраивается.

Я протестировал следующие версии Debian демонов NTP: openntpd 20080406p-10, chrony 1.30-1 и systemd 215-5 + b1.

Многие операции хоста виртуализации на гостевой машине могут привести к паузе - возобновлению. Это отрицательно повлияет на системные часы гостя. Например, клонирование виртуальной машины приводит к паузе при клонировании. Гостевые часы потом уже позади. Чтобы заставить NTP синхронизировать часы, вам необходимо перезапустить гостевую систему - точно не во всех случаях. В качестве альтернативы вы можете просто перезапустить ntpd в гостевой системе, но это тоже не оптимально. В идеале должно быть доступно событие (возобновление виртуальной машины), которое вы могли бы дополнительно использовать для этого типа исправления для гостя.

Потратив некоторое время на изучение этого вопроса, я решил использовать часы хоста непосредственно в качестве эталона для системных часов гостевой ОС CentOS 7.

Вместо того, чтобы запускать ntpd в гостевой системе, я решил, что каждые 15 минут я буду устанавливать через crontab системные часы гостевой системы с аппаратных часов гостя. Аппаратные часы гостя отражают время на хосте виртуализации, которое контролируется через ntpd, запущенный на хосте виртуализации. Это обеспечивает мне надежное время в гостевой ОС. В худшем случае часы могут быть выключены на срок до 15 минут, прежде чем они будут синхронизированы с надлежащим временем после возобновления работы гостя.

# crontab -e

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

Было бы гораздо лучше иметь событие, доступное для гостя, которое инициировало бы синхронизацию времени, когда гость был возобновлен, но, очевидно, это недоступно. Подход crontab - это обходной путь, поскольку он выполняет вызов hwclock каждые 15 минут. Он выполняет свою работу, но не так элегантно, как хотелось бы.

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":{}} об успехе.

kvm-clock синхронизирует время гостя с временем хоста гостя запускать. Вы должны использовать и ntp-клиент в гостевой системе, а также выключение / запуск вместо приостановки / возобновления.

Я использую аналогичный способ синхронизации времени после приостановки / возобновления работы виртуальной машины, но я думаю, что лучше попытаться угадать, что она должна синхронизироваться в правильном направлении и длиннее короткой разницы, которую можно исправить с помощью NTPD.

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

PS. В новом журнале изменений centos 6.7 говорится, что это можно сделать автоматически, используя только источник часов kvm-clock.