Files
gibbz/k8s/deployment.yaml
T
matsandClaude Sonnet 5 78d97ee733
Build and Publish / Metadata (push) Successful in 1s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 25s
Add a second, LAN-only TURN relay to avoid hairpin NAT entirely
The existing coturn instance advertises the router's public IP as its
relay address (external-ip=94.255.139.35) — correct for real external
users, but when both peers are on the same home network as the router,
relay traffic has to hairpin through the router's own WAN IP. That only
worked with hwnat (hardware NAT offload) disabled, which pegged the
router's CPU at 93% for well under half its rated throughput — not an
acceptable trade for the whole household's network.

Instead of touching hwnat, added a second coturn deployment
(coturn-lan, own secret, own relay port range 49210-49220) exposed via
its own MetalLB LoadBalancer IP (10.10.3.46) on the same LAN segment.
That address is answered directly via L2 ARP — no NAT, no hairpin,
hwnat never touches it — and it's deliberately not port-forwarded from
WAN, so it's LAN-only by construction.

iceConfig() now appends this as an extra iceServers entry whenever
TURN_LAN_HOST/TURN_LAN_SECRET are set. It's harmless for anyone not on
that network — the address is simply unreachable and ICE ignores it —
and WebRTC tries every configured server, using whichever candidates
actually connect.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 13:13:25 +02:00

137 lines
3.2 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: gibbz
namespace: home
labels:
app: gibbz
spec:
replicas: 1
selector:
matchLabels:
app: gibbz
template:
metadata:
labels:
app: gibbz
spec:
containers:
- name: gibbz
image: matst80/gibbz:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: PORT
value: "8080"
- name: HOST
value: "0.0.0.0"
- name: OTEL_SERVICE_NAME
value: "gibbz"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://otel-debug-service.monitoring.svc.cluster.local:4318"
- name: STUN_URLS
value: "stun:turn.k6n.net:3478,stun:stun.l.google.com:19302"
- name: TURN_URLS
value: "turn:turn.k6n.net:3478?transport=udp,turn:turn.k6n.net:3478?transport=tcp,turns:turn.k6n.net:5349?transport=tcp"
- name: TURN_SECRET
valueFrom:
secretKeyRef:
name: coturn-secret
key: static-auth-secret
optional: true
- name: TURN_USERNAME
valueFrom:
secretKeyRef:
name: coturn-auth
key: username
optional: true
- name: TURN_CREDENTIAL
valueFrom:
secretKeyRef:
name: coturn-auth
key: password
optional: true
- name: TURN_LAN_HOST
value: "10.10.3.46"
- name: TURN_LAN_SECRET
valueFrom:
secretKeyRef:
name: coturn-lan-secret
key: static-auth-secret
optional: true
- name: OTEL_INGEST_KEY
valueFrom:
secretKeyRef:
name: otel-ingest-auth
key: key
optional: true
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /readyz
port: http
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: gibbz
namespace: home
labels:
app: gibbz
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: gibbz
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gibbz-ingress
namespace: home
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/websocket-services: "gibbz"
spec:
ingressClassName: nginx
rules:
- host: gibbz.k6n.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gibbz
port:
number: 80
tls:
- hosts:
- gibbz.k6n.net
secretName: gibbz-k6n-net-tls