Files
..
2025-08-20 01:16:53 +02:00
2025-08-20 01:16:53 +02:00
2025-08-18 10:31:22 +02:00
2025-08-18 10:31:22 +02:00
2025-08-20 01:16:53 +02:00
2025-08-31 08:42:35 +02:00
2025-08-20 01:16:53 +02:00
2025-08-18 10:31:22 +02:00
2025-08-20 01:16:53 +02:00

Argos Core

Argos Core es el backend central de una plataforma de videovigilancia distribuida. Está diseñado para recibir eventos desde edges (sitios remotos con Frigate), capturar/ingestar vídeo bajo demanda, almacenarlo de forma fiable y ofrecer un panel web seguro para consulta y reproducción, todo encapsulado en Kubernetes y oculto tras una VPN WireGuard.


Visión general

[Edge / Frigate] --(VPN/WG + MQTT eventos)--> [Argos Core]
                                           ├─ Mosquitto (MQTT)
                                           ├─ Orchestrator (ingesta clips)
                                           │    ├─ Pull clip nativo de Frigate
                                           │    └─ Fallback: captura RTSP temporal
                                           ├─ MediaMTX (live/retransmisión)
                                           ├─ MinIO (S3, almacenamiento)
                                           └─ Panel (FastAPI + Uvicorn)

Objetivo clave: los edges no envían flujo constante; sólo cuando hay evento. El core ingesta y guarda el clip, y ofrece visualización ondemand.


