Files
k8s-manifests/CLAUDE.md
T
chemavxandClaude Opus 5 f0e99635bf CLAUDE.md: el auto-reinicio ahora falla en cerrado y con permisos por nombre
Anade tambien como leer por que rama fue una ejecucion cuando
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none ya la ha vaciado: por la duracion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:08:50 +00:00

5.0 KiB

Notas para agentes que trabajan en este cluster

Este es el directorio de trabajo de Hermes (el agente de Telegram) y de cualquier sesión de Claude Code sobre el homelab. Aquí van solo las cosas que engañan al mirarlas: lo que parece una avería y no lo es, y lo que parece inofensivo y no lo es. Lo demás está en el skill k8s-infra.

n8n: las ejecuciones «running» que nunca terminan NO están colgadas

Desde el 2026-07-30 el deployment lleva EXECUTIONS_DATA_SAVE_ON_SUCCESS=none. Cuando un workflow sale bien, n8n crea igualmente la fila en execution_entity, le pone deletedAt al instante y no actualiza el estado, porque la va a tirar. El barrido duro se las lleva cada ~15 min.

O sea que SELECT ... FROM execution_entity enseña filas con status='running' y stoppedAt=NULL que son ejecuciones exitosas ya borradas. No hay nada que arreglar. Ya provocó un diagnóstico en falso el mismo día que se puso.

Para saber si un workflow corre de verdad, mirar workflow_statistics:

SELECT name, count FROM workflow_statistics WHERE workflowId='<id>';
-- production_success sube en cada vuelta aunque la ejecución no se guarde

Sale también en deletedAt IS NOT NULL. Y ojo: startedAt y deletedAt no llevan el mismo huso, así que restarlas no significa nada.

n8n: lo que se ejecuta es la versión PUBLICADA, no el borrador

workflow_entity.nodes es el borrador. Producción usa la versión de workflow_history apuntada por workflow_entity.activeVersionId. Editar nodes a mano y reiniciar no cambia nada y no da ningún error. La API pública (PUT /api/v1/workflows/{id}) sí publica; parcheando SQLite hay que escribir en las dos tablas.

Diagnóstico rápido: comparar las dos columnas. Si difieren, lo que corre no es lo que estás leyendo.

Antes de tocar una BD de un pod: desarmar ArgoCD

Casi todo está bajo Applications con automated{selfHeal,prune}. Un kubectl scale --replicas=0 para hacer un VACUUM se revierte solo a mitad.

kubectl -n argocd patch app <app> --type json \
  -p '[{"op":"remove","path":"/spec/syncPolicy/automated"}]'
# ... trabajo ...
kubectl -n argocd patch app <app> --type merge \
  -p '{"spec":{"syncPolicy":{"automated":{"prune":true,"selfHeal":true}}}}'

Rearmarlo al final levanta el pod y aplica la config nueva de una vez.

ArgoCD: una Application de directorio se traga los .json

path: n8n incluye *.yaml, *.yml y *.json como manifiestos. Un JSON que no sea un objeto de Kubernetes deja la app en ComparisonError («Object 'Kind' is missing»). Por eso application-n8n.yaml tiene directory.exclude: "workflow-*.json". Los .md no se parsean: este fichero es seguro.

El auto-reinicio de Uptime Kuma sí funciona (desde 2026-07-30) y va cerrado

Kuma cae → notificación «n8n Auto-Restart» → webhook público de n8n → PATCH del restartedAt. Antes no reiniciaba nada (sin RBAC: 403), y sus «éxitos» eran el aviso de FALLO enviándose bien.

  • La SA es n8n-restarter. Desde el 2026-07-31 son Roles por namespace con resourceNames sobre los 12 workloads exactos del SERVICE_MAP (ver n8n/rbac-restarter.yaml), no un ClusterRole abierto. Si añades un servicio al mapa, hay que añadirlo también ahí o dará 403 — deliberado: el mapa y el permiso se mueven juntos. Motivo: esa SA va montada en el pod entero de n8n y los nodos Code leen el token de /var/run/secrets/…, así que cualquier workflow con un nodo Code hereda lo que se conceda aquí. El límite no es el mapa, es el RBAC.
  • La clave del mapa es el nombre exacto del monitor en Kuma. Renombrarlo allí lo desconecta en silencio.
  • El webhook exige la cabecera X-Kuma-Token (secret n8n-kuma-webhook, fuera de git) y desde el 2026-07-31 falla en CERRADO: el env ya no lleva optional, así que sin secreto el pod no arranca, y la puerta lanza error si la variable falta. Antes se saltaba la comprobación «para no quedarte sin avisos», y ese argumento era falso: el aviso de caída lo manda Kuma por su notificación 1, directa, no por este webhook.
  • Para apps bajo ArgoCD, el restartedAt se revierte tras el reinicio. El pod sí se reinicia; la anotación no queda. No es un fallo. Por eso el éxito se comprueba con observedGeneration >= la generation que devolvió el PATCH, y con >= y no con ==: la reversión vuelve a subir la generation.
  • Cómo saber por qué rama fue una ejecución cuando SAVE_ON_SUCCESS=none ya la ha vaciado: por la duración. deletedAt - startedAt (con el offset fijo de 1 h) da ~0,02 s si la puerta rechazó, ~0,3 s si el PATCH falló y se fue por la rama de fallo, y ~60 s si hizo el ciclo completo con su espera.

Un workflow que termina en verde no dice que haya hecho su trabajo

Vale para n8n y para cualquier automatismo de aquí: comprobar el efecto (que el restartedAt cambió, que el pod es nuevo, que el fichero está), no el código de salida ni el contador de éxitos.