-
-
Notifications
You must be signed in to change notification settings - Fork 61
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
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 17f3b2e
fix(/docs/install): Typo
davidkornel 2f9f64e
refact(/docs/example/janus): Simplify prerequisites
davidkornel 71aa3ea
refact(examples/janus): Simplify Ingress and cert mananger install se…
davidkornel 3aac95d
refact(examples/janus): Refer to stunner install guide instead of red…
davidkornel 0591277
fix: Remove extra space
davidkornel 6fcdb00
fix: Wording
davidkornel efcb150
docs: Move kurento back in the examples
davidkornel 682efee
fix: Typos
davidkornel 0f0a600
docs(TLS): Extend the If you have your own domain section
davidkornel 578814d
docs(RTD): Add TLS doc
davidkornel 47d5bd8
refact(/examples/livekit): Refactor LiveKit example doc
davidkornel a0556fd
fix(/examples/livekit): Remove unnecessary stun server configuration …
davidkornel 78a5785
refact(/examples/livekit): Minor changes
davidkornel 1f36672
refactor(/examples/mediasoup): Refactor mediasoup example doc
davidkornel b8c1748
refactor(/examples/jitsi): Refactor Jitsi example doc
davidkornel e88566f
fix: Fix wrong doc reference
davidkornel 0415106
fix: Revert removing stun config from livekit
davidkornel 2ec37b1
refact(/examples/neko): Minor refactor
davidkornel 636febe
refact(examples): Minor refact and adding missing Help section
davidkornel 77c3a92
docs(/examples/mediasoup): Add missing mediasoup arch fig
davidkornel 653a23b
docs(neko): Fix note block
davidkornel 7389d9a
docs: Add Elixir from PR #162
davidkornel e1d61ad
docs: Addresing suggested changes
davidkornel 3a0fd57
docs(/examples/elixir): Inititial refactor
davidkornel b296e6a
docs(TLS.md): Minor changes
davidkornel 1e79d22
refact(/examples/livekit): Compact README
davidkornel d0a9b5f
docs(livekit): Change section title
davidkornel ee89aa6
refact(/janus): Refactor docs once more
davidkornel 6c70d2f
docs(elixir): Refactor and fix image
davidkornel ecfdaff
docs(jitsi): Refactor once more
davidkornel b3cc45e
docs(mediasoup): Refactor once more
davidkornel 3e20945
docs(neko): Refactor
davidkornel 32b9cc2
docs(TLS): Reword ingress desc
davidkornel 82df6bb
docs(examples): Reword prerequisites
davidkornel c68a491
doc(examples/simple-tunnel): Fix turncat links
levaitamas 0634024
docs(install): Add skip crd install section
davidkornel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|
||
```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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
> [!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). |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.