Saltar al contenido principal

Sora Project, despegando de verdad

· 5 min de lectura
Rei Izumi
Moon.cat owner

A finales de 2024 presenté Sora Project: Terraform para crear máquinas, FluxCD para desplegarlo todo dentro de Kubernetes y una lista de 💣 pendientes para el siguiente año. Funcionaba, sí. Pero cada pieza requería su propio ritual: lanzar un Terraform a mano, apuntar la IP, crearla en Pi-hole, añadir la máquina en Nagios, rezar para que Longhorn no se despertara de mal humor ...

Lo que tenía era un montón de herramientas automatizadas unidas por un humano. Y el humano acabó hasta las narices.

Entonces llegaron los tiempos de la IA, y después de experimentar hasta la saciedad, pensé "igual es momento de crear mi propio datacenter". Y así nació la nueva versión de Sora Project.

Las piezas​

Esta vez el proyecto se divide en cuatro, cada uno con una única responsabilidad:

  • Sora Conductor: un asistente de terminal que prepara el servidor orquestador, la máquina de la que depende todo lo demás.
  • Sora Horizon: una web que gestiona toda la red y despliega aplicaciones en Proxmox a partir de plantillas.
  • Infraestructura: las plantillas, Terraform y scripts que Horizon importa.
  • FluxCD: todo lo que se ejecuta dentro de Kubernetes.

Sora Conductor​

Todo empieza por un servidor físico que se encarga de lo básico: DNS, DHCP, NTP, base de datos, Nagios, certificados ... Lo mismo que en su día documenté en el Rasp Project, guía a guía, comando a comando.

Ahora es un asistente. Respondes un formulario, observas el log y pasa al siguiente paso. Si algo explota (y explotará), lo vuelves a lanzar y continúa donde lo dejó. Y si quieres otro servidor igual, le das el fichero de respuestas y se instala solo.

consejo

Nagios se compila desde el código fuente. Conductor te avisa antes de empezar de que puede tardar y fallar. Es el aviso más sincero que he escrito nunca 😃.

Sora Horizon​

Y aquí está la pieza que faltaba. Horizon es el sitio donde vive todo: las redes, las IPs, los nombres DNS, los servidores, las carpetas compartidas, los dispositivos, las credenciales y, sobre todo, los stacks.

Un stack es una aplicación desplegada a partir de una plantilla: eliges la plantilla, rellenas el formulario y despliegas. Horizon crea las máquinas, ejecuta los scripts por fases, publica los nombres en Pi-hole, los checks en Nagios y los targets en Prometheus. Y cuando lo eliminas, lo deshace todo.

¿Recordáis que Pi-hole no tenía API y que perdí un año intentando piratearlo? Pues la versión nueva sí la tiene, y Horizon la usa. Crear un nombre en Horizon es lo que hace que una VM reciba su IP por DHCP y resuelva por DNS. Sin tocar Pi-hole. Jamás. 🥹

información

Un año después, la espera dio sus frutos. A veces la mejor decisión es no hacer nada y seguir adelante.

Las plantillas​

Antes, cada máquina era un único Terraform que lo hacía todo con cloud-init. El problema: cambiar algo de su configuración no llegaba nunca a la máquina, ya que cloud-init solo se ejecuta al crearla. La única forma de aplicar un cambio era destruirla y volverla a crear. 🔥

Ahora las aplicaciones se despliegan por fases: la máquina primero (siempre el mismo servidor Ubuntu base), y después los scripts que la convierten en lo que debe ser. Cambiar un ajuste es editar el stack, y solo se vuelve a ejecutar la parte afectada.

Las plantillas actuales despliegan PostgreSQL, la monitorización, Kubernetes y GitLab Runner.

Kubernetes sin estado​

Tras la guerra con Longhorn y CNPG, he tomado una decisión radical: el clúster no tiene volúmenes. Ninguno. Se rechaza cualquier intento de crear uno.

  • Las bases de datos viven en un PostgreSQL externo, con PgBouncer delante y copias de seguridad cada noche.
  • La monitorización vive en su propia máquina: Prometheus, Loki, Tempo y Grafana. El clúster le envía sus métricas, logs y trazas.
  • Todo lo demás está en Git.

Si el clúster muere, se despliega uno nuevo y FluxCD lo vuelve a llenar. Sin restaurar nada. Sin llorar. Bueno, sin llorar mucho.

aviso

Loki sigue siendo Loki. Pero ahora, cuando se enfada, se enfada en su propia máquina y no se lleva el clúster por delante 😌.

Los nodos tampoco se actualizan: se sustituyen. Añadir un worker es añadir una línea en el formulario de Horizon; sustituir el control plane es quitar uno y añadir otro en el mismo guardado. El nuevo se une primero, el antiguo se va después, y el endpoint de la API ni se entera.

FluxCD​

FluxCD también ha pasado por el quirófano. Ahora lo instala el Flux Operator, sin token y sin escribir en el repositorio: el clúster lee Git y Git ni sabe que el clúster existe.

La organización por niveles se mantiene, pero más limpia: red, ingress, observabilidad, identidad y aplicaciones. Y con reglas que el propio Kubernetes aplica: sin volúmenes, todo ingress con su clase, pods sin privilegios y rollback automático si una actualización falla.

¿Y lo de las actualizaciones que explotaban? Cada componente se actualiza solo dentro de un rango: los parches llegan solos, las versiones menores de lo que puede tumbar el clúster requieren un commit. Slack avisa de todo.

¿Y ahora?​

Ahora toca usarlo. La documentación completa está en Sora Project, con una guía de despliegue desde un Proxmox vacío hasta las aplicaciones.

La red queda totalmente funcional con la arquitectura básica. Lo suficientemente básica como para ser el sueño húmedo de muchas empresas o, peor, el que ni siquiera saben que existe.

Por fin, a despegar. ☁️