We are proud to present STUNner v0.20.0, the fourth stable release candidate of the STUNner Kubernetes media gateway for WebRTC, brought to you by l7mp.io.
Originally, we did not intend to release a fourth release candidate (RC). In fact, after RC1, we hadn't planned on releasing any additional RCs. However, a few minor bug fixes and feature requests have made it necessary to revise our plans once again. As a result, we have decided to roll out a fourth, and, if all goes well, final-release candidate before v1.
News
There are no major new features in this release. Minor changes include a couple of new Gateway annotations to choose the nodeport and control whether to expose the health check port on external load-balancer Services (see the rewritten documentation). Additionally, two significant architectural changes have been made that may impact our users: as of this release, we have set the default "TURN session stickiness" to "client-IP," disabled the operator finalizer, and added full support for STUN deployments (previously, only TURN was supported). This completes the NAT traversal protocols supported by STUNner, offering the full WebRTC suite.
Session stickiness
TURN is a layer-7 protocol that implements its own handshakes for creating and managing allocations, requesting permission to reach peer IPs, and more. This is quite different from most UDP-based protocols, like DNS, which typically use a single packet exchange. DNS is simpler to support in UDP load balancers, as it does not require subsequent packets from the same client to be routed to the same endpoint/pod. This can be managed without creating per-client session state in the load balancer (e.g., using round-robin or a simple hash). Unfortunately, many load balancer implementations still default to DNS-like stateless UDP session routing, which conflicts with the UDP/TURN requirement that packets from the same client IP and port be routed to the same backend pod. When this fails, you get the dreaded "no allocation found" errors, indicating that the TURN packets of a session were routed by the load balancer to a new pod where no TURN allocation exists for the session.
Enabling sticky sessions for the load balancer service can improve the robustness of TURN connection routing, especially during scale-out/scale-in events. Therefore, in this release, STUNner sets load balancer Service's session affinity to clientIP
.
We have received overwhelmingly positive feedback from our users regarding this change. However, it is still not entirely clear how UDP session stickiness is implemented across different Kubernetes providers' load balancer controllers. Please file an issue if this setting causes any problems in your deployment.
Disabling the operator finalizer
In the last release, we introduced a session finalizer in the STUNner gateway operator. This feature ensured that all Kubernetes resources automatically created by the operator were properly removed and resource statuses were invalidated when the operator terminated. Unfortunately, this conflicted with the high-availability requirements of some of our customers. Specifically, during operator restarts (e.g., due to a node failure), there was a transient phase where the old operator instance had already removed the dataplanes and external load balancer services and the new instance had not yet finished creating the replacements, causing clients' live TURN sessions to break.
To address this issue, we have disabled the finalizer by default in this release. You can still enable it by using the command-line flag --enable-finalizer=true
on the operator; otherwise, it remains off by default. This change means that when the operator terminates Kubernetes resources it automatically created may be left in an undefined state. To avoid potential issues, make sure you manually remove all Gateway API resources (Gateways, UDPRoutes, etc.) when uninstalling STUNner to clean up your cluster.
STUN support
Several users have indicated that they expected a project named "STUNner" to actually support the STUN protocol where the name comes from. Until now, our focus has been on supporting TURN in STUNner and, although the implementation has always included a complete STUN server, we had not explicitly supported STUN. With this release, STUN is now a first-class citizen in STUNner. For more details, see the related blog post.
Commits
feature: Set LB service session affinity to "clientIP" (#51)
feature: Allow Gateways to select the target port, fixes #50
feature: Allow stunnerd pod labels/annotations to be set from the DP
feature: Configure the exposition of the health-check port, fix #49
feature(turncat): Set SNI on TURN/TLS client connections
fix: Fix indexing error in upsertDeployment, #48
fix: Fix segfault when setting the affinity from the Dataplane
fix: Prevent concurrent WS socket write errors in the CDS client
fix: Remove STUNner annotations from Service unless defined in Gateway
fix: Set spec.externalTrafficPolicy only for external Services, fix #150
fix(turncat): Report error in turncat when invoked with empty peer IP
main origin/main feat: Disable operator finalization
Enjoy STUNner and don't forget to support us!