Componentes

  • WireGuard (wg-easy): servidor VPN del clúster. Todo el tráfico de edges → core circula por WG.

  • Mosquitto (eclipse-mosquitto:2): broker MQTT interno (ClusterIP). Topic de eventos (p. ej. frigate/events).

  • Orchestrator (Python):

    • Se suscribe a MQTT.
    • Tras un evento, intenta descargar el clip nativo desde la API del Frigate del edge.
    • Si no existe, hace captura RTSP temporal con ffmpeg (duración configurada) contra la cámara/edge.
    • Sube el resultado a MinIO (s3://argos/...) y registra metadatos en SQLite embebido.
  • MinIO (S3 compatible): almacenamiento de clips y miniaturas.

  • MediaMTX: redistribución de flujos (RTSP/WHIP/SRT) y posible live view on-demand.

  • Panel (FastAPI/Uvicorn):

    • Lista eventos desde MinIO (sin exponer MinIO: proxy de objetos).
    • Página de reproducción (/view?key=…).
    • Endpoints simples (/file, /api/events, /health).
  • CoreDNS: DNS interno con split-horizon (resolución diferente desde LAN/VPN/cluster cuando aplica).

  • Ingress NGINX (interno/externo) + certmanager: TLS para el panel; HTTP01 servido por el controlador externo.

  • MetalLB: IPs para servicios tipo LoadBalancer en la red 192.168.200.0/24 (p. ej. MediaMTX).


Flujo de datos (evento → clip)

  1. Edge detecta (Frigate) y publica en MQTT frigate/events.
  2. Orchestrator recibe el evento, localiza la cámara/edge en su settings.yaml.
  3. Intenta pull del clip nativo vía API Frigate del edge (VPN).
  4. Si no hay clip, ejecuta ffmpeg para capturar RTSP temporal (fallback).
  5. Sube el fichero a MinIO con una clave tipo: camX/YYYY/MM/DD/TS_eventId.mp4 y optional thumb.
  6. Panel lo muestra en la lista y permite reproducir vía /file?key=… (stream proxy desde MinIO).

Para live, MediaMTX publica / con path=<cam>; puedes incrustar un reproductor WebRTC/RTSP en el panel.


Despliegue

Requisitos previos

  • Kubernetes operativo con:

    • MetalLB (rango 192.168.200.0/24).
    • NGINX Ingress interno y externo (split-horizon DNS).
    • certmanager + ClusterIssuer (p. ej. letsencrypt-prod).
    • wg-easy funcionando (con NAT/iptables para alcanzar 200.x, 0.x, etc.).

Estructura

argos/
├─ configmaps/   # mediamtx, mosquitto, orchestrator, panel
├─ deployments/  # mediamtx, minio, mosquitto, orchestrator, panel
├─ ingress/      # minio (opcional), panel (TLS)
├─ policies/     # network-policy, allow-same-namespace
├─ pvc/          # pvc-minio
├─ secrets/      # minio, orchestrator, panel
└─ services/     # mediamtx tcp/udp, minio, mosquitto, panel

Variables/Secrets esperados

  • MinIO (secrets/secret-minio.yaml): MINIO_ACCESS_KEY, MINIO_SECRET_KEY.
  • Orchestrator (secrets/secret-orchestrator.yaml): MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, MINIO_SECURE.
  • Panel (secrets/secret-panel.yaml): MINIO_* y MINIO_BUCKET.

Servicios y puertos

  • MinIO: ClusterIP :9000 (API), :9001 (console, opcional). No expuesto fuera.
  • Mosquitto: ClusterIP :1883.
  • MediaMTX: LoadBalancer (MetalLB) en 192.168.200.16 (RTSP 8554 TCP, WHIP 8889 TCP/HTTP 8880, SRT 8189 UDP).
  • Panel: ClusterIP :8000 → Ingress (TLS) https://argos.panel.c2et.net/ (ajusta FQDN).

Kustomize

kubectl apply -k .

Nota: evitamos commonLabels globales para no romper los selectors.


Configuración relevante

Orchestrator (configmaps/configmap-orchestrator.yaml)

  • mqtt.host: mosquitto.argos-core.svc.cluster.local
  • mqtt.port: 1883
  • mqtt.topic: frigate/events
  • minio.endpoint: minio.argos-core.svc.cluster.local:9000
  • edges: lista de edges y cámaras (URLs de Frigate, RTSP principal, etc.).

Mosquitto (configmaps/configmap-mosquitto.yaml)

  • Config mínimo:

    persistence true
    persistence_location /mosquitto/data/
    listener 1883 0.0.0.0
    allow_anonymous true  # RECOMENDACIÓN: pasar a autenticación/TLS más adelante
    

MediaMTX

  • Ejecutar sin /bin/sh -c … y pasando solo la ruta del YAML como args.
  • Corrige warnings como sourceOnDemand según el modo (publisher o record).

MinIO (seguridad/permisos)

  • Ejecuta como no-root con runAsUser: 1000 y un initContainer que hace chown/chmod/ACL del PVC.
  • Estrategia de despliegue Recreate para evitar doble pod en updates cuando la readinessProbe tarda.

Ingress + cert-manager

  • El Certificate del panel debe forzar el solver HTTP01 por el ingress externo:

    • Anotación: acme.cert-manager.io/http01-ingress-class: nginx-external (o ajusta en ClusterIssuer).

Operación

Comandos útiles

# Estado general
kubectl -n argos-core get pods,svc,ingress,endpoints

# Endpoints vacíos (<none>)
kubectl -n argos-core get endpoints <svc> -o wide
# Revisa selector del Service y labels del Pod

# Logs
kubectl -n argos-core logs -f deploy/<nombre>

# Reinicios controlados
kubectl -n argos-core rollout restart deploy/<nombre>

# Diff del Service en vivo vs manifiesto
kubectl -n argos-core get svc argos-panel -o yaml --show-managed-fields=false

Problemas típicos y fixes

  • Service con ENDPOINTS <none>: selector ≠ labels, o pod not Ready (probe fallando). Ajusta selector a {app: …} y corrige readiness.
  • Dos pods tras update: rolling update atascado. Usa strategy: Recreate mientras estabilizas.
  • MinIO file access denied: permisos del PVC. Añade initContainer que hace chown -R 1000:1000 /data + ACL.
  • Mosquitto Connection refused desde Orchestrator: Service sin endpoints o broker no escucha en 1883. Ver logs mosquitto y ss -lnt.
  • Panel ASGI app not found: uvicorn app:app --app-dir /app y asegúrate de montar app.py con app = FastAPI().
  • MediaMTX unknown flag -c: no usar /bin/sh -c …; pasar args: ["/config/mediamtx.yml"].

Edge (resumen de mañana)

  • WireGuard cliente (IP del edge en la VPN; DNS apuntando al core).
  • Frigate en Docker + mqtt.host=mosquitto.argos-core.svc.cluster.local.
  • API de Frigate accesible desde el core por la VPN (p. ej. http://10.20.0.10:5000).
  • Opcional: MediaMTX local si se quiere “empujar” live al core durante la alarma.

Seguridad y siguientes pasos

  • Endurecer Mosquitto (usuarios/TLS), MinIO (políticas/buckets versionados), y el Panel (auth detrás de Ingress o login propio).
  • Métricas y dashboards (Prometheus/Grafana), y mover metadatos a PostgreSQL para búsquedas ricas.
  • Live WebRTC integrado en el panel (MediaMTX WHIP/WHEP).

Licencia / Créditos

  • MediaMTX (Bluenviron), MinIO, Eclipse Mosquitto, Frigate (en los edges).
  • Argos Core: composición y orquestación Kubernetes + servicios auxiliares.