Skip to content
← Todas las publicaciones
· Delta1 Labs KeyrightAutoalojamientoAlta disponibilidadOperaciones

Ejecutar Keyright autoalojado en varios nodos para alta disponibilidad

Tu servidor de licencias está en la ruta de activación de tus clientes, así que no debería ser un punto único de fallo. Keyright autoalojado es un servicio ASP.NET Core sin estado —todo el estado vive en tu PostgreSQL— por lo que la alta disponibilidad es solo ejecutar dos o tres réplicas tras un balanceador de carga sin afinidad de sesión. Aquí tienes exactamente cómo.

Un servidor de licencias tiene un trabajo poco vistoso pero implacable: está en la ruta de activación de tus clientes y, cuando es inalcanzable en el momento equivocado, alguien no puede arrancar el software que pagó. Un buen diseño de cliente suaviza esto con la gracia sin conexión —un lease en caché cubre una caída breve— pero “breve” hace mucho trabajo en esa frase. Si tu único nodo de licencias está caído durante una tarde de parcheo, o su VM se está migrando, o simplemente se vino abajo, dependes de que la ventana de gracia de cada cliente sea más larga que tu caída. Eso no es un plan. La alta disponibilidad sí lo es.

La buena noticia es que hacer Keyright autoalojado de alta disponibilidad resulta casi anticlimático, porque la app se construyó para ello. Este artículo recorre exactamente por qué, y cómo levantar un despliegue de dos o tres nodos.

Conclusión clave: Keyright autoalojado es un servicio ASP.NET Core sin estado —todo el estado vive en tu PostgreSQL— así que la alta disponibilidad es solo ejecutar dos o tres réplicas tras un balanceador de carga sin afinidad de sesión. Lo que de verdad hay que hacer de alta disponibilidad es Postgres. La HA multinodo es un despliegue Pro o Enterprise (ambos cubren hasta tres nodos de producción); Standard cubre un único nodo.

Por qué un servidor de licencias necesita HA de entrada

Piensa en dónde se sitúa realmente el servicio. Cada activación nueva, cada reclamación de puesto, cada revalidación en línea de un lease pasa por él. Para la mayoría de tus clientes ese tráfico es intermitente e invisible, hasta el momento en que no lo es, porque alguien está incorporando una máquina nueva o un lease ha expirado y el cliente lo está renovando. Si el servidor está caído entonces, esa persona concreta está bloqueada, y estar-bloqueado-en-la-activación es el peor momento posible para estarlo. Se convierte en un ticket de soporte en minutos.

Ya mitigas el caso común con la validación sin conexión entre activaciones y las ventanas de gracia ante caídas. La HA es la otra mitad: en lugar de confiar en que una caída se mantenga dentro de la gracia de todos, eliminas el punto único de fallo para que no haya caída que graciar. Dos nodos significan que uno puede morir, parchearse o reprogramarse mientras el otro sigue respondiendo.

La arquitectura que lo hace fácil

Keyright autoalojado tiene exactamente dos partes móviles: una app sin estado y tu base de datos.

La app es la imagen ghcr.io/delta1-labs/keyright —un servicio ASP.NET Core escuchando en el puerto 8080. La imagen es solo app: no hay base de datos dentro de ella. No guarda estado entre peticiones. Licencias, activaciones, puestos, créditos, el registro de auditoría, las claves de firma —todo ello vive en PostgreSQL, al que apuntas la app con la cadena de conexión KEYRIGHT_DB. La app crea y migra su propio esquema en el primer arranque, así que no hay SQL que ejecutar a mano.

Esa única decisión de diseño —app sin estado, todo el estado en tu base de datos— es lo que hace trivial la HA. Como nada está anclado a un proceso concreto, puedes ejecutar tantas copias de la app como quieras, y cualquier copia puede responder cualquier petición. No hay sesión en memoria, ni caché local de nodo con la verdad, ni nada que perder cuando un nodo desaparece. Escalar la app hacia fuera es solo ejecutar el mismo contenedor más de una vez.

Ejecutar varias réplicas

Si usas Docker Compose, escalar la capa de app es un flag:

docker compose up -d --scale keyright=3

Eso te da tres contenedores de app idénticos, todos leyendo el mismo KEYRIGHT_DB y todos con la misma configuración. Pon un balanceador de carga delante (más abajo) y tienes un despliegue de tres nodos.

En Kubernetes con el chart de Helm, es un valor:

# values.yaml
replicaCount: 3
helm upgrade --install keyright delta1/keyright -f values.yaml

Kubernetes programa tres pods, el Service reparte la carga entre ellos y, como los pods no tienen estado, puedes añadirlos o drenarlos libremente. Repártelos entre nodos o zonas de disponibilidad con anti-afinidad de pods si quieres sobrevivir a la pérdida de una máquina o zona entera.

Una cosa permanece idéntica en todas las réplicas: la clave de autolicencia. Keyright es fail-closed —necesita una clave de autolicencia (o de prueba) válida para servir tráfico siquiera— y cada nodo se ejecuta con la misma clave. No hay registro por nodo ni un apretón de manos de recuento de nodos; una renovación o un cambio de edición es solo cambiar la clave en tu configuración y reiniciar los nodos. Desplegar la clave es un cambio de configuración, no una danza de licenciamiento.

El balanceador de carga y las sondas de salud

Pon cualquier balanceador de carga HTTP delante de los nodos de app —el balanceador L7 de tu nube, un controlador de ingress, nginx, HAProxy, lo que ya ejecutes. Dos cosas que acertar:

