iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
Cloud Native

K8s上的機器人沙盒系列 第 9

# Day 9|部署 coturn + TURN-REST & WebRTC-Internals 連線驗證

  • 分享至 

  • xImage
  •  

承接 Day 8(Selkies 與 WebRTC 基礎),今天動手部署 coturn + TURN-REST API,讓瀏覽器在多 NAT/防火牆環境中也能建立 WebRTC 連線,並學會用 webrtc-internals 觀察連線是否走到 TURN。

A. 為什麼需要 TURN?

  • ICE 機制會先嘗試 Host、Server Reflexive(STUN),若都失敗才 fallback 到 Relay(TURN)。
  • 在企業網路或多層 NAT 情境下,直連常失敗 → TURN = 必須的備援方案
  • coturn 是最常見的開源 TURN Server,支援 STUN/TURN/REST API 認證。

B. coturn 部署(K8s 範例)

1) Namespace 與 Secret

kubectl create ns turn
kubectl -n turn create secret generic turn-secret --from-literal=secret=MyTURNSecret123

2) ConfigMap(coturn 設定)

# coturn-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coturn-config
  namespace: turn
  labels:
    app: coturn
  
data:
    turnserver.conf: |
      listening-port=3478
      tls-listening-port=5349
      realm=turn.example.com
      fingerprint
      use-auth-secret
      static-auth-secret=MyTURNSecret123
      total-quota=100
      bps-capacity=0
      stale-nonce=600
      no-loopback-peers
      no-multicast-peers

套用:

kubectl apply -f coturn-config.yaml

3) Deployment 與 Service

# coturn-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coturn
  namespace: turn
spec:
  replicas: 1
  selector:
    matchLabels:
      app: coturn
  template:
    metadata:
      labels:
        app: coturn
    spec:
      containers:
      - name: coturn
        image: instrumentisto/coturn:latest
        args: ["-c", "/etc/coturn/turnserver.conf"]
        ports:
        - containerPort: 3478
        - containerPort: 5349
        volumeMounts:
        - name: config
          mountPath: /etc/coturn
      volumes:
      - name: config
        configMap:
          name: coturn-config
---
apiVersion: v1
kind: Service
metadata:
  name: coturn
  namespace: turn
spec:
  type: LoadBalancer
  ports:
  - name: udp-3478
    port: 3478
    protocol: UDP
  - name: tcp-3478
    port: 3478
    protocol: TCP
  - name: tcp-5349
    port: 5349
    protocol: TCP
  selector:
    app: coturn

若環境無 LoadBalancer,可改 NodePort;正式建議配置靜態 IP + DNS:turn.example.com

C. TURN REST API Service(Token 生成)

Selkies 支援 時間戳簽名的 REST APITURN REST API draft)。

  • Token = Base64(username:expiry),以 HMAC-SHA1 與 secret 簽名。
  • 這樣可避免長期憑證外流,常見有效期數分鐘。

範例:簡單 Node.js Token API

// turn-rest.js
const crypto = require('crypto');
const express = require('express');
const app = express();

const secret = process.env.TURN_SECRET || 'MyTURNSecret123';
const realm = 'turn.example.com';

app.get('/turn-cred', (req, res) => {
  const ttl = 300; // 5 分鐘
  const username = Math.floor(Date.now() / 1000) + ttl;
  const hmac = crypto.createHmac('sha1', secret);
  hmac.update(username.toString());
  const password = hmac.digest('base64');

  res.json({
    username: username.toString(),
    password,
    ttl,
    uris: [
      `stun:${realm}:3478`,
      `turn:${realm}:3478?transport=udp`,
      `turn:${realm}:3478?transport=tcp`,
      `turns:${realm}:5349?transport=tcp`
    ]
  });
});

app.listen(8080, () => console.log('TURN REST API on :8080'));

部署後,瀏覽器端 Selkies 會先打 /turn-cred 拿臨時帳號密碼,再組成 ICE Server Config。

D. webrtc-internals 驗證連通性

1) 打開工具

  • Chrome:輸入 chrome://webrtc-internals
  • Firefox:輸入 about:webrtc

2) 驗證步驟

  1. 開啟 Selkies 提供的 URL。

  2. webrtc-internals 觀察:

    • ICE Candidate Pair 狀態:succeeded
    • 若看到 relay → 表示流量確實經由 TURN。
    • 若成功直連,會顯示 srflx(STUN)或 host
  3. 檢查位元率與延遲:

    • googFrameRateSentgoogRttbytesSent/Received

E. 常見問題

  • 無法連線:防火牆未放行 3478/5349;或 NodePort 映射錯誤。
  • 一直走 TURN:可能是雙方在同網也被誤導走 TURN;檢查 ICE Policy 與 STUN Server 配置。
  • 密碼錯誤:TURN REST API secret 與 coturn 不一致。
  • 延遲過高:確認 TURN 節點是否離使用者太遠;建議多區域部署。

F. 感想

俺は誰?ここはどこ?俺は何をしている?


上一篇
Day 8|Selkies 架構與 WebRTC 基礎:ICE / STUN / TURN / Codec Bitrate與Latency
系列文
K8s上的機器人沙盒9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言