# An Introduction to Service Mesh ## A simple Web UI: videos-web

Consider `videos-web`
It's an HTML application that lists a bunch of playlists with videos in them. ``` +------------+ | videos-web | | | +------------+ ```
## A simple API: playlists-api

For `videos-web` to get any content, it needs to make a call to `playlists-api` ``` +------------+ +---------------+ | videos-web +---->+ playlists-api | | | | | +------------+ +---------------+ ``` Playlists consist of data like `title`, `description` etc, and a list of `videos`.
Playlists are stored in a database.
`playlists-api` stores its data in a database ``` +------------+ +---------------+ +--------------+ | videos-web +---->+ playlists-api +--->+ playlists-db | | | | | | | +------------+ +---------------+ +--------------+ ```
## A little complexity

Each playlist item contains only a list of video id's.
A playlist does not have the full metadata of each video.
Example `playlist`: ``` { "id" : "playlist-01", "title": "Cool playlist", "videos" : [ "video-1", "video-x" , "video-b"] } ``` Take not above `videos: []` is a list of video id's
Videos have their own `title` and `description` and other metadata.
To get this data, we need a `videos-api`
This `videos-api` has its own database too
``` +------------+ +-----------+ | videos-api +------>+ videos-db | | | | | +------------+ +-----------+ ``` For the `playlists-api` to load all the video data, it needs to call `videos-api` for each video ID it has.

## Traffic flow

A single `GET` request to the `playlists-api` will get all the playlists from its database with a single DB call
For every playlist and every video in each list, a separate `GET` call will be made to the `videos-api` which will retrieve the video metadata from its database.
This will result in many network fanouts between `playlists-api` and `videos-api` and many call to its database.
This is intentional to demonstrate a busy network.
## Full application architecture

``` +------------+ +---------------+ +--------------+ | videos-web +---->+ playlists-api +--->+ playlists-db | | | | | | | +------------+ +-----+---------+ +--------------+ | v +-----+------+ +-----------+ | videos-api +------>+ videos-db | | | | | +------------+ +-----------+ ``` ## Adding an Ingress Controller Adding an ingress controller allows us to route all our traffic.
We setup a `host` file with entry `127.0.0.1 servicemesh.demo` And `port-forward` to the `ingress-controller` ``` servicemesh.demo/home --> videos-web servicemesh.demo/api/playlists --> playlists-api servicemesh.demo/home +--------------+ +------------------------------> | videos-web | | | | servicemesh.demo/home +------+------------+ +--------------+ +------------------>+ingress-nginx | |Ingress controller | +------+------------+ +---------------+ +--------------+ | | playlists-api +--->+ playlists-db | +------------------------------> | | | | servicemesh.demo/api/playlists +-----+---------+ +--------------+ | v +-----+------+ +-----------+ | videos-api +------>+ videos-db | | | | | +------------+ +-----------+ ```
## Run the apps: Docker

There is a `docker-compose.yaml` in this directory.
Change your terminal to this folder and run: ``` docker-compose build docker-compose up ``` You can access the app on `http://localhost`
## Run the apps: Kubernetes

Create a cluster with [kind](https://kind.sigs.k8s.io/docs/user/quick-start/) ``` kind create cluster --name servicemesh --image kindest/node:v1.18.4 ```
### Deploy videos-web

``` cd ./kubernetes/servicemesh/ kubectl apply -f applications/videos-web/deploy.yaml kubectl port-forward svc/videos-web 80:80 ``` You should see blank page at `http://localhost/`
It's blank because it needs the `playlists-api` to get data
### Deploy playlists-api and database

``` cd ./kubernetes/servicemesh/ kubectl apply -f applications/playlists-api/deploy.yaml kubectl apply -f applications/playlists-db/ kubectl port-forward svc/playlists-api 81:80 ``` You should see empty playlists page at `http://localhost/`
Playlists are empty because it needs the `videos-api` to get video data

### Deploy videos-api and database

``` cd ./kubernetes/servicemesh/ kubectl apply -f applications/videos-api/deploy.yaml kubectl apply -f applications/videos-db/ ``` Refresh page at `http://localhost/`
You should now see the complete architecture in the browser