> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Operación de Streaming Hub

> Despliega Streaming Hub con Helm en BYOC, ejecuta migraciones fuera de banda, conecta las sondas de liveness y readiness, establece la configuración esencial y observa el hub a través de OTLP.

Esta página es para operadores que ejecutan Streaming Hub en su propia infraestructura (BYOC). Cubre el despliegue, la configuración que importa, el contrato de salud y apagado, y cómo observar el servicio.

## Desplegar con Helm

***

Streaming Hub se distribuye como un chart de Helm dedicado, `streaming-hub-helm`, separado de cualquier otro chart de producto de Lerian. El chart ejecuta el hub en una de dos formas:

* **`all`** — un único deployment que ejecuta todos los workers de segundo plano. Este es el valor por defecto y el más simple de operar.
* **`split`** — deployments **ingest** y **delivery** separados que escalan de forma independiente: las réplicas de ingest comparten un único grupo de consumidores de Kafka, mientras que las réplicas de delivery procesan los trabajos de entrega desde Postgres.

La forma split se controla por proceso con `STREAMING_HUB_ROLE` (`all` | `ingest` | `delivery`). El rol controla **qué workers de segundo plano se ejecutan y qué clientes de Kafka marcan**; **no** controla qué rutas HTTP se montan. Cada rol sirve la API del plano de control completa y, sobre todo, el endpoint `/readyz` del que dependen tu orquestador y el scrape de métricas. Hay una sola imagen y un solo binario; el rol es una entrada de despliegue, no de compilación.

## Ejecutar migraciones de base de datos

***

Streaming Hub está respaldado por una única base de datos PostgreSQL propiedad del hub, y **nunca se migra a sí mismo**. Las migraciones de esquema se ejecutan **fuera de banda** —como un paso de migración separado (por ejemplo, un hook PreSync de ArgoCD) que aplica las migraciones versionadas antes de que el hub arranque. En el arranque, el hub solo *verifica* que la versión de esquema que espera está presente; nunca ejecuta una migración como efecto secundario del arranque.

El hub sí aprovisiona con antelación sus propias particiones de tabla semanales como una tarea rutinaria de segundo plano; eso es mantenimiento interno, no una migración de esquema, y no requiere ninguna acción del operador más allá de dejar el cron de particiones en ejecución.

## Salud y apagado ordenado

***

Streaming Hub expone dos endpoints de sonda distintos. Conecta cada uno a la sonda de Kubernetes correspondiente:

