Skip to main content

如何在Kubenetes集群中部署Stun服务器

· 3 min read
Ferdinand Su

一般地,WebRTC需要两台主机建立P2P连接从而完成直接的数据传输。然而,在一些情况下,这是不可能的(例如在K8s集群中),为此,我们需要STUN/TURN服务器的支持。而STUNner就是这样的一个专门为K8s集群准备的Stun/Turn服务器。本文将讲述如何快速部署Stunner到K8s实验集群中以开展非生产用途的测试。

1. 安装Stunner

使用Helm安装Stunner非常轻松。但是,请记得为containerd配置镜像:sudo nano /etc/containerd/config.toml

...
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.mirrors.ustc.edu.cn","https://docker.mirrors.ustc.edu.cn"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
endpoint = ["https://gcr.m.daocloud.io"]
...

然后,通过脚本安装Helm | Installing Helm,脚本见此处。 下面,利用helm安装stunner到集群。

helm repo add stunner https://l7mp.io/stunner
helm repo update
helm install stunner-gateway-operator stunner/stunner-gateway-operator-dev --create-namespace --namespace=stunner-system

这样,stunner会被安装到stunner-system命名空间下。

2. 配置网关和鉴权

参照网关相关文档,部署以下组件到stunner命名空间下。

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: stunner-gatewayclass
spec:
controllerName: "stunner.l7mp.io/gateway-operator"
parametersRef:
group: "stunner.l7mp.io"
kind: GatewayConfig
name: stunner-gatewayconfig
namespace: stunner
description: "STUNner is a WebRTC ingress gateway for Kubernetes"
---
apiVersion: stunner.l7mp.io/v1
kind: GatewayConfig
metadata:
name: stunner-gatewayconfig
namespace: stunner
spec:
logLevel: "all:DEBUG,turn:INFO"
realm: stunner.l7mp.io
authRef:
name: stunner-auth-secret
namespace: stunner
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: complex-gateway
namespace: stunner
annotations:
stunner.l7mp.io/service-type: NodePort
stunner.l7mp.io/enable-mixed-protocol-lb: 'true'
spec:
gatewayClassName: stunner-gatewayclass
listeners:
- name: udp-listener
port: 3478
protocol: TURN-UDP
allowedRoutes:
namespaces:
from: All
- name: tcp-listener
port: 3478
protocol: TURN-TCP
allowedRoutes:
namespaces:
from: All
---
apiVersion: v1
kind: Secret
metadata:
name: stunner-auth-secret
namespace: stunner
type: kubernetes.io/basic-auth
stringData:
type: static
username: stunner-user
password: rfrCWzl_i5fBr

3. 配置路由

还是遵照同一文档,部署以下组件到stunner命名空间下。

apiVersion: stunner.l7mp.io/v1
kind: StaticService
metadata:
name: internal-debugger
namespace: stunner
spec:
prefixes:
- "0.0.0.0/0" # 这里实际上是有安全隐患的
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: UDPRoute
metadata:
name: internal-debugger-route
namespace: stunner
spec:
parentRefs:
- name: complex-gateway
rules:
- backendRefs:
- group: stunner.l7mp.io
namespace: stunner
kind: StaticService
name: internal-debugger

4. 构造ICE配置

文档上说在集群内运行curl "http://stunner-auth.stunner-system:8088/ice?service=turn&username=stunner-user" 即可获得合法的配置,遗憾的是,我获取到的总是带PlaceHolder的。因此便自己构造了一波。

运行kubectl -n stunner get services即可找到刚才部署的网关,集群内外端口可在 PORT(S) 处看到,3478是内部端口。不妨设外部端口为1234,那么,一个合法的外部ICEConfig就是:

{
"iceServers": [
{
"username": "stunner-user",
"credential": "rfrCWzl_i5fBr",
"urls": [
"turn:<nodeIp>:1234?transport=udp",
"turn:<nodeIp>:1234?transport=tcp"
]
}
],
"iceTransportPolicy": "all"
}

此配置可以用于任何合法的位置。

5. 查看日志

kubectl -n stunner get pods

查看这个pod日志即可。