# EduCDN

EduCDN is a content delivery network on a smaller scale, that helps (CN2) students understand how such a network operates. A CDN is used by tech companies to distribute their services (streaming, hosting etc.) across the globe. It was developed by Ramon Bister & Roman Weber during the Distributed Systems course.

## Architecture

This describes the EduCDN setup with two locations.

![Architecture overview](assets/img/architecture-multi_location.drawio.svg)

### Components

The following describes the different components. At least one of each runs in docker containers per location. For a more detailed description, check the presentation slides under `assets/presentation`.

- **Frontend**: User frontend that shows CDN events.
- **Backend**: Written in GO, where all the magic of EduCDN happens.
- **[Treafik](https://github.com/traefik/traefik)**: Reverse proxy that load balances requests to ideal docker container.
- **[Minio](https://github.com/minio/minio)**: S3 based storage system that replicates content across sites.
- **[NSQ](https://github.com/nsqio/nsq)**: Distributed messaging platform used to send events to all frontends.
- **DNS**: DNS server that resolves nzz.ch (and others) to CDN and not to the official website.

## Run edudcn

This part explains how to run EduCDN. If this is the first time using EduCDN, start with the first part. It includes steps that need to be set up one-time. If you are restarting EduCDN, continue with the second part.

### First part: Initial setup

The setup requires a working [docker installation](https://docs.docker.com/engine/install/).

#### Prepare env File

- Create or open the file `deployment/.env`.
- Declare the two environment variables `MINIO_ROOT_USER` and `MINIO_ROOT_PASSWORD` and set them to an arbitrary value.

The `.env` file may now look like the following:

```text
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=password
```

#### Certification setup

In order to access the websites via https, a self-signed certificate is used. During the first setup, run the command `make create-ca`. This will create certificates in the folder `deployment/certs`.

For a smooth user experience, this certificate must be added in the browser. For security reasons, consider creating a new browser profile. Adding the certificate will work in all browsers, but here it is only shown in Firefox. Head to [about:settings#privacy](about:settings#privacy) > View Certificates > Import... > and import `deployment/certs/ca.crt`.

!["Firefox add certificate"](assets/img/firefox-add-certificate.png)

#### Make configure-storage

This step should only be executed once per setup on an arbitrary location. Make sure to wait until storage configuration until EduCDN is started on all locations. **Only come back to this after completing the second part** !

In order to configure the storage units properly, run `make configure-storage`. Otherwise, access keys are missing and files can't be cached. This is the error message when configure-storage hasn't been run.

!["Access Key Id"](assets/img/access-key-not-set.png)

### Second part: Continued setup

We are almost ready to run EduCDN.

#### Build docker

Use `make build-docker` in the root of this project to compile the GO code and build the docker image. This requires an installation of GO.

Alternatively, pull the newest docker image from the OST GitLab server by changing the container Image variable in the Makefile to `# CONTAINER_IMAGE=registry.gitlab.ost.ch:45023/ramon.bister/educdn:latest`.

#### Prepare config.yaml

Still in the folder deployment, the `config.yaml` specifies how many instances will be started. It is divided into three components:

- **Global**: Variables/settings that are the same across all regions.
- **Local**: Relevant within the region (eg. eu-zrh). Change name and region if needed. Further, specify the number of containers to be started.
- **Remote**: Needed for the storage replication and NSQ setup. Must contain name and IP address of the other regions.

Look up the IP of your device (on Linux `ip -br addr`) and add it as the local address in `deployment/config.yaml`. The snippet of `config.yaml` is supposed to look like this.

```yaml
local:
  name: zrh
  region: eu
  address: <YOUR IP GOES HERE>
  dns:
    forwarder: 1.1.1.1
```

If you are running the setup on multiple computers, repeat the step above for each device. Then specify the **name, IP of the other locations and number of storage replicas** under remote. This is needed for the NSQ and storage services to find the other sites correctly.

```yaml
remote:
  - name: tok
    region: jp
    address: <IP OF DEVICE1>
    storage:
      replicas: 1
  - name: atl
    region: us
    address: <IP OF DEVICE2>
    storage:
      replicas: 1

```

Under `assets/example-config` there are example configuration for a three location setup. Adjust the YAML files to your needs!

#### Set local DNS

There are three possible DNS options. This is needed for the client to use the DNS container, which forwards to `dashboard.educdn.net`. 

In case `dig dashboard.educdn.net` doesn't return the device's IP, turn the network interface off and on.

Here is how to do it on Linux.

!["Set DNS on Linux"](assets/img/set-dns-on-linux.png)

##### 127.0.0.1 / localhost

The option used most often, use this if EduCDN is running on the local device. Set the local DNS to `127.0.0.1` as shown in the screenshot above.

##### Unicast IP of local IP

If EduCDN is running on a different host, set the IP of the location you want to connect to.

##### Anycast IP

The last option is to enable anycast, which can be done setting in to true `config.yaml`. The DNS to set on the network interface in this case is `7.7.7.7`.

```yaml
global:
  anycast:
    enabled: true
    address: 7.7.7.7
```

#### Start EduCDN

Now it is finally time to start the EduCDN by running `make run-docker`.

#### Other make targets

A CDN location can be deployed using dedicated targets in the `Makefile`.

- `build-docker`: Builds the `educdn` container image
- `run-docker`: Calls `build-docker` and bootstraps CDN location(s)
- `stop-docker`: Stops the CDN location(s)
- `clean-docker`: Calls `clean-docker` and removes **all** docker volumes

### Further information

Information that might be helpful for troubleshooting.

#### Links to access components

In order to access different components of EduCDN, use the following links.

- **Frontend**: [dashboard.educdn.net](dashboard.educdn.net)
- **Storage/MinIO**: [localhost:9000](localhost:9000)
- **Traefik**: [localhost:8080](localhost:8080)

#### Pull repo and docker image

On the PCs in the network lab, the docker image or the repository might not be up-to-date. Thus make sure to pull the newest repository from main and use the newest image.

1. `make stop-docker`
2. `docker image rm registry.gitlab(....)educdn:latest --force`
3. `make run-docker`

If the docker image can't be found, you'll most likely need to change your DNS back to automatic.

#### Browser profile on lab PCs

The computer in the network lab do already have a Firefox profile called EduCDN, where the certificate is already added. To use the profile, go to [about:profiles](about:profiles) and click `Launch profile in new browser`.

#### Add more storage units

While adding new frontend and backends can be added to the `config.yaml` when EduCDN is already running (`make stop-docker && make run-docker`), this isn't possible for storage units. There you need to run `make clean-docker && make run-docker` and then `make configure-storage`.
