ClusterTriage / Blog / Cluster assessment
Van Cluster Assessment tot Patch Night: de ClusterTriage-werkwijze in de praktijk
Dit artikel volgt een praktijkvoorbeeld van de vijfstaps ClusterTriage-werkwijze, toegepast op een productie Hyper-V cluster. Twaalf High Risk-bevindingen werden ontdekt, opgelost in afhankelijkheidsvolgorde, opnieuw gemeten om de fixes te verifiëren, en daarna uitgevoerd als een patchrun zo schoon dat de on-call beheerder niet uit bed hoefde.
0. De situatie geschetst
Dit was een geplande Windows Update-ronde op een productie multi-site Hyper-V cluster: zes Windows Server 2022 nodes, verspreid over twee Nederlandse datacenters, met ongeveer 135 VM's. De updates waren bewust ingepland als laatste stap van een cluster assessment engagement, na meerdere dagen remediation verspreid over enkele weken, en op afstand uitgevoerd met Cluster Aware Updating.
Mijn ochtend in Bangkok had ik besteed aan de laatste controles: het run script, een nieuwe DNS-audit van alle nodes, en een volledige Failover Cluster Validation, allemaal schoon om kwart over elf. Daarna, om 06:37 Amsterdamse tijd, terwijl de beheerders van de klant nog sliepen, startte ik de run. Om 09:08 was het klaar: 23 updates geïnstalleerd, nul fouten, nul geannuleerd, elke node weer up, elke VM waar die hoort, voordat de eerste gebruikers binnenkwamen op een stille vrijdagochtend. Een van de twee beheerders was met vakantie. De ander checkte in via Teams, midden in een wandeling met zijn hond, toen de run al bijna klaar was. Niemand hoefde uit bed.
Dat is het hele verhaal, en dat is precies het punt. Een patchrun op een productie multi-site cluster zou de saaiste gebeurtenis van de maand moeten zijn. Dat was het ook, maar alleen omdat alles wat eraan voorafging zo zorgvuldig was uitgevoerd.
1. Intake, weet waar je staat
De eerste stap van de ClusterTriage-werkwijze. Elk engagement begint met een gesprek over topologie, storagemodel, beheertools, backup, monitoring en recente incidenten. Niet omdat het een formaliteit is, maar omdat elk later oordeel ervan afhangt.
Dit cluster: de zes nodes van hierboven, SAN-storage via iSCSI op dedicated 25 GbE-netwerken, SET virtual switches voor LAN en Live Migration, beheerd via Virtual Machine Manager, geback-upt met Veeam. De VM's waren ongelijk verdeeld over de twee sites.
De intake brengt ook aan het licht wat er in beweging is. Hier waren dat twee dingen: de klant was halverwege het vervangen van zijn domeincontrollers, waardoor het DNS-landschap onder het cluster veranderde, en een Linux-VM had een bekend live-migratieprobleem. Beide zouden er aan het eind toe doen. Een intake die de bewegende delen mist, levert een Bevindingen-document op dat al verouderd is bij aflevering.
2. Scripted inventory: read-only, herhaalbaar, geen agents
Stap twee. De data komt van PowerShell-inventarisatiescripts die op maat voor de omgeving zijn geschreven, uitgevoerd vanaf de eigen managementserver van de klant. Niets wordt geïnstalleerd, niets wordt veranderd. Het inventory script is read-only by design en zegt dat in de header, omdat degene die de run goedkeurt dat in de source moet kunnen verifiëren.
Een paar designkeuzes hebben zich over meerdere engagements bewezen:
Pre-flight vóór inventory. Fase 0 test elke node op DNS-resolutie in het management-subnet, ICMP, WinRM-bereikbaarheid, listener-bindings en firewallstatus. Elke node die pre-flight niet doorstaat, wordt uitgesloten van alle volgende secties, met een inline banner die de server benoemt, zodat het rapport zelfdocumenterend blijft in plaats van stil onvolledig.
Hervatbaarheid. Een state file registreert welke secties klaar zijn. Als een run wordt onderbroken bij sectie 9 van 12, begint de volgende run bij sectie 10 en voegt toe aan hetzelfde outputbestand. Op een zes-node cluster duurt een volledige inventory lang; die verliezen door een verbroken sessie is niet acceptabel.
Resultaat. De output is één tekstbestand. Het toont de verschillen ten opzichte van de vorige meting, wat van groot belang is voor stap vier.
3. Analyse op basis van best practice: getallen, geen indrukken
Stap drie. Elk gegeven wordt vergeleken met de Microsoft-baseline voor de topologie, en elke afwijking krijgt een risiconiveau met een ondersteunende referentie. De eerste volledige meting van dit cluster leverde twaalf High Risk-bevindingen op. Een voorbeeld, want het zijn de concrete getallen die een Bevindingen-document bruikbaar maken:
Clock drift tot 86 seconden. Eén site was schoon, binnen een seconde. De andere site, plus een verdwaalde node, zat er 64 tot 86 seconden naast. Dat patroon wijst op een mislukte time source aan de ene kant, niet op willekeurige drift. Kerberos tolereert vijf minuten; CSV ownership en cluster heartbeats degraderen veel eerder. Bevinding, richting van de root cause, en een harde randvoorwaarde: geen patchronde tot alle nodes binnen een seconde van elkaar liggen.
Defender-uitsluitingen: leeg op alle zes nodes. Geen paths, geen processen, geen extensies. Elke VHDX-I/O kwam in aanmerking voor real-time scanning, de meest voorkomende oorzaak van Event ID 9 (trage I/O op een clustered volume) en vrijwel zeker de reden achter de trage backup-window waar de klant al een jaar mee leefde.
Pending reboots op vijf van de zes nodes, bevestigd tot in PendingFileRenameOperations in de registry, met ongeveer 200 dagen sinds de laatste restart.
Patch-level zeven maanden achter. De nieuwste hotfix op elke node dateerde van oktober vorig jaar.
Geen ervan is exotisch. Allemaal onzichtbaar op een dashboard dat alleen groene VM's toont.
4. Het Bevindingen-document en een herhaalde meting
Stap vier. Bevindingen worden verzameld in een gestructureerd document: (1) huidige situatie, (2) best practice, (3) afwijking, (4) aanbeveling, (5) actie, (6) referentie, kleurgecodeerd op risico. Maar een Bevindingen-document is een momentopname, en remediation verandert het beeld. Daarom krijgt het document deltaversies: meet opnieuw, vergelijk met het vorige outputbestand, en verplaats bevindingen pas naar opgelost wanneer de data dat bevestigt.
Die discipline werkt beter dan een afvinklijst. Een voorbeeld dat het delen waard is: de klant rolde de Defender exclusions uit via Group Policy, exact zoals aanbevolen. De verificatie-run liet zien dat alle zes nodes nog steeds alles scanden. De oorzaak zat in de GPO-editor: in de Administrative Template voor exclusions waren de waardenaam en de waarde verwisseld. Defender neemt de waardenaam als de exclusion, dus de policy had twintig labels als exclusion list geladen en sloot in feite niets uit. Kolommen omdraaien, gpupdate, opnieuw verifiëren: 162 checks passed. Zonder een herhaalde meting met het script zou die policy er jarenlang compliant uit blijven zien.
Over drie deltacycli kromp de High Risk-lijst van twaalf naar een handvol: BIOS-versies gelijkgetrokken over de sites, drivers gelijkgetrokken, pending reboots van vóór het cluster assessment opgelost via een gecontroleerde restartcyclus (weken vóór de patchrun), clock drift opgelost bij de time source, exclusions geverifieerd actief. Wat High Risk bleef, was de patch backlog zelf, bewust als laatste gepland, want een cluster patchen met verbroken time sync, openstaande file renames en een veranderende DNS-laag is precies hoe je een backlog in een storing verandert.
5. De actielijst en de afhankelijkheidsketen die alles bewaakt
De vijfde stap zet aanbevelingen om in een actieplan, en de volgorde is daarbij doorslaggevend. Elke actie krijgt een eigenaar, een afhankelijkheidsketen en een verificatiestap. Voor de patchrun zag de keten er zo uit: klokken binnen een seconde, pending reboots opgelost, WinRM bereikbaar op alle nodes, en, vanwege de lopende domeincontroller-migratie, DNS geverifieerd schoon op elke node.
Die laatste vereiste verdient nadruk. De nieuwe domeincontrollers hadden andere IP-adressen dan de servers die ze vervingen. Een clusternode die midden in het patchen herstart en opstart terwijl hij naar een buiten gebruik gestelde resolver wijst, kan mogelijk niet schoon rejoinen. Dus op de ochtend van de run draaide opnieuw een standalone read-only DNS-audit over iedere node: ingestelde DNS-servers, suffixes, registration settings, met een expliciete match flag tegen de lijst met oude DC-adressen. Nul hits. Elke node verwees naar twee geldige, nieuwe domeincontrollers.
Daarna de laatste randvoorwaarde: een volledige Failover Cluster Validation. Geen gedeeltelijke run, het hele rapport inclusief storage, en elke regel gelezen, niets overgeslagen. Het kwam schoon terug. Dat was het groene licht.
6. De patch-night
De run zelf was gescript rond Invoke-CauRun in remote-updating mode. Geen CAU-clusterrol, geen virtual computer-object, geen permanent account in het cluster, omdat deze klant doelbewust patcht, op zijn eigen schema, niet automatisch. Het script doet vier dingen die de moeite waard zijn om te kopiëren.
De checks zijn op maat gemaakt voor de omgeving. Alle zes nodes actief, geen al lopende CAU-run, en één zeer specifieke check: de Linux-VM met het bekende Live Migration-probleem was van tevoren handmatig uitgeschakeld, met de cluster stop action navenant ingesteld. Het script verifieert dat de VM daadwerkelijk offline is en stopt als dat niet zo is, omdat een onvolledige drain midden in het patchen niet acceptabel is. (Dit had geautomatiseerd kunnen worden met een successful-run trigger, maar handmatig uitschakelen was veiliger: als een geautomatiseerd script een VM stopt en daarna midden in het patchen blijft hangen, moet je aan de klant uitleggen waarom hun VM offline is. Dat risico is het niet waard.)
Het script patcht één site per keer. CAU heeft geen native site awareness, maar -NodeOrder accepteert een expliciete lijst. Eerst de drie nodes op site 1, daarna die op site 2. Op een multi-site cluster houd je zo het verhaal rond failovercapaciteit op elk moment van de run eenvoudig: hooguit één node down, en je weet altijd welke site de gedrainde workload draait.
$cauParams = @{
ClusterName = $Cluster # FQDN
CauPluginName = 'Microsoft.WindowsUpdatePlugin'
NodeOrder = $NodeOrder # site 1, then site 2
RequireAllNodesOnline = $true
Force = $true
EnableFirewallRules = $true
}
$job = Start-Job { param($p)
Import-Module ClusterAwareUpdating
Invoke-CauRun @p
} -ArgumentList $cauParams
Het laat je zien wat er gebeurt. Invoke-CauRun blokkeert en drukt niets nuttigs af naar de console. Door het als background job te starten blijft de main thread vrij om Get-CauRun en Get-ClusterNode elke twintig seconden te pollen en alleen de wijzigingen te tonen: een node die naar Suspending gaat terwijl hij draint, Restarting bij een herstart, de cluster state die naar Down klapt en terug naar Up. Ik volgde de run tijdens een ontspannen lunch aan mijn bureau: de tamelijk saaie logfeed die zijn voortgang toonde op het ene scherm, Failover Cluster Manager open op de node in behandeling op het tweede, en de Cluster Aware Updating-console op het derde. Alle drie waren het elke twintig seconden met elkaar eens. Het was duidelijk dat dit uitstekend ging. Die driedubbele bevestiging is het verschil tussen vertrouwen en bijna drie uur lang zenuwachtig verversen.
Een valse start. De eerste poging stierf in zes seconden op een foute pluginnaam (Microsoft.WindowsUpdatePlugin, niet Microsoft.WindowsUpdate; Get-CauPlugin geeft de geregistreerde namen weer). De les die daarna in het script is ingebakken: verzamel de error stream van de job en meld de fout luid, want een script dat "complete" afdrukt na een run die nooit begon, is erger dan geen script.
De run installeerde de cumulatieve update, de .NET-rollup en de definition updates op elke node, waarbij elke node om de beurt werd gedraind, gepatcht, herstart en hervat, eerst de ene site en daarna de andere. Get-CauReport bevestigde het daarna: succeeded, drieëntwintig updates, niets gefaald, niets geannuleerd.
7. Waarom dit werkte en wat het kostte
De verleiding bij een patch backlog van zeven maanden is om de updates gewoon uit te voeren en te hopen. De backlog was het symptoom dat zichtbaar was. De omstandigheden die patchen gevaarlijk maakten, driftende klokken, verouderde openstaande operaties, een niet-geverifieerde policy-rollout, een DNS-laag midden in een migratie, waren niet zichtbaar totdat het inventarisatiescript ze had gemeten.
In die volgorde doet de werkwijze haar werk. Meet alles, benoem de afwijkingen, bepaal de afhankelijkheidsvolgorde, meet opnieuw na elke wijziging, en voer dan pas de riskante operatie uit, afgeschermd achter een laatste validatie en verpakt in een script dat zijn eigen precondities controleert. De patch-night was saai omdat niets eraan aan het toeval werd overgelaten, inclusief de timing. Het verschil van vijf tot zes uur tussen Bangkok en Nederland blijkt een echt operationeel voordeel voor kritiek onderhoud. Ik kon uitgerust aan de laatste checks beginnen, het CAU-script starten in het rustigste uur van de klant, en zag het klaar zijn tijdens mijn lunch, terwijl hun werkdag net begon.
Waar staat je cluster voordat je aan de volgende Windows Update begint? Een ClusterTriage Hyper-V cluster assessment volgt precies deze werkwijze, en eindigt met de gescripte patchrun die het verschil maakt tussen een saaie nacht en een incident om drie uur 's nachts.
Boek een Hyper-V cluster assessment →Veelgestelde vragen
De vijfstaps werkwijze: (1) Intake: begrijp topologie, storage, tooling, backup, monitoring. (2) Scripted inventory: read-only, herhaalbare PowerShell over alle nodes. (3) Analyse: vergelijk met Microsoft-baselines, rangschik afwijkingen op risico. (4) Bevindingen-document: gestructureerde output met herhaalde metingen om remediation te verifiëren. (5) Actielijst: voer aanbevelingen uit in afhankelijkheidsvolgorde, bewaakt door validatie.
Clock drift tot 86 seconden (breekt Kerberos en CSV), geen Defender exclusions (veroorzaakt trage I/O), pending reboots op vijf nodes, en zeven maanden gemiste patches. Niets daarvan zichtbaar op een dashboard dat alleen groene VM's toont. Een gescripte meting vindt wat dashboards verbergen.
Klokken binnen een seconde, pending reboots opgelost, WinRM bereikbaar op alle nodes, en DNS geverifieerd, kritiek omdat de domeincontrollers midden in een migratie zaten. Elke voorwaarde had een verificatiestap. Een volledige Failover Cluster Validation, met elke regel gelezen en niets overgeslagen, was het laatste groene licht.
Van 06:37 tot 09:08 Amsterdamse tijd (2 uur en 31 minuten). Zes nodes, 23 updates geïnstalleerd, nul fouten, nul geannuleerd. Elke node weer up, elke VM waar die hoort, voordat de eerste gebruikers binnenkwamen op een rustige vrijdagochtend.
De VM had een bekend Live Migration-probleem dat een drain om drie uur 's nachts zou laten vastlopen. Het script verifieert expliciet dat de VM offline is en breekt af als dat niet zo is, want een vastgelopen drain midden in het patchen is onacceptabel. Bekende blokkades moeten vóór de run zijn weggenomen.