Проблема

Проблема

На моем хосте я использую 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 (по крайней мере, я полагаю, что затронутый код также выполняется на хосте, я в этом не уверен). В любом случае, вот как это настроить:

  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используетне поддерживается, но я не нашел другой команды, которая бы выполняла эту работу.

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

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

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

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

НТП

Альтернативой использованию агента было бы использование демона 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 (см. выше).

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

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

решение2

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

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

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

# crontab -e

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

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

решение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(Протокол точного времени - Виртуальная машина ядра):ПТПсопоставимо сНТП, но с большей точностью и для локальной сети. Хост-система 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 с будет скорректирована путем ускорения тактовой частоты виртуальной машины, в то время как большие разницы будут устранены со всеми (плохими) последствиями.

Я нашел это вДокументация RedHat, так что честь и хвала им.

Связанный контент