Saltar a contenido

Glosario

Pensado para alguien que ve estos términos por primera vez. Definiciones cortas primero, detalle técnico después. Se irá expandiendo en fases siguientes — por ahora cubre los términos que ya aparecen en el resto del sitio.

GitOps

En una frase: el estado deseado del sistema vive en Git, y un proceso automático (no una persona con kubectl) se encarga de que el cluster real coincida con lo que dice Git.

Detalle: en vez de ejecutar comandos contra el cluster a mano, se edita un archivo YAML, se hace commit, y una herramienta (aquí, Argo CD) detecta el cambio y lo aplica. Si alguien cambia algo directo en el cluster sin pasar por Git, GitOps lo revierte (selfHeal) — Git es la única fuente de verdad.

Tunnel (Cloudflare Tunnel)

En una frase: una forma de exponer un servicio interno a internet sin abrir puertos en el router/firewall.

Detalle: un proceso (cloudflared) corre dentro de la red local y abre una conexión saliente hacia Cloudflare. El tráfico público llega a Cloudflare y viaja hacia adentro por esa misma conexión — no hace falta port-forwarding ni IP pública propia.

Argo CD

En una frase: el "robot" que sincroniza el cluster Kubernetes con lo que está escrito en Git.

Detalle: vigila uno o más repos Git, compara el estado declarado (manifiestos YAML/Kustomize) contra el estado real del cluster, y aplica la diferencia. Ver flujo GitOps.

Manifest (manifiesto)

En una frase: un archivo YAML que describe qué quieres que exista en Kubernetes (un Deployment, un Service, un Ingress...).

Detalle: Kubernetes no se controla escribiendo código imperativo ("crea un pod"), sino declarando el resultado deseado ("quiero 2 réplicas de esta imagen corriendo"). El manifiesto es ese documento.

App of Apps

En una frase: un patrón donde una Application de Argo CD no despliega una app directamente, sino que despliega otras Applications.

Detalle: en este lab, application.yaml (raíz) vigila la carpeta apps/ de apps-registry; cada archivo ahí dentro es una Application hija que a su vez apunta a un workload real. Permite agregar una app nueva con un solo archivo YAML nuevo.

Kustomize

En una frase: una forma de componer manifiestos de Kubernetes sin plantillas (a diferencia de Helm).

Detalle: un archivo kustomization.yaml lista qué recursos YAML incluir y qué parches aplicarles, sin necesidad de un lenguaje de templating separado.

Namespace

En una frase: una partición lógica dentro del mismo cluster físico — agrupa recursos relacionados y les pone un límite alrededor.

Detalle: este lab tiene un namespace por dominio de negocio (ecommerce, docs-portal) más argocd para el propio Argo CD. Todo lo que gobierna a un namespace (cuotas, políticas de red) vive en platform-infra, separado de los manifiestos de la app — así una app nueva no puede "olvidarse" de traer su propia gobernanza.

ResourceQuota

En una frase: el techo total de recursos que un namespace entero puede consumir, sumando todos sus pods.

Detalle: la cuota real de ecommerce (platform-infra/ecommerce-governance/resourcequota.yaml):

hard:
  requests.cpu: "3"
  requests.memory: 4Gi
  limits.cpu: "8"
  limits.memory: 8Gi
  pods: "12"
  persistentvolumeclaims: "6"
  requests.storage: 80Gi

Si un Deployment nuevo pidiera más requests.memory del que queda disponible bajo ese techo, Kubernetes rechaza el pod directamente — no lo deja arrancar y luego fallar.

LimitRange

En una frase: los valores por defecto (y los mínimos/máximos) que aplican a un contenedor individual dentro de un namespace, para cuando el manifiesto no los declara explícitos.

Detalle: complementa a ResourceQuota (que mira el namespace entero) a nivel de un solo contenedor. La de ecommerce (limitrange.yaml) pone defaultRequest: 100m/128Mi, default: 500m/512Mi (límites si el contenedor no los declara), y un rango permitido de 10m/16Mi a 2 CPU/1Gi por contenedor — evita tanto el contenedor que no pide nada y termina compitiendo mal por recursos, como el que pide de más y se come la cuota del namespace entero él solo.

