diff --git a/kubernetes/servicemesh/introduction.md b/kubernetes/servicemesh/introduction.md new file mode 100644 index 0000000..1c7fbe3 --- /dev/null +++ b/kubernetes/servicemesh/introduction.md @@ -0,0 +1,189 @@ +# 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 architecture +
+
+ +``` + ++------------+ +---------------+ +--------------+ +| videos-web +---->+ playlists-api +--->+ playlists-db | +| | | | | | ++------------+ +-----+---------+ +--------------+ + | + 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 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 + +``` + +Refresh page at `http://localhost/`
+You should now see the complete architecture in the browser
\ No newline at end of file diff --git a/kubernetes/servicemesh/linkerd/readme.md b/kubernetes/servicemesh/linkerd/readme.md new file mode 100644 index 0000000..01b4014 --- /dev/null +++ b/kubernetes/servicemesh/linkerd/readme.md @@ -0,0 +1,116 @@ +# Introduction to Linkerd + +## Kubernetes + +Lets create a Kubernetes cluster to play with using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/) + +``` +kind create cluster --name linkerd --image kindest/node:v1.18.4 +``` + +## Get a container to work in + +``` +docker run -it --rm -v ${HOME}:/root/ -v ${PWD}:/work -w /work --net host alpine sh + +# install curl & kubectl +apk add --no-cache curl +curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl +chmod +x ./kubectl +mv ./kubectl /usr/local/bin/kubectl + +#test cluster access: +/work # kubectl get nodes +NAME STATUS ROLES AGE VERSION +linkerd-control-plane Ready master 26m v1.18.4 + +``` + +## Linkerd CLI + +Lets download the `linkerd` command line tool
+I grabbed the `edge-20.9.4` release using `curl` + +You can go to the [releases](https://github.com/linkerd/linkerd2/releases/tag/edge-20.9.4) page to get it + +``` +curl -L -o linkerd https://github.com/linkerd/linkerd2/releases/download/edge-20.9.4/linkerd2-cli-edge-20.9.4-linux-amd64 +chmod +x linkerd && mv ./linkerd /usr/local/bin/ + +linkerd --help +``` + +## Pre flight checks + +Linkerd has a great capability to check compatibility with the target cluster
+ +``` +linkerd check --pre + +``` + +## Get the YAML + +``` +linkerd install > ./kubernetes/servicemesh/linkerd/manifest/linkerd-edge-20.9.4.yaml +``` + +## Install Linkerd + +``` +kubectl apply -f ./kubernetes/servicemesh/linkerd/manifest/linkerd-edge-20.9.4.yaml +``` + +Let's wait until all components are running + +``` +kubectl -n linkerd get deploy +kubectl -n linkerd get svc +``` + +# Grafana + +``` +kubectl -n linkerd port-forward svc/linkerd-grafana 3000 + +``` + +## Deploy example microservices (Video catalogue) + +``` +kubectl apply -f kubernetes/servicemesh/applications/playlists-api/ +kubectl apply -f kubernetes/servicemesh/applications/videos-api/ +kubectl apply -f kubernetes/servicemesh/applications/videos-web/ +``` + +``` +kubectl port-forward svc/playlists-api 81:80 +kubectl port-forward svc/videos-web 80 +kubectl -n ingress-nginx port-forward deploy/nginx-ingress-controller 80 +``` + +# Mesh our video catalog services + +``` +kubectl get deploy +NAME READY UP-TO-DATE AVAILABLE AGE +playlists-api 1/1 1 1 8h +playlists-db 1/1 1 1 8h +videos-api 1/1 1 1 8h +videos-db 1/1 1 1 8h +videos-web 1/1 1 1 8h + +kubectl get deploy playlists-api -o yaml | linkerd inject - | kubectl apply -f - +kubectl get deploy playlists-db -o yaml | linkerd inject - | kubectl apply -f - +kubectl get deploy videos-api -o yaml | linkerd inject - | kubectl apply -f - +kubectl get deploy videos-db -o yaml | linkerd inject - | kubectl apply -f - +kubectl get deploy videos-web -o yaml | linkerd inject - | kubectl apply -f - + + +linkerd -n default check --proxy + +linkerd -n default stat deploy + +``` + + diff --git a/kubernetes/servicemesh/readme.md b/kubernetes/servicemesh/readme.md index 2384be7..18241fe 100644 --- a/kubernetes/servicemesh/readme.md +++ b/kubernetes/servicemesh/readme.md @@ -4,190 +4,10 @@ To understand service mesh, we need a good use case.
We need some service-to-service communication.
A basic microservice architecture will do.
-## A simple Web UI: videos-web -
-
+[The Introduction Guide](./introduction.md) -Consider `videos-web`
-It's an HTML application that lists a bunch of playlists with videos in them. +# Service Mesh Guides -``` -+------------+ -| videos-web | -| | -+------------+ -``` -
+## Introduction to Linkerd -## 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 architecture -
-
- -``` - -+------------+ +---------------+ +--------------+ -| videos-web +---->+ playlists-api +--->+ playlists-db | -| | | | | | -+------------+ +-----+---------+ +--------------+ - | - 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 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 - -``` - -Refresh page at `http://localhost/`
-You should now see the complete architecture in the browser
\ No newline at end of file +Getting started with [linkerd](./linkerd/readme.md) \ No newline at end of file