Hipster Shop: Cloud-Native Microservices Demo Application
This project contains a 10-tier microservices application. The application is a
web-based e-commerce app called “Hipster Shop” where users can browse items,
add them to the cart, and purchase them.
Google uses this application to demonstrate use of technologies like
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.
If you’re using this demo, please ★Star this repository to show your interest!
👓Note to Googlers: Please fill out the form at
go/microservices-demo if you are using this
application.
Screenshots
Home Page |
Checkout Screen |
|
|
Service Architecture
Hipster Shop is composed of many microservices written in different
languages that talk to each other over gRPC.
Find Protocol Buffers Descriptions at the ./pb
directory.
Service |
Language |
Description |
frontend |
Go |
Exposes an HTTP server to serve the website. Does not require signup/login and generates session IDs for all users automatically. |
cartservice |
C# |
Stores the items in the user's shipping cart in Redis and retrieves it. |
productcatalogservice |
Go |
Provides the list of products from a JSON file and ability to search products and get individual products. |
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 |
Node.js |
Charges the given credit card info (mock) with the given amount and returns a transaction ID. |
shippingservice |
Go |
Gives shipping cost estimates based on the shopping cart. Ships items to the given address (mock) |
emailservice |
Python |
Sends users an order confirmation email (mock). |
checkoutservice |
Go |
Retrieves user cart, prepares order and orchestrates the payment, shipping and the email notification. |
recommendationservice |
Python |
Recommends other products based on what's given in the cart. |
adservice |
Java |
Provides text ads based on given context words. |
loadgenerator |
Python/Locust |
Continuously sends requests imitating realistic user shopping flows to the frontend. |
Features
- Kubernetes/GKE:
The app is designed to run on Kubernetes (both locally on "Docker for
Desktop", as well as on the cloud with GKE).
- gRPC: Microservices use a high volume of gRPC calls to
communicate to each other.
- Istio: Application works on Istio service mesh.
- OpenCensus Tracing: Most services are
instrumented using OpenCensus trace interceptors for gRPC/HTTP.
- Stackdriver APM: 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.
- Skaffold: Application
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 load generator.
Installation
We offer three installation methods:
-
Running locally with “Docker for Desktop” (~20 minutes) You will build
and deploy microservices images to a single-node Kubernetes cluster running
on your development machine.
-
Running on Google Kubernetes Engine (GKE)” (~30 minutes) You will build,
upload and deploy the container images to a Kubernetes cluster on Google
Cloud.
-
Using pre-built container images: (~10 minutes, you will still need to
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).
Option 1: Running locally with “Docker for Desktop”
💡 Recommended if you're planning to develop the application or giving it a
try on your local cluster.
-
Install tools to run a Kubernetes cluster locally:
- kubectl (can be installed via
gcloud components install kubectl
)
- Docker for Desktop (Mac/Windows): It provides Kubernetes support as noted
here.
- skaffold
(ensure version ≥v0.20)
-
Launch “Docker for Desktop”. Go to Preferences:
- choose “Enable Kubernetes”,
- set CPUs to at least 3, and Memory to at least 6.0 GiB
-
Run kubectl get nodes
to verify you're connected to “Kubernetes on Docker”.
-
Run skaffold run
(first time will be slow, it can take ~20 minutes).
This will build and deploy the application. If you need to rebuild the images
automatically as you refactor the code, run skaffold dev
command.
-
Run kubectl get pods
to verify the Pods are ready and running. The
application frontend should be available at http://localhost:80 on your
machine.
Option 2: Running on Google Kubernetes Engine (GKE)
💡 Recommended if you're using Google Cloud Platform and want to try it on
a realistic cluster.
-
Install tools specified in the previous section (Docker, kubectl, skaffold)
-
Create a Google Kubernetes Engine cluster and make sure kubectl
is pointing
to the cluster.
gcloud services enable container.googleapis.com
gcloud container clusters create demo --enable-autoupgrade \
--enable-autoscaling --min-nodes=3 --max-nodes=10 --num-nodes=5 --zone=us-central1-a
kubectl get nodes
-
Enable Google Container Registry (GCR) on your GCP project and configure the
docker
CLI to authenticate to GCR:
gcloud services enable containerregistry.googleapis.com
gcloud auth configure-docker -q
-
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,
then run skaffold run -p gcb --default-repo=gcr.io/[PROJECT_ID]
instead.
-
Find the IP address of your application, then visit the application on your
browser to confirm installation.
kubectl get service frontend-external
Troubleshooting: A Kubernetes bug (will be fixed in 1.12) combined with
a Skaffold bug
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.
Option 3: Using Pre-Built Container Images
💡 Recommended if you want to deploy the app faster in fewer steps to an
existing cluster.
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.
This option offers you pre-built public container images that are easy to deploy
by deploying the release manifest directly to an existing cluster.
Prerequisite: a running Kubernetes cluster (either local or on cloud).
-
Clone this repository, and go to the repository directory
-
Run kubectl apply -f ./release/kubernetes-manifests
to deploy the app.
-
Run kubectl get pods
to see pods are in a Ready state.
-
Find the IP address of your application, then visit the application on your
browser to confirm installation.
kubectl get service/frontend-external
(Optional) Deploying on a Istio-installed GKE cluster
Note: you followed GKE deployment steps above, run skaffold delete
first
to delete what's deployed.
-
Create a GKE cluster (described in "Option 2").
-
Use Istio on GKE add-on
to install Istio to your existing GKE cluster.
gcloud beta container clusters update demo \
--zone=us-central1-a \
--update-addons=Istio=ENABLED \
--istio-config=auth=MTLS_PERMISSIVE
NOTE: If you need to enable MTLS_STRICT
mode, you will need to update
several manifest files:
kubernetes-manifests/frontend.yaml
: delete "livenessProbe" and
"readinessProbe" fields.
kubernetes-manifests/loadgenerator.yaml
: delete "initContainers" field.
-
(Optional) Enable Stackdriver Tracing/Logging with Istio Stackdriver Adapter
by following this guide.
-
Install the automatic sidecar injection (annotate the default
namespace
with the label):
kubectl label namespace default istio-injection=enabled
-
Apply the manifests in ./istio-manifests
directory.
kubectl apply -f ./istio-manifests
This is required only once.
-
Deploy the application with skaffold run --default-repo=gcr.io/[PROJECT_ID]
.
-
Run kubectl get pods
to see pods are in a healthy and ready state.
-
Find the IP address of your istio gateway Ingress or Service, and visit the
application.
INGRESS_HOST="$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')"
echo "$INGRESS_HOST"
curl -v "http://$INGRESS_HOST"
Conferences featuring Hipster Shop
This is not an official Google project.