Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor example docs #164

Merged
merged 37 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a55845e
refact(/docs/examples): Refactoring the example docs WIP
davidkornel Sep 29, 2024
17f3b2e
fix(/docs/install): Typo
davidkornel Sep 29, 2024
2f9f64e
refact(/docs/example/janus): Simplify prerequisites
davidkornel Sep 29, 2024
71aa3ea
refact(examples/janus): Simplify Ingress and cert mananger install se…
davidkornel Sep 29, 2024
3aac95d
refact(examples/janus): Refer to stunner install guide instead of red…
davidkornel Sep 29, 2024
0591277
fix: Remove extra space
davidkornel Sep 29, 2024
6fcdb00
fix: Wording
davidkornel Sep 29, 2024
efcb150
docs: Move kurento back in the examples
davidkornel Oct 9, 2024
682efee
fix: Typos
davidkornel Oct 9, 2024
0f0a600
docs(TLS): Extend the If you have your own domain section
davidkornel Oct 9, 2024
578814d
docs(RTD): Add TLS doc
davidkornel Oct 11, 2024
47d5bd8
refact(/examples/livekit): Refactor LiveKit example doc
davidkornel Oct 11, 2024
a0556fd
fix(/examples/livekit): Remove unnecessary stun server configuration …
davidkornel Oct 11, 2024
78a5785
refact(/examples/livekit): Minor changes
davidkornel Oct 11, 2024
1f36672
refactor(/examples/mediasoup): Refactor mediasoup example doc
davidkornel Oct 11, 2024
b8c1748
refactor(/examples/jitsi): Refactor Jitsi example doc
davidkornel Oct 14, 2024
e88566f
fix: Fix wrong doc reference
davidkornel Oct 14, 2024
0415106
fix: Revert removing stun config from livekit
davidkornel Oct 15, 2024
2ec37b1
refact(/examples/neko): Minor refactor
davidkornel Oct 15, 2024
636febe
refact(examples): Minor refact and adding missing Help section
davidkornel Oct 15, 2024
77c3a92
docs(/examples/mediasoup): Add missing mediasoup arch fig
davidkornel Oct 15, 2024
653a23b
docs(neko): Fix note block
davidkornel Oct 16, 2024
7389d9a
docs: Add Elixir from PR #162
davidkornel Oct 16, 2024
e1d61ad
docs: Addresing suggested changes
davidkornel Oct 16, 2024
3a0fd57
docs(/examples/elixir): Inititial refactor
davidkornel Oct 16, 2024
b296e6a
docs(TLS.md): Minor changes
davidkornel Oct 16, 2024
1e79d22
refact(/examples/livekit): Compact README
davidkornel Oct 16, 2024
d0a9b5f
docs(livekit): Change section title
davidkornel Oct 19, 2024
ee89aa6
refact(/janus): Refactor docs once more
davidkornel Oct 19, 2024
6c70d2f
docs(elixir): Refactor and fix image
davidkornel Oct 19, 2024
ecfdaff
docs(jitsi): Refactor once more
davidkornel Oct 19, 2024
b3cc45e
docs(mediasoup): Refactor once more
davidkornel Oct 19, 2024
3e20945
docs(neko): Refactor
davidkornel Oct 19, 2024
32b9cc2
docs(TLS): Reword ingress desc
davidkornel Oct 21, 2024
82df6bb
docs(examples): Reword prerequisites
davidkornel Oct 21, 2024
c68a491
doc(examples/simple-tunnel): Fix turncat links
levaitamas Oct 24, 2024
0634024
docs(install): Add skip crd install section
davidkornel Oct 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -555,17 +555,6 @@ applications into Kubernetes.

### Media-plane deployment model

