Kured
Daemon de reinicio de Kubernetes (Kubernetes Reboot Daemon): reinicia los nodos
de forma segura cuando el SO lo pide tras instalar parches de seguridad.
Resumen
Kured corre como DaemonSet en los 3 nodos y vigila el sentinel
/var/run/reboot-required (generado por unattended-upgrades). Cuando lo
detecta dentro de la ventana configurada, hace cordon + drain del nodo, lo
reinicia y lo vuelve a uncordon. Un lock en la API serializa los reinicios:
nunca se reinician dos nodos a la vez.
Estado
| Campo |
Valor |
| Estado |
Operativo |
| Argo CD Application |
kured |
| Namespace |
kured |
Despliegue
| Campo |
Valor |
| Método |
Helm chart |
| Chart / imagen |
kured@6.1.0 (appVersion 1.23.0) |
| Origen |
https://kubereboot.github.io/charts |
| Config en el repo |
clusters/luka/apps/kured/application.yaml |
Red
| Campo |
Valor |
| Service |
— (DaemonSet, no expone nada) |
| IP |
— |
| Puertos |
— |
| URL interna |
— |
| URL externa |
— |
| TLS |
— |
Acceso y usuarios
- No tiene usuarios ni interfaz. Logs vía
kubectl -n kured logs.
Configuración
- Ventana de reinicio:
startTime: 06:00, endTime: 08:00, timeZone:
Europe/Madrid (hora local).
- Comprobación del sentinel: cada
10m (period), acortado para que los 3
nodos puedan reiniciarse serialmente dentro de la ventana de 2 h.
- Sentinel:
/var/run/reboot-required (hostPath montado en /sentinel).
- Taint previo al drenado:
weave.works/kured-node-reboot
(PreferNoSchedule) para que Longhorn deje de programar réplicas en el nodo.
- Lock: sin TTL (serialización estricta; nunca dos nodos a la vez). Si un
nodo se queda colgado, el lock
weave.works/kured-node-lock se limpia a mano
(se ignora en Argo CD para que el selfHeal no lo borre).
- Drenado:
drainGracePeriod: 60, drainTimeout: 10m; forceReboot: false
(si el drenado falla, no fuerza el reinicio).
- Bloqueo por pods:
blockingPodSelector: [cnpg.io/instanceRole=primary] —
kured no reinicia un nodo que aloje un primario CNPG (el drenaje fallaría por
el PDB, ver Notas). Esos nodos se reinician a mano.
- Disparador (SO):
unattended-upgrades instala parches de noble-security
y deja el sentinel; Automatic-Reboot: false (el reinicio lo hace Kured). Ver
rol Ansible k3s/ansible/roles/unattended-upgrades/.
Almacenamiento
- — (sin PVC; solo monta el directorio del sentinel en modo read-only).
Dependencias
- Depende de:
unattended-upgrades en el SO (genera el sentinel).
- Usado por: nadie (servicio de plataforma).
Backup y recuperación
- — (re-desplegable desde Git; sin estado).
Monitorización
- Expone la métrica
kured_reboot_required{node=...} en :8080/metrics
(1 = hay reinicio pendiente).
- Scrapeado vía PodMonitor
kured (clusters/luka/config/servicemonitors/kured.yaml).
Referencias
Notas / TODO
- ⚠️ Incidencia (sep 2026) — resuelta:
failed to create fsnotify watcher: too
many open files (EMFILE). El default fs.inotify.max_user_instances=128 se
agota (kawhi 143 en uso, kobe 134, kyrie 93) y inotify_init() falla → kured
no puede vigilar /var/run/reboot-required. Fix: fs.inotify.max_user_instances=512
y max_user_watches=524288 vía /etc/sysctl.d/90-homelab-inotify.conf
(role longhorn-prereqs; valores adoptados tras la incidencia — RKE2 recomienda
8192, aquí 512 es suficiente para el volumen del homelab). Ya aplicado en los 3
nodos y verificado.
- Notificaciones (Slack/Telegram) pendientes; se añadirán con la observabilidad.
- Validado (sep 2026): test completo de los 3 nodos — cordon→drain→reboot→
uncordon automático, en serie (lock), sin degradar Longhorn ni CNPG.
drainGracePeriod: 60 y drainTimeout: 10m funcionan.
- Requisito de capacity: el control-plane (
kobe) necesita 8 GB. Con
4 GB, al drenar un worker, el churn de pods reasignados + la reconstrucción de
réplicas Longhorn saturaba kobe (load 40, memoria agotada) y colgaba el API.
- Para tests manuales fuera de la ventana: ensanchar
startTime/endTime a
mano y suspender el autosync de Argo CD (el selfHeal revierte el cambio de
ventana en ~1 min).
- Primarios CNPG no se reinician solos: kured no añade el taint
node.kubernetes.io/unschedulable al hacer cordon (solo spec.unschedulable),
por lo que CNPG no detecta el drenaje y no hace switchover → su PDB
(<cluster>-primary, minAvailable:1) bloquea el drain, y kured evicta
mientras tanto pods sin PDB (p. ej. authentik-server) → 502. Fix:
blockingPodSelector: [cnpg.io/instanceRole=primary] — kured se salta los
nodos con primario CNPG; esos nodos se reinician a mano con switchover previo
(docs/runbooks/reboot-nodo-cnpg.md). Ver incidencia
2026-09-24-heimdall-502.