ADR 0001 — Por qué k3d (y no k3s directo, minikube, o un cluster cloud)¶
Estado: aceptada Fecha: 2026-08 (retroactiva — decisión tomada al arrancar el lab, documentada en Fase 2 del portal)
Contexto¶
El lab corre sobre un NAS ZimaOS doméstico, sin presupuesto para un cluster gestionado y con recursos modestos y compartidos con otras apps del NAS (Gitea, Nginx Proxy Manager, este mismo portal). El propósito del lab es doble: servir de portafolio técnico real y de material de estudio para el hijo del usuario (7mo semestre de Ingeniería de Sistemas) — ver guía del estudiante. Para que ambos objetivos tengan sentido, el cluster necesitaba comportarse como un Kubernetes real y multi-nodo, no como una caja de arena de un solo proceso: patrones como afinidad de pods, StatefulSets con almacenamiento persistente por nodo, y tráfico cross-node debían poder reproducirse y depurarse de verdad, no simularse.
También pesó la restricción del propio sistema operativo: / en
ZimaOS es un squashfs de solo lectura y /usr es un overlay
igualmente inmutable — instalar un binario nativo como k3s que
espera escribir en /usr/local/bin, /etc/rancher, etc. de forma
persistente no encaja bien con ese filesystem sin trabajo extra de
por medio.
Opciones consideradas¶
| Opción | A favor | En contra |
|---|---|---|
| k3d | Multi-nodo real corriendo como contenedores Docker (server + agent), se crea/destruye en segundos, no toca el filesystem inmutable de ZimaOS más allá de /DATA |
Al ser Docker-in-Docker, hereda las capas de red de Docker — un blackhole de MTU/PMTUD real apareció por esto (ver Consecuencias) |
| k3s directo (sin Docker) | Sin la capa extra de red de Docker-in-Docker, más cercano a un nodo "real" | Necesita instalar servicios systemd y escribir en rutas de sistema (/usr/local/bin, /etc/rancher) que en ZimaOS son de solo lectura o requieren workarounds — solo /DATA y /etc quedan escribibles |
| minikube | Instalación simple, muy documentado, ideal para aprender lo básico | Single-node por defecto — no permite reproducir tráfico cross-node, afinidad de pods, ni el tipo de incidentes de infraestructura real que este lab busca documentar como aprendizaje |
| Cluster gestionado (cloud) | Cero mantenimiento de infraestructura, SLA real | Costo recurrente que este lab no tiene presupuestado; además reduce el valor de aprendizaje — gran parte de lo documentado en playbooks/ (MTU, DNS, límites de recursos) es justamente lo que un proveedor gestionado abstrae |
Decisión¶
k3d, multi-nodo (hoy: 1 server + 1 agent, k3d-lab-cluster-server-0 /
k3d-lab-cluster-agent-0), corriendo como contenedores Docker sobre
el propio NAS.
Consecuencias¶
- Se ganó un cluster real y gratuito, reproducible con un solo
script (
scripts/deploy-lab.sh), y suficientemente parecido a un Kubernetes de producción como para que los incidentes documentados enplaybooks/sean transferibles a un entorno cloud real. - Se pagó con un blackhole de red cross-node real: cualquier pod
agendado en un nodo distinto al de
commerce-postgres-0(StatefulSet, fijo a un nodo) fallaba de forma consistente al hablar con Postgres — diagnosticado hasta el bit exacto (payload interno 1420 bytes OK, 1450 bytes blackhole total, sin ICMP "frag needed") y resuelto ajustando el MTU real de la interfazflannel.1a 1400 en cada nodo. Ver known-issues.md y el playbook del crashloop de Medusa para el diagnóstico completo. El fix no persiste solo — está automatizado enscripts/deploy-lab.sh(funciónfix_flannel_mtu), se reaplica cada vez que el cluster arranca o se recrea. - Deuda aceptada a propósito: el
podAffinityque fuerza amedusa-deploya compartir nodo con Postgres se dejó como red de contención extra después del fix de fondo — no es estrictamente necesario, pero es barato mantenerlo. - Para revertir esta decisión haría falta migrar a un cluster
gestionado o a
k3snativo, lo que implicaría asumir el costo recurrente (cloud) o resolver las restricciones de filesystem inmutable de ZimaOS (k3s nativo) — ninguna de las dos se justifica hoy con el tamaño real del lab.