* [One to one video call with Kurento](/docs/examples/kurento-one2one-call/README.md): This tutorial
shows how to use STUNner to connect WebRTC clients to a media server deployed into Kubernetes
behind STUNner in the [media-plane deployment model](/docs/DEPLOYMENT.md). All this happens
*without* modifying the media server code in any way, just by adding 5-10 lines of
straightforward JavaScript to configure clients to use STUNner as the TURN server.
* [Magic mirror with Kurento](/docs/examples/kurento-magic-mirror/README.md): This tutorial has been
adopted from the [Kurento](https://www.kurento.org) [magic
mirror](https://doc-kurento.readthedocs.io/en/stable/tutorials/node/tutorial-magicmirror.html)
demo, deploying a basic WebRTC loopback server behind STUNner with some media processing
added. In particular, the application uses computer vision and augmented reality techniques to
add a funny hat on top of faces.
* [Video-conferencing with LiveKit](/docs/examples/livekit/README.md): This tutorial helps you deploy
the [LiveKit](https://livekit.io) WebRTC media server behind STUNner. The docs also show how to
obtain a valid TLS certificate to secure your signaling connections, courtesy of the
Expand All @@ -576,6 +565,12 @@ applications into Kubernetes.
behind STUNner. The docs also show how to obtain a valid TLS certificate to secure your signaling
connections, using [cert-manager](https://cert-manager.io), [nip.io](https://nip.io) and [Let's
Encrypt](https://letsencrypt.org).
* [Video-conferencing with Elixir WebRTC](/docs/examples/elixir-webrtc/README.md): This tutorial helps
you deploy a fully fledged [Elixir WebRTC](https://elixir-webrtc.org/) video-conferencing room called
[Nexus](https://github.com/elixir-webrtc/apps/tree/master/nexus) into Kubernetes
behind STUNner. The docs also show how to obtain a valid TLS certificate to secure your signaling
connections, using [cert-manager](https://cert-manager.io), [nip.io](https://nip.io) and [Let's
Encrypt](https://letsencrypt.org).
* [Video-conferencing with Jitsi](/docs/examples/jitsi/README.md): This tutorial helps you deploy a
fully fledged [Jitsi](https://jitsi.org) video-conferencing service into Kubernetes behind
STUNner. The docs also show how to obtain a valid TLS certificate to secure your signaling
Expand All @@ -595,6 +590,17 @@ applications into Kubernetes.
providing an ingress gateway service to a remote desktop application. We use
[neko.io](https://neko.m1k1o.net) to run a browser in a secure container inside the Kubernetes
cluster, and stream the desktop to clients via STUNner.
* [One to one video call with Kurento](/docs/examples/kurento-one2one-call/README.md): This tutorial
shows how to use STUNner to connect WebRTC clients to a media server deployed into Kubernetes
behind STUNner in the [media-plane deployment model](/docs/DEPLOYMENT.md). All this happens
*without* modifying the media server code in any way, just by adding 5-10 lines of
straightforward JavaScript to configure clients to use STUNner as the TURN server.
* [Magic mirror with Kurento](/docs/examples/kurento-magic-mirror/README.md): This tutorial has been
adopted from the [Kurento](https://www.kurento.org) [magic
mirror](https://doc-kurento.readthedocs.io/en/stable/tutorials/node/tutorial-magicmirror.html)
demo, deploying a basic WebRTC loopback server behind STUNner with some media processing
added. In particular, the application uses computer vision and augmented reality techniques to
add a funny hat on top of faces.

## Documentation

Expand Down
2 changes: 1 addition & 1 deletion docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ helm install stunner-gateway-operator stunner/stunner-gateway-operator --create-
--namespace=stunner-system
```

And that's all: you don't need to install the dataplane separately, this is handled automatically by the operator. The `stunnerd` pods created by the operator can be customized using the Dataplane custom resource: you can specify the `stunnerd` container image version, provision resources per each `stunenrd` pod, deploy into the host network namespace, etc.; see the documentation [here](https://pkg.go.dev/github.com/l7mp/stunner-gateway-operator/api/v1alpha1#DataplaneSpec).
And that's all: you don't need to install the dataplane separately, this is handled automatically by the operator. The `stunnerd` pods created by the operator can be customized using the Dataplane custom resource: you can specify the `stunnerd` container image version, provision resources per each `stunnerd` pod, deploy into the host network namespace, etc.; see the documentation [here](https://pkg.go.dev/github.com/l7mp/stunner-gateway-operator/api/v1alpha1#DataplaneSpec).

### Development version

Expand Down
5 changes: 3 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@

### Media-plane deployment model

* [One to one video call with Kurento](examples/kurento-one2one-call)
* [Magic mirror with Kurento](examples/kurento-magic-mirror/README.md)
* [Video-conferencing with LiveKit](examples/livekit/README.md)
* [Video-conferencing with mediasoup](examples/mediasoup/README.md)
* [Video-conferencing with Janus](examples/janus/README.md)
* [Video-conferencing with Elixir WebRTC](examples/elixir-webrtc/README.md)
* [Video-conferencing with Jitsi](examples/jitsi/README.md)
* [Cloud-gaming with CloudRetro](examples/cloudretro/README.md)
* [Remote desktop access with Neko](examples/neko/README.md)
* [One to one video call with Kurento](examples/kurento-one2one-call)
* [Magic mirror with Kurento](examples/kurento-magic-mirror/README.md)

## Manuals

Expand Down
103 changes: 103 additions & 0 deletions docs/examples/TLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# TLS

This documentation sums up the TLS and certificate issues you will encounter deploying the examples.

## The issue

Some client-side application must work over a secure HTTPS connection, because [getUserMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#browser_compatibility) is available only in secure contexts. This implies that the client-server signaling connection must be secure too. In the demos, we will aim to obtain a proper CA-signed certificate (self-signed certificates haven't been tested). Obtaining a valid TLS certificate is a challenge. Thus, the majority of the installation guides will be about securing client connections to the client-side apps and the WebRTC mediaservers over TLS. Once HTTPS is correctly working, integrating the mediaservers with STUNner is very simple.

## TLS certificates

Some WebRTC servers will need a valid TLS cert, which means it must run behind an existing DNS domain name backed by a CA signed TLS certificate. This is simple if you have your own domain, but if you don't, we still have a solution for that.

> [!NOTE]
>
> By default, the examples and commands snippets assume you don't own a domain.

### If you don't have your own domain

[nip.io](https://nip.io) provides a dead simple wildcard DNS for any IP address. We will use this to "own a domain" and obtain a CA signed certificate for the mediaserver. This will allow us to point the domain name `client-<ingress-IP>.nip.io` to an ingress HTTP gateway in our Kubernetes cluster, which will then use some automation (namely, cert-manager) to obtain a valid CA signed cert.

### If you have your own domain

We use `nip.io` to "own a domain" in some examples. To replace it with your own domain, you must locate the corresponding lines in the specific mediaserver's configuration file and overwrite them.

> [!NOTE]
>
> Although they might look similar, every mediaserver has a different configuration. You might need to (re)configure more things in one mediaserver than another.

> [!NOTE]
>
> Make sure to set up your Ingress correctly and do not forget to create a new DNS record pointing to your Ingress' IP address!

## Installation

### Ingress

The first step of secured traffic ingestion is obtaining a valid cert by installing a Kubernetes Ingress: this will be used during the validation of our certificates and to terminate client TLS encrypted contexts.

Install an Ingress controller into your cluster. We used the official [nginx ingress](https://github.com/kubernetes/ingress-nginx), but this is not required.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Install an Ingress controller into your cluster. We used the official [nginx ingress](https://github.com/kubernetes/ingress-nginx), but this is not required.
Install an Ingress controller into your cluster. We used the official [nginx ingress](https://github.com/kubernetes/ingress-nginx), but other Ingress implementations might work (check their documentation for install steps).


```console
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx
```

Wait until Kubernetes assigns an external IP to the Ingress.

```console
until [ -n "$(kubectl get service ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" ]; do sleep 1; done
```

Store the Ingress IP address Kubernetes assigned to our Ingress; this will be needed later when we configure the validation pipeline for our TLS certs.

```console
kubectl get service ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
export INGRESSIP=$(kubectl get service ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESSIP=$(echo $INGRESSIP | sed 's/\./-/g')
```

### Cert manager

We use the official [cert-manager](https://cert-manager.io) to automate TLS certificate management.

Add the Helm repository, which contains the cert-manager Helm chart, and install the charts:

```console
helm repo add cert-manager https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager \
--create-namespace --set global.leaderElection.namespace=cert-manager \
--set crds.enabled=true --timeout 600s
```

At this point we have all the necessary boilerplate set up to automate TLS issuance for the demo.

## Troubleshooting

#### Wildcard DNS domain rate limiting

Note that public wildcard DNS domains might run into [rate limiting](https://letsencrypt.org/docs/rate-limits/) issues. If this occurs you can try [alternative services](https://moss.sh/free-wildcard-dns-services/) instead of `nip.io`.

#### Certificate issuance

If you work with certificates you must be aware that signing a certificate request takes some time and it differs for every CA (certificate authority). If you sense there is a problem with the certificate being signed or issued, you can check it directly and see what is going on.

First, you'll need to find the certificate and its related resources in your cluster.
```console
kubectl get certificate -A
kubectl get certificaterequests.cert-manager.io -A
kubectl get certificatesigningrequests.certificates.k8s.io
```

To find more information about them
```console
kubectl describe certificate <certificate> -A
kubectl describe certificaterequests.cert-manager.io <cert-request> -A
kubectl describe certificatesigningrequests.certificates.k8s.io <cert-signing-request>
```

# Help

STUNner development is coordinated in Discord, feel free to [join](https://discord.gg/DyPgEsbwzc).
4 changes: 4 additions & 0 deletions docs/examples/benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,7 @@ Notice that the average packets/second rate will be slightly lower in case of a

* It is advised to repeat the measurment with different packet sizes. Recommended packet sizes in bytes are 64, 128, 256, 512, 1024, and 1200. Small packet sizes result lower effective throughput (when packet drop is < 1%).
* Measuring [measuring one-way latency](https://stackoverflow.com/questions/63793030/iperf2-latency-is-a-two-way-or-one-way-latency) with `iperf` requires the clocks at the iperf client and server to be synchronized. Without this the results may be corrupted, and you may even see negative latencies.

# Help

STUNner development is coordinated in Discord, feel free to [join](https://discord.gg/DyPgEsbwzc).
17 changes: 6 additions & 11 deletions docs/examples/cloudretro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ In this demo you will learn how to:

## Prerequisites

The below installation instructions require an operational cluster running a supported version of
Kubernetes (>1.22). Most hosted or private Kubernetes cluster services will work, but make sure
that the cluster comes with a functional load-balancer integration (all major hosted Kubernetes
services should support this). Otherwise, STUNner will not be able to allocate a public IP address
for clients to reach your WebRTC infra.
See prerequisites [here](../../INSTALL.md#prerequisites).

You will need a basic familiarity [with the CloudRetro
architecture](https://webrtchacks.com/open-source-cloud-gaming-with-webrtc), especially the concept
Expand Down Expand Up @@ -79,12 +75,7 @@ the CloudRetro servers running on a private pod IP address. That is where STUNne

### STUNner

First we install STUNner gateway operator with helm ([more info](https://github.com/l7mp/stunner-helm)):
```console
helm repo add stunner https://l7mp.io/stunner
helm repo update
helm install stunner-gateway-operator stunner/stunner-gateway-operator --create-namespace --namespace=stunner
```
First we install the stable version of STUNner, please follow the instructions in [this section](../../INSTALL.md#installation-1).

Wait until all the necessary resources are up and running, then you are ready to continue.

Expand Down Expand Up @@ -242,3 +233,7 @@ kubectl delete -f cloudretro-setup-coordinator.yaml
kubectl delete -f cloudretro-setup-workers.yaml
kubectl delete -f cloudretro-stunner-cleanup.yaml
```

# Help

STUNner development is coordinated in Discord, feel free to [join](https://discord.gg/DyPgEsbwzc).
4 changes: 4 additions & 0 deletions docs/examples/direct-one2one-call/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,7 @@ Delete the demo deployment using the below command:
kubectl delete -f docs/examples/direct-one2one-call/direct-one2one-call-server.yaml
kubectl delete -f docs/examples/direct-one2one-call/direct-one2one-call-stunner.yaml
```

# Help

STUNner development is coordinated in Discord, feel free to [join](https://discord.gg/DyPgEsbwzc).
157 changes: 157 additions & 0 deletions docs/examples/elixir-webrtc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# STUNner demo: Video-conferencing with Nexus

This document guides you through the installation of [Elixir WebRTC](https://elixir-webrtc.org/), called [Nexus](https://github.com/elixir-webrtc/apps/tree/master/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.

## Prerequisites

To run this example, you need:
* a [Kubernetes cluster](../../INSTALL.md#prerequisites),
* a [deployed STUNner](../../INSTALL.md#installation-1) (presumably the latest stable version),
* an [Ingress controller](../TLS.md#ingress) to ingest traffic into the cluster,
* a [Cert-manager](../TLS.md#cert-manager) to secure traffic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* a [Cert-manager](../TLS.md#cert-manager) to secure traffic.
* a [Cert-manager](../TLS.md#cert-manager) to automate TLS certificate management.


> [!NOTE]
>
> If you have your own TLS certificate, put it in a `Secret` [resource](https://kubernetes.io/docs/concepts/configuration/secret/) and deploy it into the `default` namespace under the `nexus-secret-tls` name.

### STUNner

Now comes the fun part. The simplest way to run this demo is to clone the [STUNner git repository](https://github.com/l7mp/stunner) and deploy (after some minor modifications) the [manifest](livekit-server.yaml) packaged with STUNner.

To install the stable version of STUNner, please follow the instructions in [this section](../../INSTALL.md#installation-1).

Configure STUNner to act as a STUN/TURN server to clients, and route all received media to the Nexus pods.

```console
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](../../GATEWAY.md#gateway), which exposes the STUNner STUN/TURN server over UDP:3478 to the Internet, and the [UDPRoute definition](../../GATEWAY.md#udproute), which takes care of routing media to the pods running the Nexus Gateway service.

```yaml
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.

```console
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}')
```
### Nexus Docker images

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](ghcr.io/elixir-webrtc/apps/nexus) 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:

```console
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", "iceTransportPolicy": "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.

```console
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.

```console
sed -i "s/ingressserviceip/$INGRESSIP/g" docs/examples/elixir-webrtc/nexus-server.yaml
```

Finally, fire up Nexus.

```console
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!

## Test

After installing everything, execute the following command to retrieve the URL of your freshly deployed Nexus demo app:

```console
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.

# Help

STUNner development is coordinated in Discord, feel free to [join](https://discord.gg/DyPgEsbwzc).
Loading
Loading