2020-04-23 21:12:30 +00:00
< p align = "center" >
< img src = "src/frontend/static/icons/Hipster_HeroLogoCyan.svg" width = "300" / >
< / p >
2018-07-02 17:24:11 +00:00
2020-04-23 21:12:30 +00:00
**Online Boutique** is a cloud-native microservices demo application.
Online Boutique consists of a 10-tier microservices application. The application is a
web-based e-commerce app where users can browse items,
2018-07-02 17:24:11 +00:00
add them to the cart, and purchase them.
2019-02-14 17:37:08 +00:00
**Google uses this application to demonstrate use of technologies like
2019-02-14 17:49:46 +00:00
Kubernetes/GKE, Istio, Stackdriver, gRPC and OpenCensus**. This application
works on any Kubernetes cluster (such as a local one), as well as Google
Kubernetes Engine. It’ s **easy to deploy with little to no configuration** .
2018-07-26 04:17:04 +00:00
2019-02-14 17:37:08 +00:00
If you’ re using this demo, please ** ★Star** this repository to show your interest!
> 👓**Note to Googlers:** Please fill out the form at
2019-02-20 22:34:12 +00:00
> [go/microservices-demo](http://go/microservices-demo) if you are using this
> application.
2019-01-14 22:42:13 +00:00
2020-04-23 21:12:30 +00:00
Looking for the old Hipster Shop frontend interface? Use the [manifests ](https://github.com/GoogleCloudPlatform/microservices-demo/tree/v0.1.4/kubernetes-manifests ) in release [v0.1.4 ](https://github.com/GoogleCloudPlatform/microservices-demo/releases/v0.1.4 ).
2018-08-13 18:23:42 +00:00
## Screenshots
2019-02-20 22:34:12 +00:00
| Home Page | Checkout Screen |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
2020-04-23 21:12:30 +00:00
| [![Screenshot of store homepage ](./docs/img/online-boutique-frontend-1.png )](./docs/img/online-boutique-frontend-1.png) | [![Screenshot of checkout screen ](./docs/img/online-boutique-frontend-2.png )](./docs/img/online-boutique-frontend-2.png) |
2018-08-13 18:23:42 +00:00
## Service Architecture
2020-04-23 21:12:30 +00:00
**Online Boutique** is composed of many microservices written in different
2018-08-13 18:23:42 +00:00
languages that talk to each other over gRPC.
[![Architecture of
2019-01-02 21:34:01 +00:00
microservices](./docs/img/architecture-diagram.png)](./docs/img/architecture-diagram.png)
2018-08-13 18:23:42 +00:00
Find **Protocol Buffers Descriptions** at the [`./pb` directory ](./pb ).
2019-02-20 22:34:12 +00:00
| Service | Language | Description |
| ---------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| [frontend ](./src/frontend ) | Go | Exposes an HTTP server to serve the website. Does not require signup/login and generates session IDs for all users automatically. |
2019-11-01 15:39:30 +00:00
| [cartservice ](./src/cartservice ) | C# | Stores the items in the user's shopping cart in Redis and retrieves it. |
2019-02-20 22:34:12 +00:00
| [productcatalogservice ](./src/productcatalogservice ) | Go | Provides the list of products from a JSON file and ability to search products and get individual products. |
| [currencyservice ](./src/currencyservice ) | Node.js | Converts one money amount to another currency. Uses real values fetched from European Central Bank. It's the highest QPS service. |
| [paymentservice ](./src/paymentservice ) | Node.js | Charges the given credit card info (mock) with the given amount and returns a transaction ID. |
| [shippingservice ](./src/shippingservice ) | Go | Gives shipping cost estimates based on the shopping cart. Ships items to the given address (mock) |
| [emailservice ](./src/emailservice ) | Python | Sends users an order confirmation email (mock). |
| [checkoutservice ](./src/checkoutservice ) | Go | Retrieves user cart, prepares order and orchestrates the payment, shipping and the email notification. |
| [recommendationservice ](./src/recommendationservice ) | Python | Recommends other products based on what's given in the cart. |
| [adservice ](./src/adservice ) | Java | Provides text ads based on given context words. |
| [loadgenerator ](./src/loadgenerator ) | Python/Locust | Continuously sends requests imitating realistic user shopping flows to the frontend. |
2018-08-13 18:23:42 +00:00
## Features
- **[Kubernetes](https://kubernetes.io)/[GKE](https://cloud.google.com/kubernetes-engine/):**
The app is designed to run on Kubernetes (both locally on "Docker for
Desktop", as well as on the cloud with GKE).
- **[gRPC](https://grpc.io):** Microservices use a high volume of gRPC calls to
communicate to each other.
- **[Istio](https://istio.io):** Application works on Istio service mesh.
- **[OpenCensus](https://opencensus.io/) Tracing:** Most services are
instrumented using OpenCensus trace interceptors for gRPC/HTTP.
- **[Stackdriver APM](https://cloud.google.com/stackdriver/):** Many services
are instrumented with **Profiling** , **Tracing** and **Debugging** . In
addition to these, using Istio enables features like Request/Response
**Metrics** and **Context Graph** out of the box. When it is running out of
Google Cloud, this code path remains inactive.
2019-04-17 16:00:38 +00:00
- **[Skaffold](https://skaffold.dev):** Application
2018-08-13 18:23:42 +00:00
is deployed to Kubernetes with a single command using Skaffold.
- **Synthetic Load Generation:** The application demo comes with a background
job that creates realistic usage patterns on the website using
[Locust ](https://locust.io/ ) load generator.
## Installation
2020-02-15 00:47:18 +00:00
We offer the following installation methods:
2019-02-20 19:07:37 +00:00
2020-02-15 00:47:18 +00:00
1. **Running locally** (~20 minutes) You will build
2019-02-20 19:07:37 +00:00
and deploy microservices images to a single-node Kubernetes cluster running
2020-04-15 01:04:09 +00:00
on your development machine. There are three options to run a Kubernetes
2020-02-15 00:47:18 +00:00
cluster locally for this demo:
2020-04-15 01:04:09 +00:00
- [Minikube ](https://github.com/kubernetes/minikube ). Recommended for
2020-02-15 00:47:18 +00:00
Linux hosts (also supports Mac/Windows).
- [Docker for Desktop ](https://www.docker.com/products/docker-desktop ).
Recommended for Mac/Windows.
2020-04-15 01:04:09 +00:00
- [Kind ](https://www.docker.com/products/docker-desktop ). Supports Mac/Windows/Linux.
2020-02-15 00:47:18 +00:00
1. **Running on Google Kubernetes Engine (GKE)”** (~30 minutes) You will build,
2019-02-20 19:07:37 +00:00
upload and deploy the container images to a Kubernetes cluster on Google
Cloud.
2020-02-15 00:47:18 +00:00
1. **Using pre-built container images:** (~10 minutes, you will still need to
2019-02-20 19:07:37 +00:00
follow one of the steps above up until `skaffold run` command). With this
option, you will use pre-built container images that are available publicly,
instead of building them yourself, which takes a long time).
2020-02-15 00:47:18 +00:00
### Option 1: Running locally
2018-08-13 18:23:42 +00:00
2019-02-20 19:07:37 +00:00
> 💡 Recommended if you're planning to develop the application or giving it a
> try on your local cluster.
2018-07-02 17:24:11 +00:00
2018-07-26 04:17:04 +00:00
1. Install tools to run a Kubernetes cluster locally:
2018-07-02 18:03:55 +00:00
- kubectl (can be installed via `gcloud components install kubectl` )
2020-02-15 00:47:18 +00:00
- Local Kubernetes cluster deployment tool:
- [Minikube (recommended for
2020-04-15 01:04:09 +00:00
Linux)](https://kubernetes.io/docs/setup/minikube/)
- [Docker for Desktop (recommended for Mac/Windows) ](https://www.docker.com/products/docker-desktop )
- It provides Kubernetes support as [noted
here](https://docs.docker.com/docker-for-mac/kubernetes/)
- [Kind ](https://github.com/kubernetes-sigs/kind )
2019-11-04 18:06:03 +00:00
- [skaffold ]( https://skaffold.dev/docs/install/ ) (ensure version ≥v0.20)
2018-07-11 02:47:24 +00:00
2020-02-15 00:47:18 +00:00
1. Launch the local Kubernetes cluster with one of the following tools:
2020-04-15 01:04:09 +00:00
- To launch **Minikube** (tested with Ubuntu Linux). Please, ensure that the
2020-02-15 00:47:18 +00:00
local Kubernetes cluster has at least:
- 4 CPU's
- 4.0 GiB memory
2019-02-20 22:34:12 +00:00
2020-04-15 01:04:09 +00:00
```shell
minikube start --cpus=4 --memory 4096
```
2020-02-15 00:47:18 +00:00
2020-04-15 01:04:09 +00:00
- To launch **Docker for Desktop** (tested with Mac/Windows). Go to Preferences:
2020-02-15 00:47:18 +00:00
- choose “Enable Kubernetes”,
- set CPUs to at least 3, and Memory to at least 6.0 GiB
- on the "Disk" tab, set at least 32 GB disk space
2018-07-11 02:47:24 +00:00
2020-04-15 01:04:09 +00:00
- To launch a **Kind** cluster:
```shell
kind create cluster
```
2019-02-20 22:34:12 +00:00
1. Run `kubectl get nodes` to verify you're connected to “Kubernetes on Docker”.
2018-07-11 02:47:24 +00:00
2019-02-20 22:34:12 +00:00
1. Run `skaffold run` (first time will be slow, it can take ~20 minutes).
2018-08-09 21:40:43 +00:00
This will build and deploy the application. If you need to rebuild the images
2019-02-15 22:48:20 +00:00
automatically as you refactor the code, run `skaffold dev` command.
2018-07-11 02:47:24 +00:00
2020-04-15 01:04:09 +00:00
1. Run `kubectl get pods` to verify the Pods are ready and running.
1. Access the web frontend through your browser
- **Minikube** requires you to run a command to access the frontend service:
```shell
minikube service frontend-external
```
- **Docker For Desktop** should automatically provide the frontend at http://localhost:80
- **Kind** does not provision an IP address for the service.
You must run a port-forwarding process to access the frontend at http://localhost:8080:
```shell
kubectl port-forward deployment/frontend 8080:8080
```
2018-07-11 02:47:24 +00:00
2018-08-13 18:23:42 +00:00
### Option 2: Running on Google Kubernetes Engine (GKE)
2019-02-20 19:07:37 +00:00
> 💡 Recommended if you're using Google Cloud Platform and want to try it on
> a realistic cluster.
2018-07-11 02:47:24 +00:00
2019-02-20 22:34:12 +00:00
1. Install tools specified in the previous section (Docker, kubectl, skaffold)
2018-07-02 18:03:55 +00:00
2019-02-20 22:34:12 +00:00
1. Create a Google Kubernetes Engine cluster and make sure `kubectl` is pointing
to the cluster.
2018-07-02 18:03:55 +00:00
2019-02-20 22:34:12 +00:00
```sh
gcloud services enable container.googleapis.com
```
2018-07-02 17:24:11 +00:00
2019-02-20 22:34:12 +00:00
```sh
gcloud container clusters create demo --enable-autoupgrade \
--enable-autoscaling --min-nodes=3 --max-nodes=10 --num-nodes=5 --zone=us-central1-a
```
2018-08-16 19:49:17 +00:00
2019-02-20 22:34:12 +00:00
```
kubectl get nodes
```
2018-08-13 18:23:42 +00:00
2019-02-20 22:34:12 +00:00
1. Enable Google Container Registry (GCR) on your GCP project and configure the
`docker` CLI to authenticate to GCR:
2018-08-16 19:49:17 +00:00
2019-02-20 22:34:12 +00:00
```sh
gcloud services enable containerregistry.googleapis.com
```
2018-07-02 18:03:55 +00:00
2019-02-20 22:34:12 +00:00
```sh
gcloud auth configure-docker -q
```
2018-07-02 17:24:11 +00:00
2019-02-20 22:34:12 +00:00
1. In the root of this repository, run `skaffold run --default-repo=gcr.io/[PROJECT_ID]` ,
where [PROJECT_ID] is your GCP project ID.
2019-01-15 18:14:33 +00:00
2019-02-20 22:34:12 +00:00
This command:
2019-02-20 19:07:37 +00:00
2019-02-20 22:34:12 +00:00
- builds the container images
- pushes them to GCR
- applies the `./kubernetes-manifests` deploying the application to
Kubernetes.
2018-07-02 17:24:11 +00:00
2019-02-20 22:34:12 +00:00
**Troubleshooting:** If you get "No space left on device" error on Google
Cloud Shell, you can build the images on Google Cloud Build: [Enable the
Cloud Build
API](https://console.cloud.google.com/flows/enableapi?apiid=cloudbuild.googleapis.com),
then run `skaffold run -p gcb --default-repo=gcr.io/[PROJECT_ID]` instead.
2018-11-07 22:52:31 +00:00
2018-12-03 22:19:12 +00:00
1. Find the IP address of your application, then visit the application on your
2018-08-13 18:23:42 +00:00
browser to confirm installation.
2018-07-02 17:24:11 +00:00
kubectl get service frontend-external
2018-11-07 22:52:31 +00:00
**Troubleshooting:** A Kubernetes bug (will be fixed in 1.12) combined with
a Skaffold [bug ](https://github.com/GoogleContainerTools/skaffold/issues/887 )
causes load balancer to not to work even after getting an IP address. If you
are seeing this, run `kubectl get service frontend-external -o=yaml | kubectl apply -f-`
to trigger load balancer reconfiguration.
2019-02-20 19:07:37 +00:00
### Option 3: Using Pre-Built Container Images
2019-01-29 19:23:33 +00:00
2019-02-20 19:07:37 +00:00
> 💡 Recommended if you want to deploy the app faster in fewer steps to an
> existing cluster.
2019-01-29 19:23:33 +00:00
2019-02-20 19:07:37 +00:00
**NOTE:** If you need to create a Kubernetes cluster locally or on the cloud,
follow "Option 1" or "Option 2" until you reach the `skaffold run` step.
2019-01-29 19:23:33 +00:00
2019-02-20 19:07:37 +00:00
This option offers you pre-built public container images that are easy to deploy
by deploying the [release manifest ](./release ) directly to an existing cluster.
**Prerequisite**: a running Kubernetes cluster (either local or on cloud).
1. Clone this repository, and go to the repository directory
2019-02-22 17:55:40 +00:00
1. Run `kubectl apply -f ./release/kubernetes-manifests.yaml` to deploy the app.
2019-02-20 19:07:37 +00:00
1. Run `kubectl get pods` to see pods are in a Ready state.
1. Find the IP address of your application, then visit the application on your
2019-02-20 22:34:12 +00:00
browser to confirm installation.
2019-02-20 19:07:37 +00:00
2019-02-20 22:34:12 +00:00
```sh
kubectl get service/frontend-external
```
2019-01-29 19:23:33 +00:00
2019-01-15 18:14:33 +00:00
### (Optional) Deploying on a Istio-installed GKE cluster
2018-07-08 00:14:52 +00:00
2018-08-16 19:49:17 +00:00
> **Note:** you followed GKE deployment steps above, run `skaffold delete` first
> to delete what's deployed.
2018-07-08 00:14:52 +00:00
2019-02-20 19:07:37 +00:00
1. Create a GKE cluster (described in "Option 2").
2019-01-15 18:14:33 +00:00
2019-02-20 22:34:12 +00:00
1. Use [Istio on GKE add-on ](https://cloud.google.com/istio/docs/istio-on-gke/installing )
2019-01-15 18:14:33 +00:00
to install Istio to your existing GKE cluster.
2018-07-08 00:14:52 +00:00
2019-02-20 22:34:12 +00:00
```sh
gcloud beta container clusters update demo \
--zone=us-central1-a \
--update-addons=Istio=ENABLED \
--istio-config=auth=MTLS_PERMISSIVE
```
2018-10-09 18:50:14 +00:00
2019-12-16 14:30:23 +00:00
2. (Optional) Enable Stackdriver Tracing/Logging with Istio Stackdriver Adapter
2019-01-15 18:14:33 +00:00
by [following this guide ](https://cloud.google.com/istio/docs/istio-on-gke/installing#enabling_tracing_and_logging ).
2019-12-16 14:30:23 +00:00
3. Install the automatic sidecar injection (annotate the `default` namespace
2018-07-08 00:14:52 +00:00
with the label):
2019-02-20 22:34:12 +00:00
```sh
kubectl label namespace default istio-injection=enabled
```
2018-07-08 00:14:52 +00:00
2019-12-16 14:30:23 +00:00
4. Apply the manifests in [`./istio-manifests` ](./istio-manifests ) directory.
2019-02-20 22:34:12 +00:00
(This is required only once.)
2018-07-26 04:17:04 +00:00
2019-02-20 22:34:12 +00:00
```sh
kubectl apply -f ./istio-manifests
```
2018-08-13 18:23:42 +00:00
2020-04-08 23:28:28 +00:00
5. In the root of this repository, run `skaffold run --default-repo=gcr.io/[PROJECT_ID]` ,
where [PROJECT_ID] is your GCP project ID.
This command:
- builds the container images
- pushes them to GCR
- applies the `./kubernetes-manifests` deploying the application to
Kubernetes.
**Troubleshooting:** If you get "No space left on device" error on Google
Cloud Shell, you can build the images on Google Cloud Build: [Enable the
Cloud Build
API](https://console.cloud.google.com/flows/enableapi?apiid=cloudbuild.googleapis.com),
then run `skaffold run -p gcb --default-repo=gcr.io/[PROJECT_ID]` instead.
2018-08-16 19:49:17 +00:00
2019-12-16 14:30:23 +00:00
6. Run `kubectl get pods` to see pods are in a healthy and ready state.
2018-07-26 04:17:04 +00:00
2019-12-16 14:30:23 +00:00
7. Find the IP address of your Istio gateway Ingress or Service, and visit the
2018-08-13 18:23:42 +00:00
application.
2019-02-20 22:34:12 +00:00
```sh
INGRESS_HOST="$(kubectl -n istio-system get service istio-ingressgateway \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')"
echo "$INGRESS_HOST"
```
2018-08-16 19:49:17 +00:00
2019-02-20 22:34:12 +00:00
```sh
curl -v "http://$INGRESS_HOST"
```
2018-08-16 19:49:17 +00:00
2019-03-29 16:25:34 +00:00
### Cleanup
If you've deployed the application with `skaffold run` command, you can run
`skaffold delete` to clean up the deployed resources.
If you've deployed the application with `kubectl apply -f [...]` , you can
run `kubectl delete -f [...]` with the same argument to clean up the deployed
resources.
2020-04-23 21:12:30 +00:00
## Conferences featuring Online Boutique
2019-01-08 18:51:36 +00:00
2019-01-15 18:14:33 +00:00
- [Google Cloud Next'18 London – Keynote ](https://youtu.be/nIq2pkNcfEI?t=3071 )
showing Stackdriver Incident Response Management
2019-01-08 18:51:36 +00:00
- Google Cloud Next'18 SF
2019-02-20 22:34:12 +00:00
- [Day 1 Keynote ](https://youtu.be/vJ9OaAqfxo4?t=2416 ) showing GKE On-Prem
2019-01-15 18:14:33 +00:00
- [Day 3 – Keynote ](https://youtu.be/JQPOPV_VH5w?t=815 ) showing Stackdriver
APM (Tracing, Code Search, Profiler, Google Cloud Build)
2019-01-08 18:51:36 +00:00
- [Introduction to Service Management with Istio ](https://www.youtube.com/watch?v=wCJrdKdD6UM&feature=youtu.be&t=586 )
2019-05-26 22:35:56 +00:00
- [KubeCon EU 2019 - Reinventing Networking: A Deep Dive into Istio's Multicluster Gateways - Steve Dake, Independent ](https://youtu.be/-t2BfT59zJA?t=982 )
2019-01-08 18:51:36 +00:00
2018-07-26 04:17:04 +00:00
---
2019-02-20 22:34:12 +00:00
This is not an official Google project.