Время в виртуальной машине VMware отстаёт после suspend: что настроить в Tools, .vmx и гостевой ОС
Пока виртуальная машина VMware в suspend, её часы стоят. При resume их догоняет либо VMware Tools (разовая коррекция по часам хоста), либо служба времени гостя. Если не сработал никто, время «сбилось». Ниже: как найти виновного и какие параметры .vmx, w32tm и chrony выставить.
Почему часы виртуальной машины отстают после suspend
Мы в АйТи-Фреш обслуживаем офисную ИТ-инфраструктуру компаний до 50 рабочих мест, и вопрос «почему в виртуалке на ноутбуке время уехало» приходит стабильно после каждых длинных выходных. Механика простая. Когда вы делаете suspend, Workstation сохраняет состояние машины в файлы приостановленного состояния (.vmss и .vmem) в рабочей папке ВМ, а гостевая ОС перестаёт жить. Её часы тоже не идут. В понедельник вы нажимаете resume, и гость продолжает с того момента, на котором его заморозили: для него прошла секунда, а в реальности — 62 часа.
Дальше вариантов три. Первый: VMware Tools в момент resume делают разовую коррекцию и выставляют часы гостя по часам хоста. Это штатное поведение, и Broadcom в статье базы знаний про отключение синхронизации времени прямо перечисляет события, при которых Tools подтягивают время, даже если галочка периодической синхронизации снята: resume из suspend, vMotion, создание снапшота, откат на снапшот, сжатие диска и перезапуск службы VMware Tools (в том числе при перезагрузке гостя). Второй вариант: разовую коррекцию кто-то отключил, а в гостевой ОС нет рабочего источника времени, и часы стоят там, где их заморозили. Третий: Tools время поправили, но неверное, потому что часы самого хоста ушли.
Отдельная ловушка — путать два разных механизма. Периодическая синхронизация сверяет гостя с хостом раз в минуту. Разовая срабатывает на событиях жизненного цикла. По данным Broadcom, периодическая выключена по умолчанию, а разовая включена по умолчанию и рекомендована. Поэтому «снял галочку синхронизации, а время всё равно прыгнуло» — это нормальная картина, а не баг. Чтобы не повторяться про ESXi и vMotion, подробно эту пару переключателей для vSphere я разобрал в статье про отключение синхронизации времени в vSphere. Здесь — другой угол: что делать, когда после suspend время именно сбилось, и как это починить на Workstation, Player и в гостевых ОС.
Как понять, кто сейчас рулит часами гостя
Прежде чем править .vmx, я всегда выясняю три вещи: насколько ушло время, правильно ли оно на хосте и какой источник времени в госте считается рабочим. Первое — просто сравните часы гостя и хоста сразу после resume. Если гость отстаёт ровно на длительность suspend, коррекции не было вообще. Если гость показывает время хоста, но хост сам неверен, чините хост: гость лишь копирует его. Если гость ушёл вперёд или назад на небольшую величину (секунды или минуты), значит, коррекция была, но её перебила вторая служба времени.
Теперь источник времени в госте. В Windows это три запроса встроенной утилиты w32tm, их описание есть на learn.microsoft.com. Запускать от администратора:
w32tm /query /status
w32tm /query /source
w32tm /query /configurationВ выводе /query /source вы увидите источник: имя NTP-сервера, контроллер домена или, например, провайдер синхронизации виртуальной машины. На Hyper-V Microsoft в примере вывода показывает именно «VM IC Time Synchronization Provider», на VMware такого не будет, но принцип тот же: надо знать, кто выступает источником. Если источник — «Local CMOS Clock», гость вообще никого не слушает.
В Linux всё так же прямолинейно. Если стоит chrony, команда покажет, синхронизирован ли гость и каково смещение:
chronyc trackingВ выводе смотрите строки Stratum, System time (текущее смещение между NTP-часами и системными) и Leap status: значение Not synchronised означает, что гость ни к кому не привязан. Ещё один момент, который выручает при разборе: если в гостевой ОС одновременно работает VMware Tools с периодической синхронизацией и NTP-клиент, они дерутся за часы, и вы получаете не отставание, а мелкую «пилу». Broadcom формулирует это мягче, но смысл тот же: использовать надо одну форму периодической синхронизации, а при наличии нативной службы (NTP, chrony, W32Time) периодическую синхронизацию Tools отключить.
Как настроить синхронизацию VMware Tools: разовая коррекция и периодическая
Теперь собственно настройка. Общее правило, которое я использую: периодическую синхронизацию Tools не включаю, разовую оставляю включённой там, где у ВМ нет собственного надёжного источника времени (тестовые стенды, ноутбучные ВМ в изолированной NAT-сети), и выключаю там, где время ведёт доменная иерархия или внутренний NTP. Набор параметров зависит от продукта, и Broadcom разводит их так.
| Продукт | Периодическая (раз в минуту) | Разовая (старт, resume, снапшот) | |---|---|---| | vSphere 7.0 Update 1 и новее | Edit Settings → VM Options → VMware Tools, снять «Synchronize time periodically»; в .vmx: tools.syncTime | Снять «Synchronize at startup and resume»; в .vmx: time.synchronize.allow, по умолчанию TRUE и в файле не пишется, при отключении появляется как FALSE | | Workstation, Fusion, vSphere до 7.0 U1 | Один флажок синхронизации времени гостя с хостом в настройках ВМ (Options → VMware Tools, точная подпись зависит от версии); в .vmx: tools.syncTime | Набор параметров time.synchronize.* в состоянии FALSE (список ниже) | Обратите внимание на оговорку из той же статьи: отключение разовой синхронизации на vSphere 7.0 U1 и новее автоматически отключает и периодическую. Поэтому на практике у вас одна рукоятка «всё выключить» и одна «только периодическая».
Для Workstation и Player единого переключателя разовой коррекции нет, надо вписать в .vmx параметры. Список из статьи Broadcom такой: time.synchronize.continue, time.synchronize.restore, time.synchronize.resume.disk, time.synchronize.shrink, time.synchronize.tools.startup, time.synchronize.tools.enable и time.synchronize.resume.host. Сначала выключите ВМ, а не suspend: изменения вступают в силу только после перезапуска виртуальной машины или службы VMware Tools в госте. Сделайте копию .vmx и добавьте строки:
tools.syncTime = "FALSE"
time.synchronize.continue = "FALSE"
time.synchronize.restore = "FALSE"
time.synchronize.resume.disk = "FALSE"
time.synchronize.shrink = "FALSE"
time.synchronize.tools.startup = "FALSE"
time.synchronize.tools.enable = "FALSE"
time.synchronize.resume.host = "FALSE"В статье Broadcom значения даны именно как "FALSE" (для tools.syncTime документированы TRUE и FALSE); в старых форумных советах встречается «0», но я держусь документированной формы, чтобы потом не гадать, почему параметр не подхватился.
Не делайте обратную ошибку: не выключайте всё это, если в госте нет другого источника времени. Это как раз тот сценарий, из-за которого в статье «сбилось время»: разовая коррекция отключена, гость в изолированной сети, NTP до него не достаёт, и часы после resume остаются на прошлой неделе. Для самых простых ВМ без домена я оставляю Tools с разовой синхронизацией и только снимаю периодическую. Если интересно, как строить иерархию времени в офисе, от контроллера домена до рабочих станций, посмотрите наш материал про синхронизацию времени в офисе.
Windows в госте: почему w32time не догнал время после resume
Если разовая коррекция Tools выключена, всё зависит от службы времени Windows. И тут есть тонкость, которую я видел на практике и которую почти никто не знает. У W32Time есть параметры MaxPosPhaseCorrection и MaxNegPhaseCorrection — наибольшая положительная и отрицательная поправка в секундах, которую служба готова сделать. Если нужна поправка больше, служба не меняет часы, а пишет событие в журнал. Значения по умолчанию по документации Microsoft: для автономных клиентов и серверов — 54 000 секунд (15 часов), для контроллеров домена — 172 800 секунд (48 часов), для членов домена — специальное значение 0xFFFFFFFF, то есть «всегда корректировать».
Что это значит для suspend. Тестовая Windows-ВМ вне домена, которую вы заморозили в пятницу вечером и подняли в понедельник утром, отстаёт примерно на 60 часов. Это больше 15 часов, и w32time из коробки поправку откажется делать. Вы запускаете w32tm /resync и получаете «The computer did not resync because the required time change was too big», а в журнале System появляется событие Time-Service с кодом 34 о слишком большой требуемой поправке. Время при этом остаётся старым. Для таких машин либо оставьте разовую коррекцию Tools, либо руками поставьте время и потом дайте службе синхронизироваться. Менять MaxPosPhaseCorrection в реестре я не советую: Microsoft прямо предупреждает, что значения в W32Time служебные и менять их без необходимости не надо.
Рабочая последовательность в госте Windows после длинного suspend такая:
net stop w32time
net start w32time
w32tm /resync /rediscover
w32tm /query /statusКлюч /resync заставляет компьютер синхронизировать часы как можно скорее и сбрасывает накопленную статистику ошибок, /rediscover заново определяет сетевую конфигурацию и ищет источники, а /nowait возвращает управление без ожидания результата. Для домена добавлю главное: Kerberos терпит расхождение между клиентом и контроллером домена по умолчанию 5 минут (параметр «Maximum tolerance for computer clock synchronization»). Тестовый стенд, выросший из шаблона и проспавший выходные, с большой вероятностью выпадет из этого окна, и вы увидите отказы аутентификации, хотя пароли верные. Как устроена цепочка времени от PDC-эмулятора вниз, я расписал в материале про службу времени на PDC-эмуляторе.
Linux в госте: chrony, makestep и первая секунда после resume
В Linux-гостях картина зеркальная. Chrony по умолчанию плавно подгоняет часы (slew), а не прыгает, и большое смещение выправлял бы очень долго. Для этого есть директива makestep. По документации chrony, она заставляет chronyd переставить системные часы, если поправка больше порога, но только если с момента старта демона было не больше указанного числа обновлений часов. Отрицательное значение лимита снимает ограничение. Пример из документации: makestep 0.1 3 разрешает шаг при расхождении больше 0,1 секунды, но только на первых трёх обновлениях.
Что из этого следует для ВМ, которая постоянно уходит в suspend. Типичный дистрибутивный конфиг с «makestep 1.0 3» спасает только при загрузке. Если машину заморозили на трое суток, а chronyd работает давно, лимит обновлений уже исчерпан, и поправка будет делаться медленной плавной подстройкой. Для гостей, которые приостанавливаются, я ставлю в конфиг chrony директиву с отключённым лимитом и перезапускаю службу:
makestep 1.0 -1Файл конфигурации зависит от дистрибутива (обычно /etc/chrony.conf либо /etc/chrony/chrony.conf), проверьте в своей системе. Побочный эффект документация chrony тоже обозначает: на большинстве систем часы желательно переставлять скачком только при загрузке, до запуска программ, которые рассчитывают на монотонно идущее вперёд время. Я сознательно отступаю от этого совета только для приостанавливаемых стендов: для баз данных и очередей скачок после resume всё же лучше, чем жизнь в прошлом.
Разовое действие без правки конфига — команда, которая отменяет оставшуюся плавную поправку и сразу переставляет часы:
sudo chronyc makestep
chronyc trackingВторая команда нужна, чтобы убедиться: Leap status стал Normal, а System time близок к нулю. Если у вас в госте стоит open-vm-tools, периодическую синхронизацию Tools можно переключить прямо изнутри, утилитой vmware-toolbox-cmd: vmware-toolbox-cmd timesync status показывает состояние, а enable и disable включают и выключают периодическую синхронизацию (если хост это разрешает). Но помните, что это управляет только периодической синхронизацией, разовую коррекцию на resume гость выключить так не может, для неё нужны параметры в .vmx на стороне хоста.
Что проверить на хосте: ноутбук, сон Windows и ESXi
Часто виноват не гость, а хост. Гость при коррекции берёт время хоста, а у ноутбука после сна часы могут быть неверны, пока не отработает служба времени самого хоста. Поэтому на Windows-хосте с Workstation я проверяю те же w32tm /query /status и убеждаюсь, что хост ходит к тому же внутреннему NTP, что и остальной офис. Есть и обратная ловушка из пользовательских отчётов: отдельные пользователи Workstation сообщали, что даже при отключённых параметрах гостя часы дёргаются, когда просыпается сам хост из сна. Официального подтверждения я не нашёл, поэтому считаю это гипотезой и проверяю на своей конфигурации: если воспроизводится, сначала делаю suspend виртуалки и только потом отправляю в сон хост.
Есть ещё нюанс про аппаратные часы виртуальной машины. Broadcom пишет, что гостевая ОС при загрузке читает виртуальные CMOS/RTC-часы, а они берутся от хоста со смещением, зафиксированным при первом включении. Поэтому неверные часы хоста или миграция на хост с неверным UTC дадут неверное время гостя при старте, и отключение синхронизации Tools от этого не спасёт. Тот же документ рекомендует настроить все хосты ESXi на синхронизацию с одним или несколькими надёжными внешними источниками. В офисе это один внутренний NTP-сервер или контроллер домена, от которого время получают и хосты, и гости.
Разбор из практики: «СтартСбор», 49 рабочих мест
Клиент — краудфандинг-платформа «СтартСбор», 49 рабочих мест. У команды разработки и тестирования семь ноутбуков с VMware Workstation, на каждом по два-три тестовых стенда: Windows Server 2022 в тестовом домене и Ubuntu с PostgreSQL. Жалоба звучала так: «после выходных в стенде всё ломается — и вход по доменной учётке, и двухфакторные коды, и отчёты с датой из будущего». Сначала подозревали сам продукт, потеряли около двух рабочих дней на тесты платёжной логики. Я пришёл на стенды и первым делом сравнил часы хоста и гостя сразу после resume. Хост был верен, гости отставали ровно на время сна ноутбука, то есть на 60 с небольшим часов.
Причина нашлась быстро. Стенды были развернуты из шаблона, который когда-то настраивали под ESXi, и в нём была отключена разовая синхронизация. В тестовой сети стенда NTP-серверов не было, у Linux-гостей chrony стоял с «makestep 1.0 3», у контроллера тестового домена на Windows Server 2022 был дефолтный лимит поправки в 48 часов, у отдельных Windows-ВМ вне домена — 15 часов. Все три фактора сработали вместе: Tools не поправили, chrony давно прошёл свои первые три обновления и шаг делать уже не имел права, а w32time отказался двигаться на 60 часов, потому что это больше обоих лимитов. Члены тестового домена корректировались без ограничений, но брали время у контроллера, который сам жил в прошлом. Я не открывал ничего экзотического, всё это лежит в документации.
Исправление заняло около двух часов на все семь ноутбуков. Для Linux-гостей в chrony поставили «makestep 1.0 -1», а в Windows-гостях (контроллер тестового домена и ВМ вне домена) вернули разовую коррекцию Tools, убрав из .vmx строки со значением FALSE и оставив отключённой только периодическую (tools.syncTime). Контроллер тестового домена настроили брать время от внутреннего NTP, как в боевой сети. На хостах ноутбуков проверили w32tm /query /source. Итог: после следующих выходных расхождение гостя с хостом при resume составило не больше секунды, ошибки Kerberos и двухфакторных кодов пропали. Дополнительно мы добавили в чек-лист создания стенда один пункт: первое, что делает тестировщик после resume, — смотрит chronyc tracking или w32tm /query /status.
Частые вопросы
Почему время в виртуальной машине сбилось после suspend?
Пока ВМ приостановлена, её часы не идут. При resume гость догоняет время либо через разовую коррекцию VMware Tools, либо через свою службу времени. Если разовая коррекция выключена, а источника времени в госте нет, часы остаются там, где их заморозили.
Снял галочку синхронизации с хостом, но время всё равно прыгает. Это баг?
Нет. Галочка управляет периодической синхронизацией раз в минуту. Разовая коррекция на resume, снапшоте, vMotion, сжатии диска и перезапуске Tools работает отдельно и по умолчанию включена. На vSphere 7.0 U1 и новее её параметр time.synchronize.allow, на Workstation нужен набор time.synchronize.*.
Как полностью отключить синхронизацию времени при resume в VMware Workstation?
Выключите ВМ и в .vmx задайте FALSE для tools.syncTime и параметров time.synchronize.continue, restore, resume.disk, shrink, tools.startup, tools.enable, resume.host. Изменения вступают в силу после перезапуска ВМ или VMware Tools. Если в госте нет своего NTP, делать это не стоит.
Почему w32tm /resync не исправляет время в Windows после долгого suspend?
У автономного Windows по документации Microsoft максимальная поправка MaxPosPhaseCorrection составляет 54 000 секунд (15 часов). При большем отставании служба пишет событие и часы не меняет. Установите время вручную или оставьте разовую коррекцию Tools.
Что делать в Linux-госте с chrony, если после suspend время не выравнивается?
Выполните sudo chronyc makestep, а для постоянного эффекта задайте в конфиге makestep 1.0 -1. Отрицательный лимит разрешает шаг в любой момент, а не только при первых обновлениях после старта демона.
Можно ли одновременно использовать VMware Tools sync и NTP в госте?
Не нужно. Broadcom рекомендует одну форму периодической синхронизации: при нативной службе (NTP, chrony, W32Time) периодическую синхронизацию Tools отключают, иначе две службы борются за часы.
Источники
- Broadcom Knowledge Base: Disabling Time Synchronization for virtual machines — События разовой коррекции (resume, снапшот, vMotion, shrink, перезапуск Tools), параметры tools.syncTime и time.synchronize.allow для vSphere 7.0 U1+, список time.synchronize.* для Workstation/Fusion, замечание про RTC и NTP на ESXi. https://knowledge.broadcom.com/external/article/326306
- Microsoft Learn: Windows Time Service Tools and Settings — Ключи w32tm /resync, /rediscover, /nowait, /query /status /source /configuration; значения MaxPosPhaseCorrection и MaxNegPhaseCorrection по умолчанию. https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings
- Microsoft Learn: Maximum tolerance for computer clock synchronization — Допуск расхождения времени для Kerberos по умолчанию 5 минут. https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/maximum-tolerance-for-computer-clock-synchronization
- chrony: chrony.conf — Директива makestep: порог и лимит обновлений, отрицательный лимит снимает ограничение, пример makestep 0.1 3, рекомендация делать шаг только при загрузке. https://chrony-project.org/doc/4.6/chrony.conf.html
- chrony: chronyc — Команда makestep без аргументов (отменить плавную поправку и сразу переставить часы), поля tracking: System time и Leap status (Normal / Not synchronised). https://chrony-project.org/doc/4.6/chronyc.html
