Reemplaza los placeholders "TODO (fase 2+)" por narrativa completa, grounded en el codigo/manifiestos/incidentes reales del lab (no generico): - ADR 0001 (por que k3d) y ADR 0002 (por que Argo CD): pasan de template vacio a Contexto/Opciones/Decision/Consecuencias reales, apoyados en known-issues.md (blackhole MTU) y en la config real de ecommerce-app.yaml. - vision-general.md: el "por que" de cada frontera de confianza del diagrama. - gitops-flujo.md: ejemplo real con hashes de commit (Fase 3b de ADR 0006, v1.0.171 -> hotfix -> v1.0.172), selfHeal explicado con el syncPolicy real del repo. - red-y-exposicion.md: diagrama de terminacion TLS real, por que todo va "proxied", patron de diagnostico "interno sano, publico roto". - glosario.md: 9 terminos nuevos, cada uno con ejemplo real y verificado del repo (Namespace, ResourceQuota, LimitRange, NetworkPolicy, Deployment, Service, Ingress, StatefulSet, Init container). - notas-sueltas.md: MinIO/S3, limites reales del subscriber revalidate-storefront.ts, que se automatizaria desde cero. Validado con `docker build --target build` (mkdocs build --strict, mismo paso que el pipeline real) -- cero links rotos, cero warnings.
4.3 KiB
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.