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.
92 lines
4.6 KiB
Markdown
92 lines
4.6 KiB
Markdown
# Visión general
|
|
|
|
Este lab corre sobre un NAS ZimaOS doméstico, sin IP pública ni
|
|
presupuesto de nube — cada capa del diagrama de abajo existe por una
|
|
razón concreta de ese contexto, no por moda arquitectónica. Esta
|
|
página explica el "por qué" de cada frontera; el "cómo" vive en las
|
|
páginas enlazadas al final de cada sección.
|
|
|
|
## Flujo de una petición pública
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
User(["Usuario"]) -->|HTTPS| CF["Cloudflare<br/>(DNS proxied + túnel)"]
|
|
CF -->|HTTP/2, red host| CFD["cloudflared<br/>(app ZimaOS)"]
|
|
CFD --> NPM["Nginx Proxy Manager<br/>192.168.68.61:90"]
|
|
NPM --> LB["k3d-lab-cluster-serverlb<br/>(k3d-proxy, 90→80)"]
|
|
LB --> TR["Traefik<br/>(ingress del cluster)"]
|
|
TR -->|Host: shop.cruzcloud.net| FE["frontend-svc<br/>(Next.js)"]
|
|
TR -->|Host: commerce.cruzcloud.net| MED["medusa-svc<br/>(Medusa API)"]
|
|
TR -->|Host: media.cruzcloud.net| MIN["minio-svc<br/>(imágenes de producto)"]
|
|
TR -->|Host: gitea.cruzcloud.net| GIT["Gitea"]
|
|
TR -->|Host: docs.cruzcloud.net| DOCS["docs-portal-svc<br/>(este sitio)"]
|
|
|
|
subgraph GitOps["Control plane GitOps"]
|
|
ARGO["Argo CD"] -->|sync| FE
|
|
ARGO -->|sync| MED
|
|
ARGO -->|sync| DOCS
|
|
GIT -.->|watch repos| ARGO
|
|
end
|
|
```
|
|
|
|
## Componentes
|
|
|
|
| Capa | Qué es | Dónde vive |
|
|
|---|---|---|
|
|
| Cloudflare Tunnel | Expone `*.cruzcloud.net` a internet sin abrir puertos en el NAS | Fuera del cluster, app nativa ZimaOS (`cloudflared`) |
|
|
| Nginx Proxy Manager | Enruta por dominio hacia el cluster | Fuera del cluster, contenedor `nginxproxymanager` |
|
|
| k3d | Cluster Kubernetes local (multi-nodo, Docker) | Host ZimaOS |
|
|
| Traefik | Ingress controller del cluster | Dentro de k3d |
|
|
| Argo CD | Sincroniza el estado del cluster con Git (patrón App of Apps) | Namespace `argocd` |
|
|
| Gitea | Origen de verdad de los manifiestos y del código de las apps | Contenedor propio, expuesto vía túnel |
|
|
|
|
## Por qué cada frontera está donde está
|
|
|
|
**Cloudflare Tunnel, no port-forwarding.** El NAS vive detrás de NAT
|
|
residencial, sin IP pública fija. En vez de abrir puertos en el router
|
|
(superficie de ataque directa contra el hogar), `cloudflared` abre una
|
|
conexión **saliente** hacia Cloudflare y todo el tráfico público viaja
|
|
hacia adentro por esa misma conexión — el origen nunca expone un
|
|
puerto escuchando en internet. El transporte de esa conexión se fijó a
|
|
HTTP/2 en vez del QUIC por defecto tras un incidente real de
|
|
inestabilidad; ver [ADR 0003](../decisiones/0003-por-que-http2-sobre-quic-tunnel.md).
|
|
|
|
**Nginx Proxy Manager, fuera del cluster.** No todo lo que sirve
|
|
`*.cruzcloud.net` vive dentro de k3d — Gitea, por ejemplo, corre como
|
|
contenedor Docker aparte. NPM es el único punto de enrutamiento por
|
|
dominio que necesita conocer *ambos* mundos (cluster y no-cluster), así
|
|
que vive fuera de Kubernetes a propósito, no por descuido.
|
|
|
|
**`k3d-lab-cluster-serverlb`, la frontera de entrada al cluster.** Es
|
|
el load balancer que el propio k3d monta automáticamente para publicar
|
|
puertos del host hacia los nodos internos — no es un componente que
|
|
este lab configuró a mano, viene con la topología multi-nodo elegida
|
|
en [ADR 0001](../decisiones/0001-por-que-k3d.md).
|
|
|
|
**Traefik, enrutamiento por `Host` dentro del cluster.** Una vez el
|
|
tráfico entra al cluster por un único puerto (90/9443), Traefik es
|
|
quien decide a qué Service mandarlo según el header `Host` de cada
|
|
petición — así NPM solo necesita saber "todo `*.cruzcloud.net` va al
|
|
puerto 90 del cluster", sin tener que aprender un forward_host nuevo
|
|
cada vez que se agrega un servicio interno. Cuando esta capa falla en
|
|
silencio (`forward_host`/`forward_port` mal apuntado en NPM), el
|
|
síntoma es siempre el mismo: "internamente sano, públicamente roto" —
|
|
ver [Red y exposición](red-y-exposicion.md).
|
|
|
|
**Argo CD, el único escritor del cluster.** Ningún pipeline de CI ni
|
|
ninguna persona corre `kubectl apply` contra producción — Argo CD es
|
|
la única pieza con permisos de escritura, y reconstruye
|
|
automáticamente cualquier diferencia entre Git y el cluster real
|
|
(`selfHeal: true`). El porqué completo de esa elección está en
|
|
[ADR 0002](../decisiones/0002-por-que-argocd-vs-manual.md); el paso a
|
|
paso de un commit real hasta quedar corriendo, en
|
|
[Flujo GitOps](gitops-flujo.md).
|
|
|
|
**Gitea, autoalojado.** Además de alojar el código, Gitea corre el CI
|
|
(Gitea Actions) y el registry de imágenes en el mismo lugar — un solo
|
|
componente autoalojado en vez de depender de la disponibilidad y los
|
|
límites de un servicio externo gratuito para un lab que ya de por sí
|
|
no tiene presupuesto de nube.
|
|
|
|
Ver también: [Red y exposición](red-y-exposicion.md) · [Flujo GitOps](gitops-flujo.md) · [Glosario](glosario.md)
|