This document guides you through the installation of Elixir WebRTC, called Nexus into Kubernetes, when it is used together with the STUNner WebRTC media gateway.
In this demo you will learn to:
- integrate a typical WebRTC application with STUNner,
- obtain a valid TLS certificate to secure the signaling plane,
- deploy the Nexus app server into Kubernetes, and
- configure STUNner to expose Nexus to clients.
To run this example, you need:
- a Kubernetes cluster,
- a deployed STUNner (presumably the latest stable version),
- an Ingress controller to ingest traffic into the cluster,
- a Cert-manager to automate TLS certificate management.
Note
If you have your own TLS certificate, put it in a Secret
resource and deploy it into the default
namespace under the nexus-secret-tls
name.
Now comes the fun part. The simplest way to run this demo is to clone the STUNner git repository and deploy (after some minor modifications) the manifest packaged with STUNner.
To install the stable version of STUNner, please follow the instructions in this section.
Configure STUNner to act as a STUN/TURN server to clients, and route all received media to the Nexus pods.
git clone https://github.com/l7mp/stunner
cd stunner
kubectl apply -f docs/examples/elixir-webrtc/nexus-call-stunner.yaml
The relevant parts here are the STUNner Gateway definition, which exposes the STUNner STUN/TURN server over UDP:3478 to the Internet, and the UDPRoute definition, which takes care of routing media to the pods running the Nexus Gateway service.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: udp-gateway
namespace: stunner
spec:
gatewayClassName: stunner-gatewayclass
listeners:
- name: udp-listener
port: 3478
protocol: UDP
---
apiVersion: stunner.l7mp.io/v1
kind: UDPRoute
metadata:
name: nexus
namespace: stunner
spec:
parentRefs:
- name: udp-gateway
rules:
- backendRefs:
- kind: Service
name: nexus
namespace: default
Once the Gateway resource is installed into Kubernetes, STUNner will create a Kubernetes LoadBalancer for the Gateway to expose the TURN server on UDP:3478 to clients. It can take up to a minute for Kubernetes to allocate a public external IP for the service.
Wait until Kubernetes assigns an external IP and store the external IP assigned by Kubernetes to STUNner in an environment variable for later use.
until [ -n "$(kubectl get svc udp-gateway -n stunner -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" ]; do sleep 1; done
export STUNNERIP=$(kubectl get service udp-gateway -n stunner -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
The crucial step of integrating any WebRTC media server with STUNner is to ensure that the server instructs the clients to use STUNner as the STUN/TURN server. Unfortunately, currently the official Nexus Docker image does not support this configuration in runtime (by default Google's STUN server is hardcoded into it). Therefore, we have to modify this setting to STUNner's IP and build a new Docker image.
In order to achieve this, first clone the Elixir WebRTC sample app repository:
git clone https://github.com/elixir-webrtc/apps/
cd apps/nexus
You have to modify the ICE config to use STUNner with the given credentials in two files:
assets/js/home.js
:
...
# const pcConfig = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
# change to:
const pcConfig = { iceServers: [{ urls: 'turn:<STUNNERIP>:3478?transport=udp', username: 'user-1', credential: 'pass-1'}], iceTransportPolicy: 'relay' };
lib/nexus/peer.ex
:
...
# ice_servers: [%{urls: "stun:stun.l.google.com:19302"}],
# change to:
ice_servers: [%{urls: "turn:<STUNNERIP>:3478?transport=udp", "username": "user-1", "credential": "pass-1"}],
ice_transport_policy: :relay,
Now rebuild the Docker image, and push it into your image repository:
export MYREPO=myrepo # use your own Docker repository name!
sudo docker build -t $MYREPO/nexus .
sudo docker push $MYREPO/nexus
After uploading the image, you also have to modify the Nexus image repo location in the Kubernetes deployment file.
sed -i "s/l7mp/$MYREPO/g" docs/examples/elixir-webrtc/nexus-server.yaml
We also need the Ingress external IP address we have stored previously: this will make sure that the TLS certificate created by cert-manager will be bound to the proper nip.io
domain and IP address.
sed -i "s/ingressserviceip/$INGRESSIP/g" docs/examples/elixir-webrtc/nexus-server.yaml
Finally, fire up Nexus.
kubectl apply -f docs/examples/elixir-webrtc/nexus-server.yaml
The demo installation bundle includes a few resources to deploy Nexus:
- Nexus deployment and service,
- a cluster issuer for the TLS certificates,
- an Ingress resource to terminate the secure connections between your browser and the Kubernetes cluster.
Wait until all pods become operational and jump right into testing!
After installing everything, execute the following command to retrieve the URL of your freshly deployed Nexus demo app:
echo INGRESSIP.nip.io
Copy the URL into your browser, and if everything is set up correctly, you should be able to connect to a video room. If you repeat the procedure in a separate browser tab you can enjoy a nice video-conferencing session with yourself, with the twist that all media between the browser tabs is flowing through STUNner and the Nexus server deployed in you Kubernetes cluster.
STUNner development is coordinated in Discord, feel free to join.