Repository navigation
feat(remediation): one guarded rke2-agent restart per kubelet incident - #62
Merged
Merged
Conversation
Enables a safe automatic kubelet remediation (cluster-services-831): restart the unit that owns kubelet at most once per incident, only when the disk write probe passed recently, never on a node where that unit is not enabled. Three existing defects made the systemd-restart path unsafe or inert: - The detector remediated every condition with status False. The kubelet monitor reports its HEALTHY state as KubeletDown=False and KubeletUnhealthy=False, so enabling remediation on it would restart on every passing check. - In the DaemonSet, the image's systemctl cannot reach the host systemd. It prints "Running in chroot, ignoring command" and exits 0, so a restart did nothing and was reported as a success. - NodeDoctorKubeletUnhealthy matched KubeletHealthy == 0, which the monitor never emits, so the alert could not fire. Changes: - Monitor remediation policy fields: triggerConditions (problem-polarity trigger), maxAttemptsPerIncident (attempt recorded before dispatch, so a failed or hung restart still counts; reset when the condition clears), cooldown (spans incidents), preconditions (latest observed condition, optional monitor scope, required maxAge; a withheld dispatch does not use up the attempt). Without triggerConditions the legacy rule is unchanged. - systemd-restart: requireServiceEnabled refuses unless systemctl is-enabled says "enabled" (rke2-agent is disabled on RKE2 server nodes). systemctl runs via nsenter into PID 1's namespaces when PID 1 is systemd and our mount namespace differs, and the chroot notice is always an error. - Chart: opt-in monitors.kubelet (healthz only; no systemd/PLEG check on RKE2) with monitors.kubelet.remediation (rke2-agent, 1 per incident, 30m cooldown, write probe within 3m, requireServiceEnabled). The render fails if the write-probe gate is on but the write probe is off. Node reboot or power-cycle is not configurable from this block. - Fix the NodeDoctorKubeletUnhealthy rule to KubeletUnhealthy == 1. Tests: detector policy unit tests (mutation-checked); systemd is-enabled guard, chroot detection and nsenter decision tests; config validation tests; an end-to-end test from helm template through LoadConfig, the detector, the registry and SystemdRemediator to a recording systemctl, covering one restart per incident, no restart on a read-only disk, and refusal on a server node. Refs: cluster-services-831
…c for G204 Refs: cluster-services-831
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the cluster-services-831 postmortem (a1ubr720p02's root disk went read-only and kubelet died). This enables the kubelet monitor and an automatic remediation that is safe to leave on: at most one
rke2-agentrestart per incident, only when the disk write probe (#59) passed recently, and never on a node whererke2-agentis not the enabled unit. IPMI power-cycle and node reboot are not configured anywhere.Why the existing remediation path could not be used as-is
evaluateRemediationremediates every condition whose status isFalse. The kubelet monitor reports its healthy state asKubeletDown=FalseandKubeletUnhealthy=Falseon every passing check, so enabling remediation would have restarted on every healthy node.TestRemediationPolicy_LegacyRuleWouldRestartHealthyKubeletpins this.systemctlcannot reach the host systemd. It printsRunning in chroot, ignoring commandand exits 0, so the restart did nothing and was recorded as a success. I verified this live on a1-ops-prd.NodeDoctorKubeletUnhealthymatchedcondition_type="KubeletHealthy" == 0, which the monitor never emits.Changes
remediationblock. All new fields are opt-in; whentriggerConditionsis unset the legacy rule is unchanged.triggerConditions: problem-polarity trigger. Only the named conditions count, and only when they areTrue.maxAttemptsPerIncident: the attempt is recorded before dispatch, so a failed or hung restart still counts and is not retried. The count resets when the condition clears.cooldown: minimum time between dispatches, across incidents.preconditions: checked against the latest observed condition, with an optional monitor scope and a requiredmaxAge. A withheld dispatch does not use up the attempt.systemd-restartchanges.requireServiceEnabledrefuses unlesssystemctl is-enabledreportsenabled. On RKE2 server nodesrke2-agentis installed but disabled, and restarting it would start a second kubelet.systemctlruns throughnsenter --target 1 --mount --uts --ipc --net --pid.monitors.kubelet. It checks healthz only: kubelet is not a systemd unit on RKE2, and PLEG needs authenticated access to the metrics port.monitors.kubelet.remediationwith defaultsrke2-agent, 1 restart per incident, 30m cooldown, write probe passed within 3m, andrequireServiceEnabled.NodeDoctorKubeletUnhealthynow matchesKubeletUnhealthy == 1.Tests
Detector policy unit tests:
I mutation-checked them: disabling each guard or inverting the trigger fails at least one test.
systemd-restarttests: the is-enabled guard (enabled, disabled, masked, static, not-found, and dry-run), chroot detection, and the nsenter decision against a fake/proc.Config validation tests.
End-to-end (
test/integration/remediation/kubelet_restart_policy_test.go). The chain ishelm templatewith the kubelet remediation on →util.LoadConfig→ProblemDetector→RemediatorRegistry→SystemdRemediator→ a recording fake systemctl. Results:is-enabled rke2-agent, thenrestart rke2-agent, once;is-enabledonly, refused.Two chart checks: the default render has no kubelet monitor, and the render fails when the write probe is off.
Live read-only checks on a1-ops-prd (no restarts):
127.0.0.1:10248/healthzanswers200 okfrom all 13 node-doctor pods.nsenter ... systemctl is-enabledreaches the host systemd: rke2-agent is enabled on the 10 workers and disabled on a1ubmgmtp01-03.Refs: cluster-services-831