ClusterTriage / Blog / Time Service
Time drift in Hyper-V clusters: de stille killer van Kerberos en CSV
Een Hyper-V cluster met klok-skew tussen nodes is een tijdbom. Niet figuurlijk, maar letterlijk. Wanneer de klokken op cluster-nodes meer dan vijf minuten uit elkaar lopen, valt Kerberos om. Vanaf vijftig seconden raken cluster-heartbeats hun synchronisatie kwijt. En zodra een Hyper-V host zijn tijd-referentie verliest, kunnen domain-joined VM's die op die host draaien hun authenticatie naar AD niet meer onderhouden.
In de meeste Hyper-V cluster assessments die ClusterTriage uitvoert, vinden we klok-issues. Niet altijd dramatisch, vaak nog onder de drempel waarop iets faalt, maar wel duidelijk uit balans. En het is precies het soort probleem dat monitoring tools missen tot het te laat is, omdat een paar seconden afwijking nergens een alarm triggert.
Dit artikel legt uit waarom time service op een Hyper-V cluster anders werkt dan op een standalone server, welke configuraties wij in 2026 als best practice hanteren, en hoe je drift detecteert vóór de eerste Kerberos-failure.
1. Waarom time drift in Hyper-V clusters specifiek riskant is
Op een standalone server is klok-drift een irritatie. Op een Hyper-V cluster is het een cascade-trigger.
Kerberos. Active Directory gebruikt Kerberos voor authenticatie, en Kerberos heeft een standaard klok-tolerantie van vijf minuten. Verschil meer dan dat tussen client en KDC, en alle nieuwe authenticatie faalt met KRB_AP_ERR_SKEW. Bestaande sessies blijven werken tot hun ticket verloopt, dus de eerste symptomen komen 8 tot 10 uur na de drift en lijken zonder oorzaak. We hebben dit op klantsite zien gebeuren: maandagochtend kan niemand inloggen, alles wijst naar DNS, en de werkelijke oorzaak is een Hyper-V host die zaterdag zijn NTP-bron verloor.
Cluster heartbeats. Failover Clustering verwacht dat alle nodes binnen redelijke tijd-tolerantie zitten om heartbeat-events correct te volgen. Bij grote skew gaan nodes events in verkeerde volgorde rapporteren, en kan de Cluster Service besluiten dat een node uit het cluster is terwijl die node prima draait.
CSV coordinator-arbitratie. Cluster Shared Volume coordinator-roloverdrachten worden gelogd met timestamps. Skew tussen nodes maakt log-analyse onmogelijk, en in zeldzame gevallen kan het CSV-rebalancing in een loop brengen waarbij de balancer zijn eigen acties als gelijktijdig met de andere node interpreteert.
Live Migration timing. De live-migration handshake gebruikt timestamps voor sequence-validatie. Grote skew tussen bron en doel-host kan migraties afbreken zonder duidelijke foutmelding, of erger, de migratie compleet rapporteren terwijl er memory pages zijn overgeslagen.
VM clocks die afdwalen. Domain-joined VM's syncen met hun PDC emulator. Als die PDC emulator op zijn beurt afhankelijk is van een Hyper-V host die zijn eigen tijd niet goed beheert, krijg je drift in twee lagen, en de oplossing wordt veel ingewikkelder dan "fix de NTP-bron".
2. De Microsoft tijd-hiërarchie en waar Hyper-V hosts in passen
De juiste tijd-architectuur in een domein-omgeving:
- Het top-level. Eén DC met de PDC emulator FSMO-rol synchroniseert met een externe, betrouwbare tijdbron. Bij voorkeur
time.windows.com,pool.ntp.org, of een hardware-stratum-1-bron. Configuratie:Type = NTP,NtpServer = <bron>,0x9. - Alle andere DC's. Synchroniseren met de PDC emulator via de domein-hiërarchie. Configuratie:
Type = NT5DS. - Alle domain-joined servers, inclusief Hyper-V hosts. Synchroniseren met de domein-hiërarchie. Configuratie:
Type = NT5DS. - Alle domain-joined VM's. Synchroniseren met de domein-hiërarchie via hun eigen w32time-service. Configuratie:
Type = NT5DS. En cruciaal: de Hyper-V Time Synchronization Integration Service moet uit staan voor deze VM's. Zie sectie 3. - Non-domain VM's of geïsoleerde clusters. Direct synchroniseren met een externe NTP-bron of met een NTP-bron in het managementnetwerk. Configuratie:
Type = NTP.
Wat we in een typische Hyper-V cluster assessment vinden, is dat deze hiërarchie ergens halverwege is gebroken. De PDC emulator staat op Type = NT5DS (synct met zichzelf, in feite met de hardware-klok), de Hyper-V hosts staan op Type = NTP (en wijzen elk naar een andere bron), en de VM's hebben hun Hyper-V Time Sync IS aan staan terwijl ze ook NT5DS proberen te doen. Resultaat: drie tijd-bronnen die elk in een andere richting trekken.
3. De Hyper-V Time Synchronization Integration Service, en wanneer hem uit te zetten
De Hyper-V Time Sync Integration Service synchroniseert de VM-klok met die van de Hyper-V host. Dat klinkt nuttig, en voor non-domain-joined VM's is het dat ook. Voor domain-joined VM's is het schadelijk en hoort het uit te staan.
Waarom uit voor domain-joined VM's:
Een domain-joined VM hoort zijn tijd uit AD te halen via w32time NT5DS. Als de Hyper-V Time Sync IS ook actief is, krijg je twee concurrerende tijdbronnen: de host (die zijn eigen tijd-staat heeft) en het domein. Op het moment dat host en domein van elkaar afwijken (en dat gebeurt vaker dan je denkt), gaat de VM-klok pingpongen tussen beide.
Het Microsoft-advies:
De documentatie van Microsoft zegt dit expliciet sinds Windows Server 2012 R2: voor domain-joined VM's hoort Time Sync alleen actief te zijn voor de "Time Synchronization" sub-service tijdens save/restore-operaties, niet voor reguliere klok-sync. Praktisch betekent dat de integration service zelf uit, of de specifieke sync-component uit.
Controleer per VM:
# Per VM, op de Hyper-V host
Get-VMIntegrationService -VMName 'MyVM' |
Where-Object Name -eq 'Time Synchronization' |
Select-Object VMName, Name, Enabled
Uitschakelen voor domain-joined VM's:
# Voor één VM
Disable-VMIntegrationService -VMName 'MyVM' -Name 'Time Synchronization'
# Voor alle VM's op een host (filter op naam, OS-type, of gewoon allemaal)
Get-VM | Disable-VMIntegrationService -Name 'Time Synchronization'
In een cluster assessment rapporteren we dit per VM, met een vlag voor elke domain-joined VM die Time Sync nog aan heeft staan.
4. PDC emulator-configuratie, de root van alle tijd
Alles begint bij de PDC emulator. Als die niet goed staat, propageert de fout door het hele domein.
Welke node heeft de PDC emulator-rol:
# Vanaf elke domain-joined machine
Get-ADDomain | Select-Object PDCEmulator
Configureer de PDC emulator met een externe tijdbron:
# Op de PDC emulator zelf
w32tm /config /manualpeerlist:"time.windows.com,0x9 pool.ntp.org,0x9" `
/syncfromflags:manual /reliable:yes /update
# Stop en herstart w32time
Restart-Service w32time
# Forceer een sync en check status
w32tm /resync /rediscover
w32tm /query /status
w32tm /query /source
Tolerantie-instellingen die we standaard zetten:
# Maximum 5 minuten in beide richtingen (default is veel hoger)
w32tm /config /computer:<PDC> `
/maxposphasecorrection:300 `
/maxnegphasecorrection:300 `
/update
Restart-Service w32time
De MaxPosPhaseCorrection en MaxNegPhaseCorrection waarden bepalen hoe groot een tijd-aanpassing mag zijn voordat w32time hem weigert. Default-waarden zijn in oudere Windows-versies absurd hoog (54 jaar), wat betekent dat een corrupte NTP-bron je klok wagenwijd kan verzetten zonder dat w32time klaagt. 300 seconden (5 minuten) is een veilige drempel die handmatige tussenkomst forceert bij grote drift.
Verifieer dat de PDC emulator daadwerkelijk extern synct:
w32tm /query /source
# Verwacht: <externe NTP-bron>, niet "Local CMOS Clock" of "Free-running System Clock"
Vinden we dit niet, dan staat de PDC emulator effectief op zijn eigen hardware-klok, en alle andere DC's en servers in het domein syncen vrolijk met die drifting klok.
5. Cluster-node configuratie, w32time settings die er werkelijk toe doen
Cluster-nodes als domain-joined servers horen op Type = NT5DS. Dat is meestal de default na domain-join. Maar er zijn een paar settings die op Hyper-V hosts specifieke aandacht verdienen.
Verifieer per cluster-node:
Invoke-Command -ComputerName (Get-ClusterNode).Name {
[PSCustomObject]@{
Node = $env:COMPUTERNAME
Type = (w32tm /query /configuration | Select-String 'Type:').Line.Trim()
Source = (w32tm /query /source)
LastSync = (w32tm /query /status | Select-String 'Last Successful').Line.Trim()
Stratum = (w32tm /query /status | Select-String 'Stratum').Line.Trim()
MaxPosPhaseCorr = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config').MaxPosPhaseCorrection
MaxNegPhaseCorr = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config').MaxNegPhaseCorrection
}
} | Format-Table -AutoSize
Wat de output moet laten zien:
- Type moet
NT5DSzijn op elke cluster-node.NTPop een node die geen DC of PDC is, is een misconfiguratie. - Source moet een domain controller in hetzelfde domein zijn. "Local CMOS Clock" of "Free-running System Clock" is een symptoom van een w32time-service die zijn bron kwijt is.
- LastSync moet recent zijn, binnen het laatste sync-interval (default elke 64 tot 1024 seconden afhankelijk van stabiliteit).
- Stratum moet één hoger zijn dan dat van de PDC emulator. Als de PDC stratum 2 is (sync met extern stratum-1), dan zijn alle andere DC's stratum 3, en zijn cluster-nodes stratum 4.
- MaxPosPhaseCorrection en MaxNegPhaseCorrection zetten we standaard op 300 seconden, zelfde als op de PDC emulator. Dit voorkomt dat een corrupte sync-bron de klok ineens uren verzet.
De klok-skew tussen nodes meten:
$nodes = (Get-ClusterNode).Name
foreach ($node in $nodes) {
foreach ($peer in $nodes) {
if ($node -ne $peer) {
$offset = w32tm /stripchart /computer:$peer /dataonly /samples:1 |
Select-String '^\d' | Select-Object -First 1
Write-Host "$node <-> $peer : $offset"
}
}
}
Acceptabele skew tussen cluster-nodes: onder 1 seconde in steady state, onder 5 seconden gedurende een patch-ronde of node-reboot. Boven 30 seconden is een dringend remediation-onderwerp.
6. Drift detecteren vóór het faalt
Monitoring tools alarmeren meestal pas bij klok-skew die al schade veroorzaakt. Wij voegen tijdens Cluster Assessment remediation een eenvoudige drift-monitor toe aan klant-omgevingen:
# Drift-detection script, draaien op een management-host of via scheduled task
$threshold = 30 # seconden
$cluster = Get-Cluster
$nodes = (Get-ClusterNode -Cluster $cluster).Name
$baseline = $nodes[0]
foreach ($peer in $nodes | Where-Object {$_ -ne $baseline}) {
$output = w32tm /stripchart /computer:$peer /dataonly /samples:1 2>&1
$offsetLine = $output | Where-Object {$_ -match '^\d'} | Select-Object -First 1
if ($offsetLine -match '([\d\.\-]+)s') {
$offset = [math]::Abs([double]$matches[1])
if ($offset -gt $threshold) {
Write-Warning "Drift between $baseline and $peer: $offset seconds"
# Naar SIEM, Teams webhook, of monitoring stack hier
}
}
}
Schedule dit elke 15 minuten op een management-host. De waarde van een dedicated drift-monitor is dat hij issues uren vóór de eerste Kerberos-failure oppikt, op een moment waarop remediation nog niet-disruptief is.
Time service-configuratie is een van die onderwerpen waar elke beheerder denkt dat het op orde is, en waar we tijdens een cluster assessment in 7 van de 10 omgevingen iets vinden dat niet klopt.
Een ClusterTriage Hyper-V cluster assessment controleert tijd-hiërarchie, PDC emulator-configuratie, per-node settings en Hyper-V Time Sync IS-status per VM, en levert een remediation-script mee als onderdeel van het rapport.
Plan een cluster assessment kennismaking →7. Drie veelvoorkomende foutpatronen
Patroon 1: PDC emulator op Type = NT5DS
Klassieke configuratiefout. De PDC emulator wijst zichzelf aan als bron via NT5DS, wat effectief betekent: ik sync met mezelf, ik gebruik mijn eigen hardware-klok. Werkt totdat de hardware-klok afdrijft, en dan drijft het hele domein mee.
Fix: zet de PDC emulator op Type = NTP met een externe peer-lijst en /reliable:yes. Zie sectie 4.
Patroon 2: Hyper-V host met Type = NTP naar een externe bron
Een Hyper-V host die zelfstandig naar time.windows.com synct in plaats van naar de domein-hiërarchie. Klinkt logisch ("dichter bij de bron"), maar breekt het hele principe van een domein-hiërarchie en zorgt voor inconsistente tijd tussen hosts.
Fix: zet de host op Type = NT5DS. De host synct dan met een DC, die met de PDC emulator synct, die met externe NTP synct.
Patroon 3: VM's met Hyper-V Time Sync IS aan plus NT5DS
Domain-joined VM die op zowel de Hyper-V host als de domein-hiërarchie probeert te syncen. De klok ping-pongt, zeker als host en domein een fractie van een seconde van elkaar verschillen.
Fix: zet Hyper-V Time Sync IS uit per VM voor alle domain-joined VM's. Zie sectie 3.
8. Remediation playbook
De volgorde die wij standaard hanteren bij het herstel:
Stap 1, identificeer de PDC emulator:
Get-ADDomain | Select-Object PDCEmulator
Stap 2, fix de PDC emulator:
Configureer externe NTP-bronnen, zet /reliable:yes, zet MaxPosPhaseCorrection en MaxNegPhaseCorrection op 300 seconden, herstart w32time. Verifieer dat w32tm /query /source daadwerkelijk een externe bron toont.
Stap 3, fix alle andere DC's:
Zet ze op Type = NT5DS, verifieer dat hun source een DC in het domein is. Geen externe NTP-bronnen op niet-PDC DC's.
Stap 4, fix alle Hyper-V hosts en domain-joined member-servers:
Zet ze op Type = NT5DS. Pas MaxPosPhaseCorrection en MaxNegPhaseCorrection aan. Herstart w32time. Verifieer sync.
Stap 5, fix VM's:
Voor alle domain-joined VM's: zet Hyper-V Time Synchronization Integration Service uit. Verifieer dat de VM's via w32tm /query /source een DC in het domein als bron tonen.
Stap 6, monitor:
Schedule het drift-detection script uit sectie 6 elke 15 minuten. Hook het in op je bestaande monitoring of SIEM. Zet een drempel op 30 seconden voor early warning.
Stap 7, documenteer:
Schrijf op welke instellingen waar staan, welke externe NTP-bronnen worden gebruikt, en wat de procedure is bij een PDC emulator-failover. Dit is precies het soort kennis dat verloren gaat bij personeelswissels en waar Cluster Assessments twee jaar later weer drift in dezelfde omgeving aantreffen.
De kern
Time service in een Hyper-V cluster is niet "set and forget". De interactie tussen w32time, AD-replicatie, cluster-heartbeats, Live Migration handshake en Hyper-V Time Sync IS is complex genoeg dat een verkeerde aanname op één laag tot symptomen op een andere laag leidt. Wanneer Kerberos faalt, kijkt iedereen naar AD. Wanneer cluster-heartbeats wegvallen, kijkt iedereen naar het netwerk. De werkelijke oorzaak zit vaak twee lagen dieper, in een w32time-configuratie die niemand de afgelopen drie jaar heeft aangeraakt.
Een ClusterTriage Hyper-V cluster assessment bevat standaard tijd-serviceanalyse. Bevindingen worden gerapporteerd met severity die schaalt met de werkelijke skew en de blast radius. Remediation-scripts zijn idempotent en kunnen door het klant-team zelf worden toegepast.
Plan een Hyper-V cluster assessment kennismaking →
Veelgestelde vragen
Drift bouwt langzaam op. Tot het moment dat een PDC emulator uitvalt of een Hyper-V host wordt gepatcht, kan een misconfiguratie jarenlang verborgen blijven. We zien regelmatig dat een geplande maintenance-actie de eerste keer is dat de drift zichtbaar wordt, en dat is een ongelukkig moment voor verrassingen.
Grotendeels ja. Azure Local nodes zijn domain-joined en volgen dezelfde w32time-hiërarchie. Wel: voor Arc-managed Azure Local clusters zit er een aanvullende laag, omdat de Arc-agent ook zijn eigen tijd-validatie doet richting Azure. De drempel daar is strikter (vijf minuten max), dus drift wordt eerder zichtbaar.
Dan is een hardware-stratum-1-bron in het managementnetwerk de oplossing. Apparaten als Meinberg, Microsemi of een GPS-disciplined Linux-server kunnen als interne NTP-bron dienen. De PDC emulator wijst dan naar die hardware in plaats van naar time.windows.com. Voor strict air-gapped omgevingen is dit de standaard-aanpak.
Onder 1 seconde in steady state. Tot 5 seconden tijdens een patch-ronde of node-reboot. Boven 30 seconden is een dringend remediation-onderwerp. Boven 5 minuten is het al een actief incident, want Kerberos zal nieuwe authenticatie weigeren.
/reliable:yes markeert een tijd-bron als "betrouwbaar", wat andere w32time-clients toestaat om met hem te syncen. Het is een verplichte instelling op de PDC emulator (zonder is hij geen geldige tijd-bron voor de rest van het domein). Op een DC die geen PDC is, hoort /reliable:no of geen instelling.