Tutorial: Requesting Node Maintenance
This tutorial walks you through creating a MaintenanceRequest, which tells NVSentinel that a node needs planned maintenance. NVSentinel then cordons the node and drains its workloads before the maintenance starts.
By the end you will have:
- The MaintenanceRequest controller enabled on your cluster.
- The RBAC permissions to create a MaintenanceRequest.
- A tested maintenance cycle: NVSentinel cordons and drains a node, and uncordons the node after you delete the MaintenanceRequest.
Who is this for? Teams that already run NVSentinel and must tell it about maintenance that it cannot detect. For example, a cloud provider sends a maintenance notice, or an operator plans a hardware replacement.
Just want the AI to do it? Jump to Appendix: One-shot AI prompt.
Safety: Use a test node that has no important workloads. NVSentinel cordons and drains the node that the MaintenanceRequest names. If you do not delete the MaintenanceRequest, the node stays cordoned.
Prerequisites
- NVSentinel v1.25.0 or later.
- NVSentinel with fault-quarantine and node-drainer enabled. These components are disabled by default.
- Helm 3.14 or later and
kubectl. - Cluster-admin access to upgrade the NVSentinel Helm release and to create a ClusterRole.
- A test node that NVSentinel can cordon and drain.
See the NVSentinel Helm chart guide for the complete NVSentinel prerequisites.
1. How a MaintenanceRequest works
A MaintenanceRequest is a Kubernetes custom resource that NVSentinel defines. It contains a health event that names the node and the action for NVSentinel to take.
The health event names an action, such as a reboot. After node-drainer drains the node, fault-remediation runs that action.
The MaintenanceRequest stays in the cluster until you delete it. While it exists, the node stays cordoned. When you delete it, lifecycle-manager publishes a clearing event, and fault-quarantine uncordons the node.
Note: NVSentinel acts when you create the MaintenanceRequest. It does not wait for
startTime. ThestartTimefield is for information only. NVSentinel shows the value in thekubectl getoutput but does not use it to schedule work.
For the design rationale and limitations, see ADR-051.
2. Enable the MaintenanceRequest controller
The lifecycle-manager component and its MaintenanceRequest controller are disabled by default. Create a values file that enables both:
This setting also installs two webhooks and a ClusterRole. A webhook makes the Kubernetes API server check each MaintenanceRequest before it stores the object. Webhooks and ClusterRoles apply to the full cluster, so this step needs cluster-admin access.
Note: If platform-connector authentication is enabled (
global.platformConnectorAuth.enabled: true), this change restarts the platform-connector pod on every node. The chart adds lifecycle-manager to the list of callers that platform-connector accepts. While a platform-connector pod restarts, it cannot receive health events from its node.
Before you upgrade, make sure that the lifecycle-manager CRDs are in the cluster. Helm installs CRDs only when it installs a chart for the first time. It does not install them during helm upgrade.
If the command returns NotFound, apply the CRDs from the chart:
Apply the values file. The --reset-then-reuse-values flag applies the new chart defaults, then keeps your current values.
Make sure that lifecycle-manager is running:
The chart configures authentication and the quarantine rule for you. To learn how they work, or to see every check that the webhook applies, read Lifecycle Manager Configuration.
3. Grant RBAC to a ServiceAccount
If you create MaintenanceRequests by hand with cluster-admin access, skip this section.
A program that creates MaintenanceRequests needs its own permissions. Kubernetes gives each program an identity called a ServiceAccount. The ServiceAccount needs a ClusterRole, because a MaintenanceRequest belongs to the full cluster and not to one namespace.
Save this file as maintenancerequest-rbac.yaml. Change maintenance-automation and maintenance to the name and namespace of your ServiceAccount.
Apply the file:
Make sure that the ServiceAccount can create a MaintenanceRequest:
4. Create a MaintenanceRequest
Create the MaintenanceRequest at the time you want NVSentinel to drain the node.
Set the name of your test node:
Create a MaintenanceRequest for the node:
This MaintenanceRequest uses recommendedAction: NONE. NVSentinel cordons and drains the node, and then does no other work. To make NVSentinel do more work after the drain, change recommendedAction.
fault-remediation selects the work after the drain. Its configuration maps each recommendedAction to a maintenance resource. The table shows the result with the default fault-remediation configuration. If you changed maintenance.actions in the fault-remediation Helm values, the result can be different.
Note: The webhook replaces the value of
agentwithlifecycle-manager. The webhook keeps your value inhealthEvent.metadata.maintenanceRequestRequesterAgent.
Note: The webhook does not let you change
spec.healthEventafter you create the MaintenanceRequest.
5. Validate the MaintenanceRequest
Run the commands in this section while the MaintenanceRequest exists. You delete the MaintenanceRequest in section 6.
Wait for lifecycle-manager to publish the health event:
Make sure that NVSentinel cordoned and drained the node. The -L flag adds a column for the NVSentinel state label.
SchedulingDisabled shows that fault-quarantine cordoned the node. The NVSENTINEL-STATE column shows the progress of the drain:
If the value is quarantined or draining, run the command again after a few seconds.
For all values of this label, see State Manager.
6. Return the node to service
When the maintenance is complete, delete the MaintenanceRequest:
The MaintenanceRequest has a finalizer. A finalizer stops Kubernetes from removing an object until a controller completes its cleanup. Here, lifecycle-manager first publishes the clearing event. Then lifecycle-manager removes the finalizer, and Kubernetes removes the MaintenanceRequest.
Make sure that fault-quarantine uncordoned the node:
The status no longer shows SchedulingDisabled, and the NVSENTINEL-STATE column is empty. If the node still shows SchedulingDisabled, run the command again after a few seconds.
Note: NVSentinel uncordons the node when you delete the MaintenanceRequest, even if the action from
recommendedActiondid not finish.
Troubleshooting
The API server rejects the MaintenanceRequest
The webhook checks each MaintenanceRequest before the API server stores it. If a check fails, kubectl shows the reason at the end of the error:
Note: When you delete the MaintenanceRequest, NVSentinel uncordons the node. Pods can start on the node before you create the new MaintenanceRequest.
The HealthEventEmitted condition is False
Read the reason and the message of the condition:
lifecycle-manager sends the health event through a socket on its own node. Compare the NODE column of the two pods:
NVSentinel does not cordon the node
If the HealthEventEmitted condition is True but the node does not show SchedulingDisabled, check these causes in order.
-
fault-quarantine is not enabled. fault-quarantine is disabled by default.
If the deployment does not exist, set
global.faultQuarantine.enabled: truein your NVSentinel Helm values. -
The node is opted out of NVSentinel. fault-quarantine does not cordon a node when one of these labels has the value
false:nvsentinel.dgxc.nvidia.com/managedk8saas.nvidia.com/ManagedByNVSentinel
Show the value of both labels on the node. The
-Lflags add aMANAGEDcolumn and aMANAGEDBYNVSENTINELcolumn.If the
MANAGEDcolumn or theMANAGEDBYNVSENTINELcolumn showsfalse, the node is opted out. -
The circuit breaker tripped. fault-quarantine stops all cordons when too many nodes are cordoned. First, make sure that the circuit breaker is enabled:
If the value is
false, the circuit breaker does not stop cordons, so go to the next cause. Thecircuit-breakerConfigMap can keep an oldTRIPPEDvalue after the circuit breaker is disabled.If the value is
true, check the circuit breaker state:If the value is
TRIPPED, follow the circuit breaker runbook. -
The quarantine rule is missing. fault-quarantine cordons the node only if a ruleset matches the health event.
If the output is empty, restore the
MaintenanceRequest rulesetentry infault-quarantine.ruleSets. -
platform-connector rejected the health event. For the authentication checks and the
platform_connector_auth_violations_totalmetric, see Lifecycle Manager Configuration.
The drain state is drain-failed
node-drainer could not evict all pods from the node. The node stays cordoned. List the pods that are still on the node:
A PodDisruptionBudget or the node-drainer eviction mode can stop an eviction. For the eviction modes, see Node Drainer Configuration.
The MaintenanceRequest stays after you delete it
lifecycle-manager removes the finalizer only after platform-connector accepts the clearing event. Until then, the kubectl delete command waits and does not show the deleted message. Ctrl+C stops only the wait. The API server already marked the MaintenanceRequest for deletion, so the deletion continues.
Make sure that the deletion is waiting for the finalizer:
lifecycle-manager cannot publish the clearing event. Use the EmitFailed fix in The HealthEventEmitted condition is False. When the clearing event succeeds, lifecycle-manager removes the finalizer.
If you cannot repair platform-connector, remove the finalizer yourself.
Safety: If you remove the finalizer, lifecycle-manager does not publish the clearing event. The node stays cordoned until you uncordon it. An uncordon also cancels every other active fault on the node, so check the other faults first.
Show the health events that keep the node cordoned:
If the list contains only the checkName of your MaintenanceRequest, uncordon the node:
If the list contains other checks, keep the node cordoned. Uncordon it only after those faults clear. For what NVSentinel does when you uncordon a node, see Cancelling Break-Fix Workflows.
The node stays cordoned after you delete the MaintenanceRequest
Show the health events that keep the node cordoned:
- If the output contains the
checkNameof your MaintenanceRequest, fault-quarantine did not process the clearing event. Check the circuit breaker, as in NVSentinel does not cordon the node. A tripped circuit breaker also stops the uncordon. - If the output contains only other checks, other faults keep the node cordoned. NVSentinel uncordons the node when those faults clear.
Appendix: One-shot AI prompt
Paste this prompt into an AI coding agent that has access to your cluster. Replace the bracketed values before you run it.