NetworkPolicy

En una frase: un firewall a nivel de Kubernetes — qué tráfico de red se permite entrar (o salir) de un pod.

Detalle: sin ninguna NetworkPolicy, todos los pods de un cluster pueden hablarse entre sí libremente. La de ecommerce (networkpolicy.yaml) usa podSelector: {} (aplica a todos los pods del namespace) y permite ingress solo desde namespaceSelector: {} (cualquier namespace del cluster, típicamente Traefik llegando desde kube-system o el namespace de ingress) — bloquea tráfico externo al cluster que intentara saltarse Traefik y pegarle directo a un Service interno.

Deployment

En una frase: el controlador para cargas de trabajo sin estado — réplicas intercambiables entre sí, ninguna con identidad propia.

Detalle: frontend-deploy es un Deployment de 2 réplicas: no importa cuál de las dos atienda una petición, ambas sirven exactamente lo mismo y ninguna guarda datos propios en disco. Si un pod muere, Kubernetes crea otro cualquiera para reemplazarlo — no hay "el pod original" que recuperar. Contrastar con StatefulSet abajo.

Service

En una frase: un nombre de red estable que apunta a un grupo de pods, aunque esos pods cambien.

Detalle: los pods son efímeros (mueren y se recrean con IP nueva cada vez); un Service (ej. frontend-svc, postgres-svc) les da un nombre DNS interno fijo (frontend-svc.ecommerce.svc.cluster.local, o simplemente frontend-svc desde dentro del mismo namespace) que no cambia aunque los pods de atrás sí. postgres-svc en este lab es además un Service clusterIP: None ("headless") — necesario porque commerce-postgres es un StatefulSet y cada pod necesita su propia identidad de red estable, no una IP compartida balanceada entre réplicas.

Ingress

En una frase: la regla que dice "las peticiones a este dominio y esta ruta van a este Service", para tráfico HTTP que entra al cluster.

Detalle: ecommerce-ingress enruta por path, no solo por dominio: shop.cruzcloud.net/api/catalog va a catalog-api-svc, y todo lo demás (/) va a frontend-svc — un solo objeto Ingress con dos backends distintos según el prefijo de la URL. Es Traefik (el Ingress Controller del cluster) quien lee estos objetos y hace el enrutamiento real; el Ingress en sí es solo la declaración de la regla, no el componente que la ejecuta.

StatefulSet

En una frase: el controlador para cargas de trabajo con estado — cada réplica tiene identidad propia y almacenamiento propio que sobrevive a que el pod se reinicie.

Detalle: commerce-postgres es un StatefulSet, no un Deployment, porque el frontend puede tener 2 réplicas idénticas sin datos propios, pero Postgres no — sus datos tienen que vivir en un disco específico que sobreviva un reinicio del pod y sepa exactamente cuál pod es "el suyo". Cada pod de un StatefulSet obtiene su propio PersistentVolumeClaim vía volumeClaimTemplates (acá, postgres-data, 10Gi en local-path) y un nombre de red estable y numerado (commerce-postgres-0), a diferencia de los nombres aleatorios de un Deployment. Meilisearch, Redis y MinIO en este lab siguen el mismo patrón por la misma razón — todos guardan datos en disco que tienen que sobrevivir al pod.

Init container

En una frase: un contenedor que corre antes que los contenedores principales de un pod, y tiene que terminar bien (exit 0) para que el resto arranque.

Detalle: medusa-deploy usa dos, y a propósito están separados en vez de ser uno solo: wait-for-postgres (pg_isready en loop, solo espera a que Postgres acepte conexiones) y migrations (db:migrate, corre las migraciones de verdad). Un incidente real mostró por qué separarlos importa: cuando el chequeo de disponibilidad reusaba la misma DATABASE_URL completa de la app (con ?sslmode=disable incluido), el parser de pg_isready no la entendía y el pod quedaba atascado en Init — reportado como si fuera CrashLoopBackOff, sin serlo. El fix fue que el chequeo de disponibilidad use el mínimo de parámetros posible (host/puerto/usuario/db), nunca la URI completa pensada para la app. Ver el playbook del crashloop de Medusa.