| Endpoint   | Sonda     | Comportamiento                                                                                                                                                                                                       |
| ---------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/healthz` | Liveness  | Devuelve `200` incondicionalmente una vez que el proceso está sirviendo, independiente de la salud de Postgres, Kafka o el roster. Una liveness que falla reinicia el pod, así que no debe depender de dependencias. |
| `/readyz`  | Readiness | Reúne el conjunto completo de sondas del rol. `Healthy` o `Degraded` → `200` (se mantiene en rotación); `Down` → `503` (se saca de rotación). Una réplica `Degraded` sigue sirviendo.                                |

`/readyz` distingue dos clases de fallo. Un fallo de **sonda de runtime** —Postgres inalcanzable, consumidor muerto— lleva la réplica a **Down** y fuera de rotación. Un **degradador** —latencia elevada, lag del consumidor, un buffer de particiones escaso— fija la réplica en **Degraded** pero la mantiene sirviendo, porque una réplica deteriorada no debería rechazar tráfico. El conjunto de sondas tiene en cuenta el rol: un pod con rol delivery no se marca como no listo por no tener un consumidor de ingest.

Ante `SIGTERM`, el hub drena de forma ordenada. Cambia `/readyz` a `NotReady` **primero** —antes de dejar de servir— y espera una ventana pre-stop acotada para que el orquestador pueda sacar el pod del servicio antes de que se corten las conexiones. `/healthz` permanece en `200` durante todo el proceso, así que el pod no se mata a mitad del drenaje. Luego desmonta en un orden seguro respecto a las dependencias (HTTP, luego el consumidor, luego el dispatcher, luego las apps de segundo plano, luego los clientes de Kafka, luego el pool y luego la telemetría).

<Warning>
  Establece el `terminationGracePeriodSeconds` del deployment en el techo de drenaje derivado del hub para tu `STREAMING_HUB_SHUTDOWN_TIMEOUT`, o por encima, no en un número mágico fijo. Con el timeout de apagado por defecto de 30 segundos, el techo es de unos **80 segundos**: la ventana pre-stop de 5 segundos, más el propio timeout de apagado, más un tramo de drenaje del dispatcher en el peor caso de `min(timeout, 55s)`, más un margen fijo de desmontaje para los componentes restantes. Un periodo de gracia por debajo del techo arriesga un `SIGKILL` de una réplica que aún está drenando —seguro para la correctitud (los trabajos en vuelo se reclaman y se reenvían, deduplicados en el consumidor), pero se pierde el drenaje limpio.
</Warning>

`/version` (identidad de compilación) y `/runtime` (una instantánea barata del runtime de Go) completan la superficie operativa no autenticada para el triaje de incidentes.

## Configuración esencial

***

Streaming Hub lee su configuración de variables de entorno `STREAMING_HUB_*` (más unas cuantas variables compartidas `PLUGIN_AUTH_*` y `OTEL_*`). El inventario completo, con cada valor por defecto, está en la referencia de entorno del servicio. Las variables que estableces con más frecuencia:

| Variable                               | Valor por defecto                    | Propósito                                                                                                                                                                                     |
| -------------------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STREAMING_HUB_ENV`                    | `local`                              | Entorno de despliegue (`local` \| `staging` \| `production`). Impulsa la puerta de seguridad de producción que rechaza los flags de bypass de desarrollo.                                     |
| `STREAMING_HUB_ROLE`                   | `all`                                | Porción desplegable: `all` \| `ingest` \| `delivery`. Controla los workers y los clientes de Kafka, nunca las rutas.                                                                          |
| `STREAMING_HUB_HTTP_LISTEN_ADDR`       | `:8080`                              | La única dirección de bind del plano de control.                                                                                                                                              |
| `STREAMING_HUB_POSTGRES_DSN`           | *(requerido)*                        | El DSN de PostgreSQL propiedad del hub. El arranque falla si está vacío.                                                                                                                      |
| `STREAMING_HUB_KAFKA_BROKERS`          | *(vacío)*                            | Lista de brokers de bootstrap para el flujo interno.                                                                                                                                          |
| `STREAMING_HUB_TENANT_ID`              | `default`                            | El id de tenant de BYOC. Consulta la advertencia de abajo antes de cambiarlo.                                                                                                                 |
| `STREAMING_HUB_KEK_SOURCE`             | `env`                                | Proveedor de la clave de cifrado de claves (KEK) (`env` \| `secretsmanager`).                                                                                                                 |
| `STREAMING_HUB_KEK_REF`                | *(vacío)*                            | El **nombre** de la variable de entorno que contiene el material de la KEK, nunca el material en sí.                                                                                          |
| `STREAMING_HUB_MANIFEST_SOURCES`       | *(vacío)*                            | URLs base de manifiestos de productor a partir de los que se construye el catálogo de eventos.                                                                                                |
| `PLUGIN_AUTH_ADDRESS`                  | *(valor por defecto de plugin-auth)* | La URL base del punto de decisión de plugin-auth para la autorización del plano de control.                                                                                                   |
| `PLUGIN_AUTH_ENABLED`                  | `true`                               | Interruptor maestro de autenticación. `false` es un bypass local, **rechazado en producción**.                                                                                                |
| `STREAMING_HUB_AUTODISABLE_ENABLED`    | `true`                               | Kill switch para la auto-desactivación de destinos rotos.                                                                                                                                     |
| `STREAMING_HUB_SHUTDOWN_TIMEOUT`       | `30s`                                | Ventana de drenaje ordenado. La ventana pre-stop más `min(valor, 55s)` debe permanecer estrictamente por debajo del lease del dispatcher de 60 segundos, o el arranque falla en modo cerrado. |
| `STREAMING_HUB_MULTI_TENANT_ENABLED`   | `false`                              | `false` es BYOC de un solo tenant; `true` conecta el roster SaaS multi-tenant.                                                                                                                |
| `STREAMING_HUB_AWS_HUB_PRINCIPAL_ARN`  | *(vacío)*                            | El principal IAM público del hub incrustado en los artefactos de configuración de AWS. Requerido para los sinks de AWS.                                                                       |
| `STREAMING_HUB_AWS_SETUP_TEMPLATE_URL` | *(vacío)*                            | La URL pública de la plantilla de CloudFormation para el enlace de creación rápida de AWS.                                                                                                    |
| `OTEL_EXPORTER_OTLP_ENDPOINT`          | *(vacío)*                            | El endpoint del colector OTLP al que se exporta la telemetría (sin prefijo `STREAMING_HUB_`).                                                                                                 |

