Building a VoIP Network with Routr on DigitalOcean Kubernetes: Part I
Tags: routr, voip, kubernetes, sip
Published: 2024-03-04 12:43:15

Building a VoIP Network with Routr on DigitalOcean Kubernetes: Part I

Routr v2 takes a radical design approach by being container-first and taking full advantage of environments like Kubernetes. In this three-part tutorial, you will learn how to:

- Create a load balancer on DOKS and deploy Routr
- Secure the admin and signaling ports with Let's Encrypt
- Prepare the network for production

Before you continue, be sure to star Routr on GitHub 👇

{% github fonoster/routr no-readme %}

## Requirements

Before you start this tutorial, you will need the following:

- An account in DigitalOcean and a DOKS cluster
- NodeJS >= 18 (Use nvm if possible)
- Routr command-line tool (Install it with `npm install -g @routr/ctl`)
- Kubectl with access to your DOKS cluster
- Helm (Get from here https://helm.sh/)

## Check the DOKS cluster and other dependencies

This tutorial assumes you have a running DOKS cluster. If you need help creating a DOKS creating, please visit the following link: https://docs.digitalocean.com/products/kubernetes/how-to/create-clusters/

With that, ensure you can connect to your cluster using Kubectl before continuing with the next steps.

## Creating a new Load Balancer in Digital Ocean

To create a new load balancer, go to the networking section within the DigitalOcean panel, find the "Load Balancers" tab, and click "Create Load Balancer."

Your page will look like this:

![Load Balancers Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wclt4swy9bx84agevie.png)

Follow the creation steps using all the default values and note the load balancer's name.

## Installing Routr using Helm

Once your load balancer is up and running, follow the next instructions to install Routr with Helm.

First, add Routr to the Helm repository with:

```bash
helm repo add routr https://routr.io/charts
helm repo update
```

You can get details about the new repo with the following:

```bash
helm repo list
```

Then, create a namespace for Routr using the create namespace subcommand:

```bash
kubectl create namespace routr
```

Next, create a `values.yaml` with the following content find, and remember to replace the externalAddrs property and serviceAnnotationsTCP with your values.

Filename: _values.yaml_

```yaml
edgeport:
  externalAddrs: ["159.203.158.25"]
  serviceTypeTCP: LoadBalancer
  serviceAnnotationsTCP:
    service.beta.kubernetes.io/do-loadbalancer-name: "nyc1-load-balancer-01"
  transport:
    tcp:
      enabled: true
```

Alternatively, you could use the annotation `kubernetes.digitalocean.com/load-balancer-id` to use the load balancer's ID instead of the name.

Finally, create the SIP network with:

```bash
helm install sipnet routr/routr-connect --namespace routr -f values.yaml
```

Within a few minutes, you will see the following message:

![Succesful deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrnr1r4t9yogqogiwake.png)

You can check the status of the Pods with the "get pods" subcommand, like here:

```bash
kubectl get pods -n routr
```

You should see a list of pods and their status. If the status of all services is "Running," you are ready to go.

![PODs status](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ko9h0ux51d154tpax2s6.png)

Please see the [Official Chart](https://github.com/fonoster/routr/blob/main/ops/charts/connect/README.md) for many more options for your deployment.

## Configuring a Domain, Credentials, and Agents in Routr

With Routr deployed, the next step will be to create the following resources:

- The "sip.local" domain
- Two sets of credentials (e.g., 1001 and 1002)
- Two SIP agents (e.g., John and Jane)

To send admin commands to Routr, you must expose the admin port.

Here, for simplicity, we will use `port-forward` to expose the admin port. However, you might use a different method in production, like creating a separate load balancer.

To open the admin port, first list the services of your deployment and find the one for your admin port with the following:

```bash
kubectl get services -n routr
```

Then, open the admin using the port-forward subcommand:

```bash
kubectl port-forward svc/sipnet-routr-apiserver 51907 -n routr
```

Once the port is open, on a separate screen, begin creating a Domain with:

```bash
rctl domains create --insecure --endpoint=localhost:51907
```

Your output will look as follows:

```
Press ^C at any time to quit.
 ›   Warning: Egress rules unavailable due to 0 configured numbers.
? Friendly Name Local Domain
? SIP URI sip.local
? IP Access Control List None
? Ready? Yes
Creating Domain Local Domain... 3b20410a-3c80-4f66-b7b3-58f65ff65352
```

In the next part of the series, I will go over securing the connection with a self-signed certificate or using certificates from Let's Encrypt.

Continue by creating two sets of credentials with the following command:

```bash
rctl credentials create --insecure --endpoint=localhost:51907
```

Follow the prompt and repeat to create two sets (e.g., 1001 and 1002). Your output for the first credential will look like this:

```
This utility will help you create a new set of Credentials.
Press ^C at any time to quit.
? Friendly Name John Doe - Credentials
? Username 1001
? Password [hidden]
? Ready? Yes
Creating Credentials John Doe - Credentials... 5fbc7367-a59d-4555-9fc4-a15ff29c24c8
```

Finally, create two sets of Agents:

```bash
rctl agents create --insecure --endpoint=localhost:51907
```

The output for your first Agent will look like this:

```
This utility will help you create a new Agent.
Press ^C at any time to quit.
? Friendly Name John Doe
? Select a Domain sip.local
? Username 1001
? Credentials Name John Doe - Credentials
? Max Contacts
? Privacy None
? Enabled? Yes
? Ready? Yes
Creating Agent John Doe... 662a379d-66f1-4e6e-9df5-5126f1dcb930
```

Please repeat the process for Jane.

## Registering and Calling using Blink

Using Blink or your preferred softphone, create a new agent using the parameters in the abovementioned steps.

The result should show a green indicator like in the screenshot below.

![Registering Blink](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgcxqzjut3q7g0yf2yzz.png)

Repeat the process from another instance of Blink, and make a call going to the main screen and typing the extension.

![Calling the extension 1002](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il71x7byty7g4u323mk5.png)

You should be able to send and receive calls from both devices.

## What's next

Thank you for making it this far. In the upcoming days, I will publish Part II of this series, which will go over securing the signaling path and the admin port. In the meantime, feel free to enjoy the following tutorials:

- [Building scalable IVRs for businesses with Routr and Asterisk](https://dev.to/fonoster/building-scalable-ivrs-for-businesses-with-routr-and-asterisk-cjd)
- [Browser-to-Browser calling with SIP.js and Routr](https://dev.to/fonoster/browser-to-browser-calling-with-sipjs-and-routr-3l07)
- [Simplify SIP.js security with short-lived tokens](https://dev.to/psanders/simplify-sipjs-security-with-short-lived-tokens-mb8)