ClusterTriage / Blog / Azure Local

Heeft de remediatie op je Azure Local-cluster echt gewerkt?

Een change-ticket met de status "opgelost" vertelt je dat iemand iets heeft gedaan. Het vertelt je niet dat het cluster zich nu anders gedraagt. Op Azure Local is dat gat groter dan op een klassiek Hyper-V-cluster, omdat het platform een eigen idee heeft over hoe het geconfigureerd hoort te zijn, en een deel van je wijzigingen stilletjes terugzet.

Dit artikel beschrijft de routine die ik gebruik om te controleren of een oplossing echt heeft gewerkt: dezelfde meting op elke node, de eigen health checks van het platform, de eventlogs sinds de wijziging, en nog één keer kijken na de volgende update.

Door Hans Vredevoort · 9 november 2026 · 9 minuten leestijd · Azure Local

1. Gesloten is niet opgelost

Elk cluster assessment eindigt met een lijst bevindingen, en elke lijst bevindingen wordt een stapel tickets. Daar gaat het meestal mis. Niet bij het oplossen, maar bij het sluiten. Een ticket gaat dicht als de engineer de wijziging heeft doorgevoerd, niet als iemand heeft gemeten dat de wijziging het effect had dat ze moest hebben.

Meestal is dat hetzelfde. Soms niet, en op Azure Local zijn er een paar extra redenen waarom:

  • Het platform beheert een deel van zijn eigen configuratie. Network ATC is eigenaar van de instellingen van de adapters in zijn intents, en corrigeert afwijkingen. Een instelling die je met de hand op een node hebt aangepast, kan een uur later weer op de oude waarde staan.
  • Updates gaan over de hele stack. Een solution update brengt het besturingssysteem, de agents en via de OEM-extensie vaak ook drivers en firmware. Elk daarvan kan iets terugzetten dat je had opgelost.
  • De portal toont een samenvatting, niet de node. Wat Azure je laat zien, is het laatste resultaat dat Azure heeft bereikt. Dat is niet per se de toestand van elke node op dit moment.

Daarom behandel ik elke gesloten bevinding als een bewering die nog bewijs nodig heeft. Dat is geen wantrouwen tegenover wie het werk heeft gedaan. Het is wat we in ons eigen lab ook doen: het Azure Local-cluster met twee nodes uit Azure Local op Proxmox: wat het kostte bestaat juist zodat we nooit hoeven te raden of iets heeft gewerkt.

2. Schrijf de bevinding op als meting

Je kunt een oplossing alleen controleren als je weet wat je controleert. "Opslagnetwerk niet optimaal" valt niet te verifiëren. Dit wel:

  • Wat er mis is: jumbo frames staan op de opslagadapters niet op beide nodes gelijk ingesteld.
  • Waar: node 2, beide poorten van de storage-intent.
  • De gevonden waarde: *JumboPacket = 1514 (jumbo frames uit) op node 2, tegenover 9014 op node 1. Sommige drivers tonen die waarden als tekst, zoals "Disabled" of "9014 Bytes".
  • Het commando dat die waarde opleverde, precies zoals het is gedraaid.
  • De verwachte waarde na remediatie: 9014 op elke opslagpoort van elke node, uit het ontwerp, niet uit het geheugen.

Zo staan bevindingen in een rapport van ClusterTriage, en dat is geen kwestie van stijl. Het maakt de vervolgmeting objectief: hetzelfde commando, dezelfde scope, en een waarde die wel of niet klopt. Komen je bevindingen ergens anders vandaan, herschrijf ze dan in deze vorm voordat iemand begint met oplossen. Het kost tien minuten per bevinding en scheelt later een discussie.

3. Draai dezelfde controle opnieuw, op elke node

De fout die ik het vaakst zie: de node controleren waarop de wijziging is gedaan, en het daarbij laten. Een cluster is zo consistent als zijn minst consistente node, dus de controle draait op allemaal, in één keer, met de resultaten naast elkaar:

Invoke-Command -ComputerName (Get-ClusterNode).Name {
    Get-NetAdapterAdvancedProperty -RegistryKeyword '*JumboPacket' |
        Select-Object Name, DisplayValue
} | Sort-Object PSComputerName, Name |
    Format-Table PSComputerName, Name, DisplayValue

Vergelijk de uitvoer met de verwachte waarde uit de bevinding, de waarde die je eigen ontwerp voorschrijft. Wijkt één regel af, dan is de bevinding niet opgelost, hoe groen het ticket ook is.

Vraag op Azure Local ook aan Network ATC wat die ervan vindt, want voor adapters in een intent beslist ATC:

Get-NetIntent | Select-Object IntentName, NetAdapterNamesAsList
Get-NetIntentStatus | Select-Object Host, IntentName, ConfigurationStatus, ProvisioningStatus

Staat de intent-status niet op elke node op Success en Completed, vertrouw dan geen enkele adapterwaarde die je net hebt gelezen. ATC kan nog bezig zijn, of op het punt staan je wijziging terug te draaien.

4. Lees de health checks van Azure Local, en let op hun leeftijd

Azure Local draait zijn eigen health checks: voor elke update, en tussendoor volgens een schema. Ze zijn nuttig, en ze worden ook het vaakst verkeerd gelezen. Op een node zie je het laatste resultaat:

$envState = Get-SolutionUpdateEnvironment
$envState | Select-Object State, HealthState, HealthCheckDate

$envState.HealthCheckResult |
    Where-Object Status -ne 'SUCCESS' |
    Select-Object Title, Status, Severity, Description, Remediation

Drie dingen om in je achterhoofd te houden als je dit leest.

Het resultaat heeft een leeftijd. HealthCheckDate vertelt je wanneer de controles voor het laatst draaiden. Was dat van voor je oplossing, dan zegt het resultaat niets over je oplossing. Ook de update-readiness in Azure Update Manager kan achterlopen. Is een bevinding net opgelost, start dan eerst een nieuwe run en wacht tot HealthState niet meer op InProgress staat:

Invoke-SolutionUpdatePrecheck -SystemHealth
Get-SolutionUpdateEnvironment | Select-Object HealthState, HealthCheckDate

"Klaar voor update" is niet "bevinding opgelost". De health checks kijken naar wat een update blokkeert of in gevaar brengt. Veel bevindingen uit een assessment vallen daar helemaal buiten: een CSV met de verkeerde eigenaar, een backup die niet alle VM's dekt, een witness waar al een jaar niemand naar heeft gekeken. Een schoon readiness-resultaat is goed nieuws, maar het beantwoordt een andere vraag.

Een waarschuwing is nog steeds een bevinding. Waarschuwingen blokkeren de update niet, en daarom blijven ze vaak staan. Lees ze, en besluit per waarschuwing of die op je lijst hoort.

5. Opslag en cluster: staat alles weer waar het hoort

Veel oplossingen gaan gepaard met een herstart, een drain of een wijziging aan de opslag. Daarna heeft het cluster tijd nodig om weer in een stabiele toestand te komen, en "de wijziging werkt" telt pas als dat zo is. Dit is het korte lijstje dat ik bij elke remediatie draai, wat de bevinding ook was:

# Storage Spaces Direct: open faults en herstel-jobs
Get-HealthFault
Get-StorageJob | Where-Object JobState -ne 'Completed'
Get-VirtualDisk | Select-Object FriendlyName, HealthStatus, OperationalStatus

# Cluster: nodes, resources en shared volumes
Get-ClusterNode | Select-Object Name, State
Get-ClusterResource | Where-Object State -ne 'Online'
Get-ClusterSharedVolume | Select-Object Name, State, OwnerNode

Wat je wilt zien: geen open health faults, geen lopende storage-jobs, elke virtuele schijf Healthy en OK, elke node Up, geen resources offline, en de shared volumes verdeeld over de nodes zoals ze dat voorheen waren. Een herstel-job die nog loopt is geen fout, maar het betekent wel dat je nog niet klaar bent. Kijk opnieuw als hij klaar is.

Is er voor de oplossing een node gedraind, kijk dan ook waar de workloads terecht zijn gekomen. Afhankelijk van hoe de node is hervat, gaat niet alles terug, en een cluster waarin één node alle VM's draagt is technisch gezond en in de praktijk één storing verwijderd van een slechte dag.

Een oplossing telt pas als dezelfde meting een andere waarde laat zien. In een vervolgmeting van ClusterTriage wordt elke gesloten bevinding opnieuw gemeten, op elke node, en het deltarapport laat zien wat er veranderde en wat er terugkwam.

Plan een kennismaking over een Azure Local cluster assessment →

6. Tel de events sinds de wijziging

Sommige bevindingen zijn geen instelling maar gedrag: CSV's die pauzeren, een node die uit de membership valt, opslag die in redirected mode gaat. Dat controleer je niet met één waarde. Dat controleer je door te tellen hoe vaak het event na de oplossing voorkomt, en dat te vergelijken met de periode ervoor.

Neem het tijdstip van de wijziging als startpunt en tel per node:

$since = Get-Date '2026-11-02 18:00'   # tijdstip van de oplossing