Los **valores** de los secretos nunca pertenecen a estas variables en producción. La KEK se referencia por el *nombre* de la variable de entorno en la que la capa de despliegue la inyecta (`STREAMING_HUB_KEK_REF`); el hub lee el material de esa variable nombrada y nunca lo registra en logs. Las credenciales de SASL, de CA de TLS y del tenant manager siguen la misma regla: la variable contiene el valor en tiempo de ejecución, pero el valor proviene de tu almacén de secretos, no de un archivo de configuración versionado.

<Warning>
  **`STREAMING_HUB_TENANT_ID` es una trampa de cero entregas en BYOC.** El hub solo acepta eventos cuyo `ce-tenantid` coincida exactamente con este valor; todos los demás eventos se descartan en silencio (`unknown_or_inactive_tenant`), avanzando el offset sin fila poison. Si lo estableces en cualquier valor distinto de `default`, **debes** confirmar que el productor emite ese mismo `ce-tenantid`; de lo contrario, el hub descarta el 100% del flujo y no entrega nada, sin ningún error. Un valor distinto del predeterminado emite una advertencia de arranque; hazle caso.
</Warning>

## Análisis forense de la DLQ

***

`GET /admin/dlq` es la superficie forense del operador para las observaciones de dead-letter. Es **cross-tenant por diseño**: está protegida por el scope de admin de lib-auth, **no** lleva shim de tenant y devuelve registros de todos los tenants, así que no forma parte de la API `/v1` orientada al cliente. Las observaciones de dead-letter que lee son **solo de observabilidad**: se capturan de los tópicos de dead-letter de los productores upstream y el hub nunca las reenvía. Úsala para investigar por qué fallaron los registros upstream; no los reproduce.

## Reconciliador de tópicos

***

El reconciliador de tópicos es un detector de drift de **solo lectura**, habilitado por defecto (`STREAMING_HUB_RECONCILER_ENABLED`). En cada pasada compara los tópicos vivos del broker, el catálogo de eventos y los destinos de suscripción distintos, y señala tres tipos de drift: **tópicos fantasma** (un tópico seguido sin entrada en el catálogo), **suscripciones muertas** (un tipo de evento y major suscrito sin entrada viva en el catálogo) e infracciones de **lag frente a retención**.

**Detecta, nunca corrige**: emite gauges de solo recuento y logs estructurados, y no escribe ningún estado del broker ni de la base de datos. Cuando está deshabilitado, no crea ninguna goroutine ni marca ningún cliente de admin, así que el camino deshabilitado no cuesta nada; deshabilitarlo pierde una alarma operativa pero nunca afecta la entrega.

## Observabilidad

***

Streaming Hub exporta sus métricas, trazas y logs a través de **OTLP** (lib-observability), apuntando al colector en `OTEL_EXPORTER_OTLP_ENDPOINT`. Ahí es donde viven las métricas `streaming_hub_*` reales.

<Note>
  El endpoint `/metrics` está **casi vacío por diseño**: sirve solo el gauge estático `streaming_hub_build_info`. Haz scrape de las métricas reales del hub desde tu colector OTLP, no desde `/metrics`.
</Note>

La identidad del tenant nunca es una etiqueta de métrica —vive en los atributos de span y en los campos de log—, así que la cardinalidad de las métricas se mantiene acotada sin importar cuántos tenants sirva un despliegue.

## Próximos pasos

***

<CardGroup cols={2}>
  <Card title="Cómo funciona Streaming Hub" icon="diagram-project" href="/es/streaming-hub/how-streaming-hub-works">
    Los detalles internos de entrega detrás de las superficies operativas de arriba.
  </Card>

  <Card title="Gestión de suscripciones" icon="gear" href="/es/streaming-hub/managing-subscriptions">
    Las operaciones del plano de control que usan tus tenants.
  </Card>
</CardGroup>
