Setup of NTP on Hyper-V servers

hyper-vntpsynchronizationtime

I am having problems with NTP setup on our Hyper-V host and clients. I am not using Domain Controller (almost all advise is given for DC's which I am not using).

On all servers I have used the windows clock to setup the ntp client name (Right click, adjust date/time, Internet time, Change settings, enter NTP server name).

This didn't seem to work. Or rather, every night to monday at 01:00, the time was forcefully adjusted (caused all sorts of issues, like a broken database backup).

I have messed with w32tm (read out status, config, tried to unregister and re-register). I finally got w32tm /query /config to acknowledge that it used the ntp server:

I have had w32tm /query /source say this:

Local CMOS Clock
time.windows.com,0x9 (actually a different host, but of no matter for this report)
Free-running System Clock
VM IC Time Synchronization Provider (only for Hyper-V clients)

I finally had w32tm report "time.windows.com,0x9" but later it automatically changed to "Free-running System Clock". I have no idea why. I assume free-running is not what I want.

I guess I am completely lost regarding the time setup on both Hyper-V host and client and really need some help. I have found some guides, but they contradict each other (or just talk about domain controller setups).

w32tm on a Hyper-V client has this to say about the configuration:

C:\Windows\system32>w32tm /query /configuration
[Configuration]

EventLogFlags: 2 (Local)
AnnounceFlags: 10 (Local)
TimeJumpAuditOffset: 28800 (Local)
MinPollInterval: 10 (Local)
MaxPollInterval: 15 (Local)
MaxNegPhaseCorrection: 54000 (Local)
MaxPosPhaseCorrection: 54000 (Local)
MaxAllowedPhaseOffset: 1 (Local)

FrequencyCorrectRate: 4 (Local)
PollAdjustFactor: 5 (Local)
LargePhaseOffset: 50000000 (Local)
SpikeWatchPeriod: 900 (Local)
LocalClockDispersion: 10 (Local)
HoldPeriod: 5 (Local)
PhaseCorrectRate: 1 (Local)
UpdateInterval: 360000 (Local)


[TimeProviders]

NtpClient (Local)
DllName: C:\Windows\system32\w32time.DLL (Local)
Enabled: 1 (Local)
InputProvider: 1 (Local)
AllowNonstandardModeCombinations: 1 (Local)
ResolvePeerBackoffMinutes: 15 (Local)
ResolvePeerBackoffMaxTimes: 7 (Local)
CompatibilityFlags: 2147483648 (Local)
EventLogFlags: 1 (Local)
LargeSampleSkew: 3 (Local)
SpecialPollInterval: 604800 (Local)
Type: NTP (Local)
NtpServer: time.windows.com,0x9 (Local)

VMICTimeProvider (Local)
DllName: C:\Windows\System32\vmictimeprovider.dll (Local)
Enabled: 1 (Local)
InputProvider: 1 (Local)
NtpServer (Local)
DllName: C:\Windows\system32\w32time.DLL (Local)
Enabled: 0 (Local)
InputProvider: 0 (Local)

The above configuration results in "Free-running System Clock" which I find odd to say the least.

Both Windows Time and Hyper-V Time Synchronization Service are running.

The are no group policies targeting time service in effect.

Suggestions on how to fix this problem?

Best Answer

This is what I ended up doing and what I assume is sound:

Hyper-V host (physical server) is set to synchronize against a selection of time servers and each Hyper-V guest is set to synchronize against the host alone. The changes below are differences from default.

Host setup

First stop the time service with:

net stop w32time

Registry changes (base HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\):

  • w32time\Config\AnnounceFlags = 10
  • w32time\Parameters\NtpServers = 0.dk.pool.ntp.org,0x1 1.dk.pool.ntp.org,0x1 2.dk.pool.ntp.org,0x1 3.dk.pool.ntp.org,0x1
  • w32time\TimeProviders\NtpClient\SpecialPollInterval = 900 (15 minutes)
  • w32time\TimeProviders\NtpServer\Enabled = 1

Some use AnnounceFlags=5 but the correlation with a domain controller (which is not setup in this case) causes the ntp server to not announce itself (observation; not fact) hence AnnounceFlags is set to 10 (more on AnnounceFlags)

0x1 on the ntpservers = use special poll interval (instead of standard ntp poll intervals). (more on 0x1, 0x2, 0x4 and 0x8). Using SpecialPollInterval is not required, but it seems to be recommended (perhaps mostly for guests and not so much for hosts). If you decide not to use SpecialPollInterval, you have to limit MinPollInterval and MaxPollInterval instead. Their defaults are 10 (1024 seconds) and 15 (32768 seconds); I suggest 6 (64 seconds) and 10 (1024 seconds)) instead.

Make sure the time service is started when the server has network connection:

sc triggerinfo w32time start/networkon stop/networkoff

The default is to start (and stop) the time service with the domain controller (which is not present in this setup). Forgetting this step will stop your time server on every boot (shortly after it is started automatically). This problem was a difficult one to track.

And start the service again:

net start w32time

Now the host will poll one of the ntp time servers every 15 minutes and offer to be a ntp server for other clients. I have firewalled udp:123 to make sure only the guests are allowed in.

The server may take up to 15 minutes (SpecialPollInterval) until it announces its capabilities as a reliable time server to the world (guests). This means the guests may be free-running for 15-20 minutes after start of the service.

Guest setup

The guests drift (much) more than the host (also compared to each other) and require a relatively short poll interval. Due to this, using remote ntp servers is not ideal and as we have a reliable ntp server at hand (just configured), we are going to use this (and only this). The guests can all access the host using a virtual network.

Make sure the Hyper-V Time Integration service is installed and running. With this setup, it will be used when the virtual server is booted but also when resuming from save. It will not be used as a time source.

Stop the time service with:

net stop w32time

Make the necessary registry changes (base HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\):

  • w32time\Config\AnnounceFlags = 10
  • w32time\Parameters\NtpServers = 192.168.0.100,0x9
  • w32time\TimeProviders\NtpClient\SpecialPollInterval = 300 (5 minutes)
  • w32time\TimeProviders\NtpServer\Enabled = 0
  • w32time\TimeProviders\VMICTimeProvider\Enabled= 0

Make sure the time service is started when the server has network connection:

sc triggerinfo w32time start/networkon stop/networkoff

And start the service again:

net start w32time

Conclusion

With this setup, time should be in good control on both the host and the guests.