Sin afinidad de sesión. No actives sesiones persistentes. Como la app no tiene estado y los clientes validan sin conexión entre activaciones, no hay nada atado a un nodo que la afinidad deba preservar. Envía cualquier petición a cualquier nodo. Activar la afinidad solo concentra la carga y echa por tierra el propósito. La concurrencia entre nodos es segura sin ella: los puestos y los créditos usan una comprobación-y-descuento serializable en Postgres, así que dos nodos físicamente no pueden gastar por duplicado el mismo puesto ni el mismo saldo.

Sondas de salud. Keyright expone dos endpoints precisamente para esto:

  • GET /health — liveness. Un 200 estático que nunca saca un nodo del grupo por un parpadeo transitorio de la base de datos. Úsalo para decidir si el proceso está vivo.
  • GET /health/ready — readiness. Este también comprueba la conectividad con la base de datos y devuelve 503 cuando Postgres es inalcanzable. Úsalo para decidir si un nodo debe recibir tráfico.

Una sonda típica de balanceador:

health check: GET /health/ready   interval 10s   healthy 2   unhealthy 3

Termina TLS en el balanceador y reenvía X-Forwarded-For (la IP real del cliente) y X-Forwarded-Proto (para que el panel y el portal generen URLs https) —la app honra ambas. Expón públicamente solo el :443 a través del balanceador; mantén /admin/* e /internal/* alcanzables solo desde dentro de tu red. Tus clientes solo necesitan la ruta /v1/*.

PostgreSQL es el verdadero cuello de botella

Aquí está la parte que la gente invierte. Escalar la app es casi gratis, así que no es ahí donde debe ir tu atención. Lo que tiene que ser fiable —y lo que de verdad limita hasta dónde escalas— es PostgreSQL, porque ahí vive cada byte de estado.

Así que invierte ahí. Para cualquier cosa más allá de la evaluación, no ejecutes la base de datos incluida que ofrecen los kits por comodidad; apunta KEYRIGHT_DB a un Postgres gestionado o de alta disponibilidad —un primario con una réplica, conmutación por error automática y copias de seguridad reales. Una app sin estado delante de una única base de datos frágil no es de alta disponibilidad; solo has bajado el punto único de fallo una capa. Haz de la base de datos el componente de HA y la capa de app la sigue gratis. A muy gran escala (hacia los millones de licencias activas) añade PgBouncer para el pooling de conexiones y da a Postgres más núcleos —la guía de escalado en la documentación de operaciones tiene dimensionamiento concreto por nivel.

La razón por la que la app puede permitirse ser tan ligera es la forma de la carga de trabajo. La ruta caliente —/v1/activate y /v1/validate— es una comprobación de firma más un recuento de puestos, y los clientes cachean un lease firmado y validan sin conexión entre activaciones. No recibes una petición HTTP en cada arranque de la app; recibes una en la activación y luego periódicamente cuando un lease se renueva. Esa es una carga pequeña, intermitente y ligera en CPU, que es exactamente por qué dos o tres nodos modestos cubren con holgura un despliegue con cientos de miles de licencias activas.

Un extra gratis: actualizaciones sin tiempo de inactividad

Una vez que ejecutas 2+ nodos, las actualizaciones dejan de ser una caída. Como la app es compatible hacia atrás dentro de una línea menor y las migraciones se aplican automáticamente al arrancar, puedes renovar un nodo cada vez: dréndalo, baja la imagen nueva, deja que vuelva y quede ready, y pasa al siguiente. El balanceador sigue sirviendo desde los nodos sanos todo el rato. La misma propiedad que te da HA frente al fallo te da HA frente al mantenimiento —que, en la práctica, es la caída que de verdad programas más a menudo.

Qué edición necesitas

Keyright autoalojado se licencia por despliegue, y las ediciones se diferencian en el número de nodos:

  • Standard cubre un único nodo de producción —válido para un despliegue sencillo, pero por definición no de alta disponibilidad.
  • Pro y Enterprise cubren ambos hasta tres nodos de producción —que es lo que requiere la HA multinodo.

Standard y Pro ejecutan el mismísimo motor de funciones; el número de nodos es lo único que los separa, así que “quiero HA” es simplemente una razón para estar en Pro en lugar de Standard. Enterprise añade SSO, marca de etiqueta blanca y bloques de crédito aislados (air-gapped) sobre la misma asignación de tres nodos. El número de nodos es un término contractual —el software no cuenta ni impone nodos, y la misma clave de autolicencia se ejecuta en todas las réplicas. Consulta los precios para las cifras actuales.

Dónde encaja Keyright

Como Keyright es un solo producto en ambos modos de despliegue, la arquitectura de app-sin-estado-más-tu-base-de-datos es la misma tanto si evalúas en un portátil como si ejecutas tres nodos en producción —nada de tu integración cambia a medida que escalas hacia fuera. Si aún estás decidiendo si autoalojar siquiera, las disyuntivas entre autoalojado y nube exponen la decisión, y si te estás moviendo desde un sistema casero, migrar sin romper a los clientes es el manual. Cuando estés listo para levantar la HA, la guía de operaciones tiene el detalle de copias de seguridad, actualizaciones y dimensionamiento que convierte dos nodos en marcha en un despliegue de producción tras el que puedas dormir tranquilo.

Prueba Nebula.NET

Endurece tu código .NET en minutos — empieza con la edición gratuita.