Tutorial: Plugin Custom Remediation
Tutorial: Plugin Custom Remediation
This tutorial walks you through extending NVSentinel’s fault-remediation stage with your own repair automation — for example, a custom controller.
By the end you will understand:
- Where custom remediation fits in the NVSentinel pipeline.
- How to register a custom remediation action with no NVSentinel code changes.
- The status-condition completion contract your controller must implement.
Who is this for? Teams already running NVSentinel — who need a repair step NVSentinel does not ship out of the box (CSP RMA tickets, multi-step orchestration, …) instead of the built-in reboot / terminate / GPU-reset actions.
Just want the AI to do it? Jump to Appendix: One-shot AI prompt.
1. Where custom remediation fits
NVSentinel remediates a faulty node in stages:
fault-remediation is the extension point. After a node is cordoned and drained, fault-remediation:
- Resolves the health event’s recommended action (a built-in enum value or a custom string).
- Looks up a matching entry in the
maintenance.actionsHelm config. - Renders a Go template into a Kubernetes Custom Resource.
- Creates that CR in the cluster.
- Polls the CR’s status conditions (
completeConditionType) to avoid duplicate repair requests.
Your controller watches the CR and performs the actual repair.
Built-in vs custom actions
2. Integration approach
fault-remediation creates a Kubernetes CR for your action; your controller watches it, runs the repair, and reports completion via a status condition.
Why your CR must expose status conditions
fault-remediation’s status checker only understands Kubernetes-style conditions — it looks for a
status.conditions[] entry whose type equals completeConditionType and reads its status
(True → done, False → failed/retry).
Many external orchestrators report completion differently (e.g. a phase field, a job exit code, or a
ticket status). Use a thin wrapper CRD whose controller translates external completion into
status.conditions[Complete]=True.
3. The completion contract
Whatever CR NVSentinel creates, fault-remediation decides “is this repair done?” by reading a status condition:
Behavior of the status checker:
- Condition
True→ repair succeeded; equivalent events are marked covered. - Condition
False→ repair failed; NVSentinel drops the group and creates a new CR to retry. There is no “terminal failure” state — if a repair is unrecoverable, keep the condition offTrue(leave itUnknown/absent) rather than settingFalse, or stop requeueing after your own retry budget. - Condition missing /
Unknown→ repair in progress; NVSentinel skips creating a duplicate CR.
fault-remediation derives an effective equivalence group from the matched action — and, when
impactedEntityScope is set, the impacted entity (e.g. reset-GPU-123). It skips creating a new CR
only while a CR in that effective group (or a superseding group) is in progress or already succeeded;
it does not deduplicate every repair on the node.
supersedingEquivalenceGroups lets a broader action cover a narrower one. The subordinate action
lists the group that supersedes it. For example, a node reboot has the same effect as an RMA, so the
hardware-rma action lists restart:
4. Walkthrough — custom CR plugin (step by step)
Step 1 — Emit a custom action from a health event
A health monitor must set both fields — the action type and the custom action name:
Platform-connector overrides cannot configure custom actions. Overrides remap
recommendedActionbetween built-in enum values only (RESTART_VM,REPLACE_VM, …) and do not setcustomRecommendedAction. If an override setsrecommendedAction: CUSTOM, the custom string stays empty and fault-remediation skips remediation as an unsupported action.
Step 2 — Register the action in fault-remediation Helm values
Add your action and its template to
distros/kubernetes/nvsentinel/charts/fault-remediation/values.yaml:
Key fields:
RBAC: fault-remediation auto-generates RBAC from
maintenance.actions(resource name = lowercasekind+s). Use CRD kinds with regular plurals (RemediationRequest→remediationrequests); irregular plurals (Policy→policys) break RBAC.
Step 3 — Template variables
Available in every maintenance template:
Step 4 — Build your controller
Scaffold a controller that:
- Watches your CR kind (
RemediationRequest). - Executes the repair (call a CSP API, open a support ticket, run diagnostics, …).
- Patches the status condition:
Golden rules (same as any NVSentinel plugin):
- Reconcile is idempotent — a no-op once
Complete=True. - Make non-idempotent repairs durably idempotent. A controller restart (or a retry after a
Falsecondition, which spawns a fresh CR) can re-run your repair beforeComplete=Trueis persisted. Guard one-shot side effects (opening a ticket, calling a CSP API) with a durable key such asspec.healthEventIdor a status phase, so the effect happens at most once. - Only set
Complete=Truewhen the repair is actually done; requeue until then. SetComplete=Falseonly when you want NVSentinel to retry with a new CR. - One CR per health event — NVSentinel manages its lifecycle via the equivalence group.
Build and push the controller image with Kubebuilder’s Makefile, pointing IMG at a registry
your cluster can pull from:
Use a public repo so the cluster can pull without credentials. For a private registry (e.g. NVCR), add the cluster’s
imagePullSecretto the controller Deployment viaconfig/.
For a full Kubebuilder scaffold, reconciler walkthrough, and one-shot AI prompt, see Writing a Drain Plugin — Appendix: One-shot AI prompt — the pattern is the same (NVSentinel creates the CR and polls a status condition; your controller reconciles it and sets completion), even though the upstream stage is node-drainer instead of fault-remediation.
For a full working example (custom health monitor, CRD, controller, and Helm values), see the local custom remediation demo — a memory-pressure monitor and reclaim controller on a local KIND cluster (no GPU required).
Appendix: One-shot AI prompt
Paste this to an AI coding agent. It is self-contained: the controller is a standalone Kubebuilder project in any repository; produce Helm values snippets for fault-remediation registration (separate from the controller repo). Replace the bracketed parts.