内容提要
STUNner 是 Kubernetes 原生的 TURN 服务器,用于中继 WebRTC 媒体流量,而非负载均衡。它通过 Gateway API 将 TURN 请求终止于公共端点,并转发至后端 Pod。生产部署需配置临时凭证、多租户网关和共享密钥轮换。密钥轮换需同步更新双方,并注意数据平面重启影响。多租户建议每媒体服务器独立网关,以隔离故障。负载均衡层因云而异,EKS 上需配置弹性 IP 和混合协议支持。
延伸解读
STUNner 与负载均衡器的本质区别
STUNner 并非负载均衡器,而是中继器。它不负责选择后端 Pod,也不进行流量分发。客户端在连接前已通过信令层确定了目标 Pod,STUNner 仅验证 TURN 凭证并将媒体数据转发至该 Pod。因此,媒体服务器仍需自行处理会话分配,例如通过 Jicofo 或 Media Resource Broker。理解这一点有助于避免将 UDPRoute 误认为负载均衡池,从而正确配置后端白名单。
多租户隔离与成本权衡
多租户部署时,建议为每个媒体服务器配置独立的 Gateway 和 UDPRoute,并置于各自命名空间,以隔离故障和凭据。但每个网关会对应一个云负载均衡器,增加成本。若共享网关,则需共享认证凭据,扩大影响范围,仅适合开发或测试环境。生产环境应权衡隔离需求与成本,必要时为每个租户分配独立的 GatewayClass。
密钥轮换的同步与中断风险
轮换共享密钥时,STUNner 与媒体服务器必须同步更新,否则新凭证立即失效。安全顺序为先更新 STUNner 端并重启 stunnerd,再更新媒体服务器。注意 stunnerd 将活动 TURN 分配保存在内存中,重启会导致现有通话中断,需安排在低峰期。此外,任何导致数据平面重启的变更(如镜像更新)都会影响活动会话,应提前规划。
混合协议支持与云平台差异
在受限网络(如企业 VPN)中,UDP 可能被屏蔽,需提供 TCP 备用。STUNner 支持在同一端口(如 3478)同时提供 UDP 和 TCP,但需同时配置网关注解和云负载均衡器注解。不同云平台支持程度不同:AWS 和 Azure 可混合协议,GCP 等则需为每个协议单独部署网关,导致多个 IP 和 DNS 记录。配置时需注意注解缺失会导致协议监听器被丢弃。
Q&A
STUNner 在 Kubernetes 中扮演什么角色?
STUNner 是一个 Kubernetes 原生的 TURN 服务器,用于中继 WebRTC 媒体流量,而不是负载均衡器。它通过 Gateway API 将 TURN 请求终止于公共端点,并将媒体数据中继到后端的 Pod。
STUNner 的 UDPRoute 与负载均衡器有何不同?
UDPRoute 是一个白名单,而不是负载均衡池。它列出了允许中继到的后端 Service 的 Pod IP 地址,stunnerd 会将客户端请求的对等方地址与这些 IP 比对,匹配则转发,否则丢弃。它不会选择后端或分发流量。
STUNner 生产环境推荐使用哪种认证模式?
生产环境推荐使用临时凭证模式,即每个客户端获得由共享密钥生成的短效用户名和密码,遵循 TURN REST API 凭证方案。静态凭证仅适用于开发测试,因为泄露的凭证不会过期。
如何安全地轮换 STUNner 的共享密钥?
轮换密钥时,双方必须同步更新。安全顺序是:先替换 STUNner 端的共享密钥,然后重启 stunnerd 数据平面使其加载新值,再更新媒体服务器或凭证生成服务,最后切换凭证铸造。现有 TURN 分配可继续使用直到过期,但新凭证必须使用新密钥。
在 EKS 上部署 STUNner 时,如何配置负载均衡器以支持 TCP 和 UDP 在同一端口?
需要在 STUNner 网关上添加注解 stunner.l7mp.io/enable-mixed-protocol-lb: "true",并在负载均衡器服务上添加注解 service.beta.kubernetes.io/aws-load-balancer-enable-tcp-udp-listener: "true"。两者缺一不可,否则 TCP 或 UDP 监听器会被丢弃。
STUNner 多租户部署时,为什么建议每个媒体服务器使用独立的网关?
每个媒体服务器使用独立网关可以将凭据、指标、重启和故障隔离在单个实例范围内,避免影响其他租户。虽然会增加负载均衡器成本,但共享网关会共享认证凭据并扩大影响范围,因此仅建议在开发或测试环境使用。
STUNner 故障排查时,应该按照什么顺序检查资源?
应按照资源链的顺序从上到下检查:GatewayClass、GatewayConfig、Secret、Gateway、UDPRoute 以及生成的 Service。故障出现的层级通常指向真正的问题,例如网关无法获取地址检查控制器日志,UDPRoute 未被接受检查后端服务,中继未授权检查共享密钥是否匹配。