El pod fue desalojado el 2026-08-12 tras 21 días: el emptyDir de dind
superó su límite de 10Gi.
La caché de buildx no era la causa (los workflows hacen `buildx rm` al
inicio de cada run y se recicla sola, ~330M). Lo que se acumula son
imágenes sin tag: al republicar upstream catthehacker/ubuntu:act-22.04,
la anterior (1,5G) queda colgada para siempre.
Ni el GC de dockerd ni el de buildkit lo recogen porque ambos calculan
su umbral contra el disco del nodo (913G), no contra el cap del pod.
Nunca saltan antes del desalojo.
El sidecar hace `docker image prune -f` cada 6h por localhost:2375.
Sin -a: solo dangling, nunca una imagen con tag, así que la caché de
act y la de buildkit siguen intactas y los builds no se frenan.
Se descartó un CronJob externo: exigiría pods/exec o publicar el 2375
como Service, y ese puerto va sin TLS ni auth sobre un docker
privilegiado.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Los dos estaban en git sin ninguna Application que los gestionara: editar el
repo no desplegaba nada. De ahi que un pin de imagen de abril nunca llegara
al cluster y gitea se subiera solo de 1.25.5 a 1.27.0, y que vaultwarden se
parcheara con kubectl replace. A partir de ahora manda git.
Verificado en frio antes de adoptar: los 17 manifiestos coincidian campo a
campo con lo vivo, asi que la adopcion no revierte nada. Con
ServerSideApply/ServerSideDiff, igual que el kube-prometheus-stack: estos
objetos arrastran un last-applied viejo y el merge clasico intentaria borrar
lo que ese blob declaraba y git ya no; en un PVC eso es un campo inmutable y
el sync falla.
Limpieza que iba en el mismo paquete:
- Fuera la basura de export de 5 ficheros: last-applied-configuration, la
revision del Deployment y las anotaciones que pone el provisionador en los
PVC (bind-completed, selected-node...). Es lo que dejaba los recursos
OutOfSync para siempre. Verificado que el resto del manifiesto no cambia.
- Fuera serviceaccount-default y kube-root-ca.crt de los dos: los crea k8s
solo en cada namespace.
- RESCATADO configmap-gitea-runner-config: config del act_runner escrita a
mano en abril, montada por el runner y que NO estaba en git. Reconstruir
gitea desde el repo levantaba el runner sin configuracion.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tres ficheros describían algo distinto de lo desplegado, y aplicarlos rompía
cosas. Ahora coinciden campo por campo (verificado con kubectl diff vacío).
argocd/deployment-argocd-redis.yaml decía `resources: {}` y el nodeSelector por
defecto. Lo vivo lleva el anclaje a chemavx-k8 y límites de 200m/128Mi, sin los
cuales este pod muere con Exit Code 255 tras días de uptime. El arreglo sólo
constaba en argocd-patches/redis-patch.yaml, así que el fichero que uno
aplicaría primero era justo el que deshacía el arreglo. Queda el comentario
explicando por qué el anclaje está ahí, y el parche lleva cabecera diciendo que
es parcial y que no debe compararse con el cluster.
gitea/configmap-daemon-json.yaml le faltaban dos insecure-registries que sí
están vivos (git.chemavx.xyz y gitea.gitea.svc.cluster.local:3000). Comprobado
que lo vivo es lo correcto: el buildkitd.toml declara ese registro como
http/insecure y los workflows de CI empujan ahí. Aplicar el fichero viejo habría
dejado a la CI sin poder subir imágenes.
gitea/configmap-buildkitd-config.yaml es nuevo: ese ConfigMap llevaba 90 días
vivo sin manifiesto ninguno.
Restos de polymarket, decomisado el 2026-07-17: fuera su Namespace de
cluster-wide/namespaces.yaml (11 quedan) y borrado el directorio
polymarket-bot/, que resultó no estar en git siquiera — sus dos ficheros los
descarta .gitignore por autogenerados, así que eran basura local del export de
abril. De paso, namespaces.yaml pierde las anotaciones de último apply y gana
una cabecera: no es la lista completa del cluster (16 apps de ArgoCD crean su
propio namespace) y aplicarlo no lo reconstruye.
La auditoría baja de 26 hallazgos a 13, y ninguno de los 13 es deriva real:
8 son reddit-intel, inactivo a propósito (ver reddit-intel/PROMOTION.md), 3 son
el fichero de parche parcial, uno es un `group: ''` equivalente a estar ausente
y el último era una anotación del controlador, ya fuera del export.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
El commit 22ae5d7 (15-abr) fijó estos tags EN GIT pero nunca se aplicó al
cluster: estos namespaces no están en ArgoCD, así que un cambio en git no llega
solo. Tres meses después git decía 1.25.5 y gitea corría 1.27.0, subido en algún
reinicio sin que nadie lo decidiera. Ahora se fija a los dos lados.
gitea gitea/gitea:latest -> gitea/gitea:1.27.0
gitea (init) busybox -> busybox:1.38.0
gitea-runner gitea/act_runner:latest -> gitea/act_runner:0.6.1
gitea-runner docker:24-dind -> docker:24.0.9-dind
authentik-redis redis:alpine -> redis:8.8.0-alpine
uptime-kuma louislam/uptime-kuma:1 -> louislam/uptime-kuma:1.23.17
homarr homarr:latest -> homarr@sha256:80ee593c...
Los seis primeros se fijan a la MISMA imagen que ya corría: verificado
comparando el repoDigest del tag flotante con el del tag candidato, así que el
reinicio no cambió de versión. Homarr va por digest porque su "latest" es una
build de la rama main (org.opencontainers.image.version=main): no existe un tag
de release que describa lo que corre. Moverlo a una release es otra decisión.
Trampa que casi me come, anotada para la próxima: el imageID de un pod NO
siempre es el digest del registro. Si viene como "repo@sha256:..." lo es; si es
un "sha256:..." pelado es el id local de containerd y NO se puede descargar.
Fijar uptime-kuma a ese id dio ImagePullBackOff; el pod viejo aguantó sirviendo
(maxUnavailable 0 para 1 réplica) y se revirtió sin corte. La comparación buena
es repoDigest contra repoDigest.
De paso, al regenerar gitea-runner desde lo vivo quedan documentados el volumen
buildkitd-config y su montaje, que existían en el cluster y no en git.
Verificado tras cada cambio: rollout completo, versión de la app dentro del pod,
y los cinco servicios respondiendo desde fuera (git 200, home 200, status/auth/
grafana 302 por Authentik). El runner se ha vuelto a registrar en Gitea. Sigue
sin haber pods fuera de Running y las 18 apps de ArgoCD Synced+Healthy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
InfisicalStaticSecret syncs /gitea-runner -> gitea-runner-secret-infisical
(parallel name). Out-of-band: created via kubectl apply; commit is for record.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The old ROOT_URL (gitea.chemavx.xyz) is not routed by traefik, so every
URL Gitea generated from it was broken — including webhook payload repo
URLs, which is why ArgoCD ignored real push events (host mismatch) and
deploys waited for the ~3min polling cycle. Applied live on 2026-06-12.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploy registry:2 as Docker Hub pull-through cache on chemavx-k8 (hostPort 5000,
ClusterIP 10.43.163.56:5000). Configures dind runner to use local mirror via
daemon.json to eliminate Docker Hub rate limit failures in CI/CD.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Delete 26 secret manifests containing REDACTED placeholder values
(15 cert-manager TLS + 11 app secrets across 8 namespaces)
- REDACTED is valid base64 that decodes to non-UTF-8 bytes — ArgoCD
applying these manifests corrupts live secrets in the cluster
- Add .githooks/pre-commit that rejects any .yaml with REDACTED
- Add README.md documenting secret management policy and manual
creation commands for each service
- n8n secret manifests already fixed in previous commits (618b1e8, db04fd2)