# 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