openova/platform/stunner
hatiyildiz bc9b90d989 docs(pass-35): completion sweep for surviving DNS placeholders (8 components)
Started as gitea + relay atomic check. The gitea fix surfaced surviving
<domain> placeholders across 8 other component READMEs that prior sweeps
(Pass 29: canonical docs, Pass 32: image registries) hadn't covered.

Catalyst control-plane DNS fixes (-> {component}.<location-code>.<sovereign-domain>):
- gitea: GITEA_INSTANCE_URL.
- external-secrets: openbao ClusterSecretStore + gitea Flux GitRepository.

Application DNS fixes (-> {app}.<env>.<sovereign-domain>):
- temporal: had two drift items in one line — temporal.fuse.<domain>
  (old "fuse" product name + wrong placeholder shape). Pass 32 fixed
  the image ref on the same file but missed this. Now fully de-drifted.
- valkey: --replicaof valkey.region1.<domain> (non-canonical region1
  segment — Catalyst encodes regions in location-code).
- strimzi: kafka-kafka-bootstrap.region1.<domain>:9092 — same.
- cnpg: postgres.region1.<domain> cross-region replica host — same.
- stunner: STUN/TURN realm — kept canonical Application form for
  consistency even though STUN realms are nominally opaque.
- k8gb: Gslb ingress host app.gslb.<domain> -> app.gslb.<sovereign-domain>.
  Other illustrative k8gb refs (dnsZone, nslookup examples) preserved
  as they describe behavior generically.

products/relay/README.md: clean.

Preserved as correctly-generic: external-dns illustrative refs,
cert-manager <domain> (customer-supplied cert names), stalwart <domain>
(customer email-receiving domain).

Validation log Pass 35 entry: third end-to-end DNS sweep iteration
(29 -> 32 -> 35). Future passes should grep for bare <domain> early to
catch new instances introduced during edits.
2026-04-27 22:46:16 +02:00
..
README.md docs(pass-35): completion sweep for surviving DNS placeholders (8 components) 2026-04-27 22:46:16 +02:00

STUNner

K8s-native TURN/STUN for WebRTC NAT traversal. Application Blueprint (see docs/PLATFORM-TECH-STACK.md §4.5 — Communication). Used by bp-relay to make LiveKit (WebRTC SFU) reachable from clients behind NATs.

Status: Accepted | Updated: 2026-04-27


Overview

STUNner provides WebRTC connectivity:

  • Kubernetes-native STUN/TURN server
  • Gateway API integration
  • Scalable media relay
  • NAT traversal for video/audio

Architecture

flowchart TB
    subgraph External["External"]
        Client[WebRTC Client]
    end

    subgraph K8s["Kubernetes"]
        subgraph STUNner["STUNner"]
            GW[Gateway]
            TURN[TURN Servers]
        end

        subgraph Apps["Applications"]
            SFU[Media Server/SFU]
        end
    end

    Client -->|"STUN/TURN"| GW
    GW --> TURN
    TURN --> SFU
    Client -->|"Media"| TURN
    TURN -->|"Media"| SFU

Why STUNner

Factor STUNner Traditional TURN
Deployment Kubernetes-native Separate VMs
Scaling HPA/KEDA Manual
Configuration Gateway API CRDs Config files
Integration Native K8s External

Configuration

Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: stunner-gateway
  namespace: stunner
spec:
  gatewayClassName: stunner-gatewayclass
  listeners:
    - name: udp-listener
      port: 3478
      protocol: TURN-UDP
    - name: tcp-listener
      port: 3478
      protocol: TURN-TCP

UDPRoute

apiVersion: stunner.l7mp.io/v1
kind: UDPRoute
metadata:
  name: media-route
  namespace: stunner
spec:
  parentRefs:
    - name: stunner-gateway
  rules:
    - backendRefs:
        - name: media-server
          namespace: apps

GatewayConfig

apiVersion: stunner.l7mp.io/v1
kind: GatewayConfig
metadata:
  name: stunner-config
  namespace: stunner
spec:
  realm: stunner.<env>.<sovereign-domain>
  authType: longterm
  userName: stunner
  password:
    name: stunner-credentials
    namespace: stunner
    key: password

TURN Authentication

STUNner supports long-term credentials:

# Generate time-limited credentials
apiVersion: stunner.l7mp.io/v1
kind: GatewayConfig
spec:
  authType: longterm
  authLifetime: 86400  # 24 hours

Scaling

STUNner scales with KEDA based on connection count:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: stunner-scaler
  namespace: stunner
spec:
  scaleTargetRef:
    name: stunner
  minReplicaCount: 2
  maxReplicaCount: 10
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://mimir.monitoring.svc:8080/prometheus
        metricName: stunner_allocations_active
        query: sum(stunner_allocations_active)
        threshold: "100"

Monitoring

Metric Description
stunner_allocations_active Active TURN allocations
stunner_bytes_received_total Received bytes
stunner_bytes_sent_total Sent bytes
stunner_connections_total Total connections

Part of OpenOva