Saltar a contenido

Arquitectura

El sistema tiene dos flujos coordinados desde GitLab: uno crea y configura infraestructura; el otro entrega una versión de la aplicación sobre esa infraestructura. Los repositorios de despliegue conservan las referencias de imagen, mientras que los estados de OpenTofu conservan la relación entre configuración y recursos cloud.

Responsabilidades y control

flowchart TB
  source["Repositorios de aplicación"] --> ci["Pipeline de aplicación"]
  templates["Plantillas compartidas"] --> ci
  ci --> registry["Container Registry"]
  ci --> manifests["Manifiestos versionados"]
  manifests --> apply["Job deploy"]
  apply --> agent["GitLab Agent y clúster elegido"]
  infra["Pipeline OpenTofu"] --> cloud["Infraestructura y plataforma"]
  infra <--> state["Estados HTTP en GitLab"]
  cloud --> agent

El pipeline de aplicación produce la imagen y actualiza un repositorio de manifiestos. Después aplica su contenido mediante un contexto proporcionado por GitLab Agent. La decisión DEPLOY_TARGET=eks|gke determina el contexto. El flujo es una entrega iniciada por CI; no hay un reconciliador continuo versionado que vuelva a aplicar Git periódicamente o corrija por sí solo cambios manuales en el clúster.

El pipeline de infraestructura se divide en network, kubernetes, database y platform. Cada raíz usa su propio estado remoto y consume outputs de otras raíces cuando los necesita. platform crea el namespace de aplicación, el secreto de base de datos y el agente; en AWS también instala el controlador de balanceo.

Plano de ejecución en AWS

flowchart TB
  client["Cliente HTTPS"] --> alb["ALB público"]
  alb --> web["Service web y frontend"]
  alb --> rest["Service rest y API"]
  rest --> db["RDS MySQL privado"]
  web -. "API del mismo origen" .-> rest
  nodes["Nodos EKS privados"] --> nat["NAT Gateway"]
  nat --> external["Registry y servicios externos"]

El Ingress del frontend enruta /api/v1 al Service rest:8080 y / a web:8080, con ingressClassName: alb. El cliente JavaScript llama a la API bajo el mismo origen; la relación funcional del diagrama no implica que el servidor frontend actúe como proxy. Declara listeners HTTP/HTTPS, redirección a HTTPS y un certificado ACM existente. El nombre DNS histórico y la referencia de certificado deben adaptarse al entorno destino; el manifiesto no demuestra que se creen el registro DNS o el certificado.

EKS y RDS utilizan subredes privadas. La VPC contiene tres subredes privadas y tres públicas; un NAT Gateway proporciona salida. La regla de entrada de RDS permite MySQL desde el security group de los nodos EKS. RDS no tiene IP pública y su configuración fija multi_az = false.

El grupo de nodos tiene tamaños mínimo, máximo y deseado. Esto no equivale a demostrar que se haya instalado un controlador de escalado de nodos por carga: no aparece Cluster Autoscaler ni Karpenter en los recursos revisados. El detalle y sus implicaciones están en AWS.

Plano de ejecución en GCP

flowchart TB
  web["Service web y frontend"] --> api["Service rest y API"]
  api --> private["Private Service Access"]
  private --> sql["Cloud SQL MySQL privado"]
  nodes["Nodos GKE privados"] --> nat["Cloud NAT y Cloud Router"]
  nat --> external["Registry y servicios externos"]
  network["VPC y rangos secundarios"] --> nodes

La VPC es global y contiene subredes regionales. GKE usa modo VPC nativo y rangos secundarios de pods y Services. Sus nodos son privados; el endpoint de administración se configura separadamente y es público por defecto. Cloud NAT ofrece salida a los nodos y Cloud SQL usa una conexión privada con ipv4_enabled = false.

El diagrama muestra relaciones de dependencia y conectividad interna. La publicación HTTP de GKE no queda resuelta por el Ingress versionado, que selecciona el controlador ALB de AWS y referencia ACM. El código de plataforma GCP no instala un controlador compatible con ese manifiesto. Para reproducir el acceso externo de GKE hace falta una configuración específica del destino o recuperar la configuración externa usada por el autor. Véase GCP.

Contratos entre componentes

Contrato Productor Consumidor Condición de funcionamiento
Imagen Registry/rama:SHA Build de cada app Deployment web o rest La imagen debe existir y poder descargarse
Secreto rest Raíz platform Backend mediante envFrom Credenciales y endpoint coherentes con la base creada
Secreto registry Configuración adicional del entorno Ambos Deployments Está referenciado, pero no se crea en los recursos revisados
Contexto …:eks-agent o …:gke-agent GitLab Agent y permisos CI Job deploy Agente conectado y acceso autorizado
Outputs de estados Raíces anteriores de IaC terraform_remote_state Mismo proveedor/entorno y permisos de lectura
Manifiestos en main update-k8s-manifests Job deploy Token con capacidad real de escritura y lectura

Los namespaces y nombres de Services coinciden entre nubes, pero las cuentas, redes y bases son independientes. La compatibilidad funcional de Kubernetes no elimina las particularidades de ingress, IAM, almacenamiento o red de cada proveedor.

Límites arquitectónicos

No hay configuración de replicación MySQL entre nubes, balanceo global, recuperación automática de una región ni despliegue simultáneo de ambos servicios como transacción. Los proyectos frontend y backend tienen pipelines independientes y sus imágenes se promueven por separado.

ENVIRONMENT distingue nombres de estados y grupos de exclusión mutua del pipeline; no se propaga automáticamente a todos los nombres cloud ni a los tags, varios de los cuales conservan valores fijos de desarrollo. Crear estados con prefijos distintos no garantiza infraestructura aislada. La guía de estado detalla esta frontera.

Fuentes