Invoke-Command -ComputerName (Get-ClusterNode).Name {
    Get-WinEvent -FilterHashtable @{
        LogName   = 'System'
        Id        = 5120, 1135
        StartTime = $using:since
    } -ErrorAction SilentlyContinue
} | Group-Object PSComputerName, Id |
    Select-Object Count, Name

Event 5120 is een CSV die pauzeerde, 1135 is een node die uit de clustermembership is gehaald. Nul is het antwoord waarop je hoopt, maar nul na één rustige dag bewijst weinig. Laat het minstens één periode doorlopen waarin het oude probleem altijd opdook: een backupvenster, een patchnacht, een drukke maandagochtend. Pas dan betekent nul iets.

Is de telling niet nul, lees dan de events en de clusterlog rond die tijdstippen voordat je de bevinding heropent. Soms is de oorzaak nieuw en heeft hij niets met de oude bevinding te maken. Dat is precies de situatie waarin twee mensen naar dezelfde logs kunnen kijken en twee verschillende verhalen vertellen, waarover ik schreef in Eén incident, twee rapporten.

7. Meet opnieuw na de volgende update

De echte test van een oplossing op Azure Local is de volgende solution update. Dan komen drivers, firmware, agents en Network ATC allemaal aan de beurt, en dan verdwijnt een oplossing die op de verkeerde plek is doorgevoerd.

Het typische voorbeeld is een instelling die Network ATC beheert. Pas je die direct op de adapter aan, dan ziet ATC een afwijking en zet hij hem terug naar wat de intent zegt. De oplossing moet dan in de intent zelf, als override, zodat ATC jouw waarde afdwingt in plaats van de zijne:

$override = New-NetIntentAdapterPropertyOverrides
$override.JumboPacket = 9014        # de waarde uit je ontwerp
Set-NetIntent -Name 'storage' -AdapterPropertyOverrides $override   # de naam van je storage-intent, zie Get-NetIntent

Get-NetIntentStatus -Name 'storage' |
    Select-Object Host, ConfigurationStatus, ProvisioningStatus

Buiten ATC geldt hetzelfde. Een instelling die terugkomt na het opnieuw opbouwen van een node, hoort in de build. Een instelling die terugkomt na een OEM-update, hoort in de OEM-tooling of de hardware-baseline. Een instelling die om de paar uur vanzelf terugkomt, heeft meestal een GPO of een script achter zich.

Daarom plan ik nog één controle na de eerste update na de oplossing, als vaste stap in het updaterunbook, zoals je ook de controles na het patchen plant in Cluster Aware Updating: runbook en audit trail. Draai de commando's uit stap 3 tot en met 6 opnieuw en vergelijk. En bewaar de uitvoer van elke run, met datum en node. Voor en na, naast elkaar, is het bewijs. Een screenshot van een groene portal is dat niet.

Zo werkt onze eigen opvolging ook. In een Assurance-ronde van ClusterTriage wordt elke gesloten bevinding opnieuw gemeten met dezelfde commando's, en het resultaat komt in een deltarapport: opgelost, nog open, of teruggekomen. Hoe dat rapport is opgebouwd, staat in Hoe we het cluster assessment opvolgen.

Veelgestelde vragen

Is een groene readiness-controle in de Azure-portal genoeg om een bevinding te sluiten?

Nee. De health checks van Azure Local kijken naar wat een update blokkeert of in gevaar brengt, en veel bevindingen vallen daarbuiten. Het resultaat kan ook ouder zijn dan je oplossing. Gebruik het als één stuk bewijs, naast dezelfde meting die de bevinding opleverde, opnieuw gedraaid op elke node.

Wanneer controleer ik of een oplossing heeft gewerkt?

Drie keer: direct na de wijziging, nadat het cluster tot rust is gekomen (storage-jobs klaar, workloads terug op hun plek), en na de eerste solution update die volgt. Bij bevindingen over gedrag in plaats van instellingen ook na een periode waarin het probleem altijd optrad, zoals een backupvenster of een patchnacht.

Waarom elke node controleren als de wijziging op één node is gedaan?

Omdat de bevinding over het cluster gaat, niet over de node. Een instelling die op de ene node klopt en op de andere afwijkt, is nog steeds een bevinding, en op Azure Local kan een wijziging op één node Network ATC of andere automatisering in gang zetten die ook de andere nodes raakt.

Wat als de oude waarde steeds terugkomt?

Dan dwingt iets die waarde af. Op Azure Local is dat meestal Network ATC, dat afwijkingen corrigeert op adapters in een intent; de oplossing hoort dan als override in de intent. Andere gebruikelijke verdachten zijn een GPO, een node-image en OEM-updatetooling. Zoek eerst de bron, voordat je de waarde opnieuw aanpast.