Code Monkey home page Code Monkey logo

emojivoto's Introduction

Emoji.voto

A microservice application that allows users to vote for their favorite emoji, and tracks votes received on a leaderboard. May the best emoji win.

The application is composed of the following 3 services:

Emojivoto Topology

Running

In Minikube

Deploy the application to Minikube using the Linkerd2 service mesh.

  1. Install the linkerd CLI

    curl https://run.linkerd.io/install | sh
  2. Install Linkerd2

    linkerd install | kubectl apply -f -
  3. View the dashboard!

    linkerd dashboard
  4. Inject, Deploy, and Enjoy

    kubectl kustomize kustomize/deployment | \
        linkerd inject - | \
        kubectl apply -f -
  5. Use the app!

    minikube -n emojivoto service web-svc

In docker-compose

It's also possible to run the app with docker-compose (without Linkerd2).

Build and run:

make deploy-to-docker-compose

The web app will be running on port 8080 of your docker host.

Via URL

To deploy standalone to an existing cluster:

kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment

Generating some traffic

The VoteBot service can generate some traffic for you. It votes on emoji "randomly" as follows:

  • It votes for 🍩 15% of the time.
  • When not voting for 🍩, it picks an emoji at random

If you're running the app using the instructions above, the VoteBot will have been deployed and will start sending traffic to the vote endpoint.

If you'd like to run the bot manually:

export WEB_HOST=localhost:8080 # replace with your web location
go run emojivoto-web/cmd/vote-bot/main.go

Building

Building requires that you have protoc-gen-go v1.27.1 and protoc-gen-go-grpc v1.1.0 on your path. These can be installed by running:

go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]

Then you can set up proto files and build apps by running:

make build

Releasing a new version

To build and push multi-arch docker images:

  1. Update the tag name in common.mk

  2. Create the Buildx builder instance

    docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
    docker buildx create --name=multiarch-builder --driver=docker-container --use
    docker buildx inspect multiarch-builder --bootstrap
  3. Build & push the multi-arch docker images to hub.docker.com

    docker login
    make multi-arch
  4. Update:

    • docker-compose.yml
    • kustomize/deployment/emoji.yml
    • kustomize/deployment/vote-bot.yml
    • kustomize/deployment/voting.yml
    • kustomize/deployment/web.yml
  5. Distribute to the Linkerd website repo

    kubectl kustomize kustomize/deployment  > ../website/run.linkerd.io/public/emojivoto.yml
    kubectl kustomize kustomize/daemonset   > ../website/run.linkerd.io/public/emojivoto-daemonset.yml
    kubectl kustomize kustomize/statefulset > ../website/run.linkerd.io/public/emojivoto-statefulset.yml

Prometheus Metrics

By default the voting service exposes Prometheus metrics about current vote count on port 8801.

This can be disabled by unsetting the PROM_PORT environment variable.

Local Development

Emojivoto webapp

This app is written with React and bundled with webpack. Use the following to run the emojivoto go services and develop on the frontend.

Start the voting service

GRPC_PORT=8081 go run emojivoto-voting-svc/cmd/server.go

[In a separate terminal window] Start the emoji service

GRPC_PORT=8082 go run emojivoto-emoji-svc/cmd/server.go

[In a separate terminal window] Bundle the frontend assets

cd emojivoto-web/webapp
yarn install
yarn webpack # one time asset-bundling OR
yarn webpack-dev-server --port 8083 # bundle/serve reloading assets

[In a separate terminal window] Start the web service

export WEB_PORT=8080
export VOTINGSVC_HOST=localhost:8081
export EMOJISVC_HOST=localhost:8082

# if you ran yarn webpack
export INDEX_BUNDLE=emojivoto-web/webapp/dist/index_bundle.js

# if you ran yarn webpack-dev-server
export WEBPACK_DEV_SERVER=http://localhost:8083

# start the webserver
go run emojivoto-web/cmd/server.go

[Optional] Start the vote bot for automatic traffic generation.

export WEB_HOST=localhost:8080
go run emojivoto-web/cmd/vote-bot/main.go

View emojivoto

open http://localhost:8080

Testing Linkerd Service Profiles

Service Profiles are a feature of Linkerd that provide per-route functionality such as telemetry, timeouts, and retries. The Emojivoto application is designed to showcase Service Profiles by following the instructions below.

Generate the ServiceProfile definitions from the .proto files

The emoji and voting services are gRPC applications which have Protocol Buffers (protobuf) definition files. These .proto files can be used as input to the linkerd profile command in order to create the ServiceProfile definition yaml files. The Linkerd Service Profile documentation outlines the steps necessary to create the yaml files, and these are the commands you can use from the root of this repository:

linkerd profile --proto proto/Emoji.proto emoji-svc -n emojivoto
linkerd profile --proto proto/Voting.proto voting-svc -n emojivoto

Each of these commands will output yaml that you can write to a file or pipe directly to kubectl apply. For example:

  • To write to a file:
linkerd profile --proto proto/Emoji.proto emoji-svc -n emojivoto > emoji
-sp.yaml
  • To apply directly:
linkerd profile --proto proto/Voting.proto voting-svc -n emojivoto | \
kubectl apply -f -

Generate the ServiceProfile definition for the Web deployment

The web-svc deployment of emojivoto is a React application that is hosted by a Go server. We can use linkerd profile auto creation to generate the ServiceProfile resource for the web-svc with this command:

linkerd profile -n emojivoto web-svc --tap deploy/web --tap-duration 10s | \
   kubectl apply -f -

Now that the service profiles are generated for all the services, you can observe the per-route metrics for each service on the Linkerd Dashboard or with the linkerd routes command

linkerd -n emojivoto routes deploy/web-svc --to svc/emoji-svc

License

Copyright 2020 Buoyant, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

emojivoto's People

Contributors

adamwg avatar adleong avatar aliariff avatar alpeb avatar c-mejlak avatar cpretzer avatar cypherfox avatar dadjeibaah avatar danielbryantuk avatar dependabot[bot] avatar eddiezane avatar franziskagoltz avatar grampelberg avatar ihcsim avatar inoahnothing avatar kleimkuhler avatar klingerf avatar nrmitchi avatar olix0r avatar pothulapati avatar rantwijk avatar siggy avatar sterlingwhite avatar wmorgan avatar zknill avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emojivoto's Issues

Update version number vote-bot-update.yml

Issue

In MOOC LinuxFoundationX LFS143x - Introduction to Service Mesh with Linkerd Chapter 11. Canary and Blue-Green Deployments / Canary and Blue-Green Deployments / Using TrafficSplit: Part 2

Next, update the vote-bot deployment:
            Run: kubectl apply -f https://raw.githubusercontent.com/BuoyantIO/emojivoto/linux-training/training/traffic-split/vote-bot-update.yml

Command above fails because of the version number mismatch which exists in the current/existing resource. i.e. The current resource has v11 and the file still has v10.

File Path: emojivoto/training/traffic-split/vote-bot-update.yml

Linkerd Version Client version: stable-2.10.2 Server version: stable-2.10.2

Proposed Solution

Change the version number to v11.

the log of emojivoto-web

I use docker-compose to deploy the applications, and got some log which seem a little strange.

voting-svc_1 | 2019/10/26 08:41:15 Starting grpc server on GRPC_PORT=[8080]
emoji-svc_1 | 2019/10/26 08:41:15 Starting grpc server on GRPC_PORT=[8080]
web_1 | 2019/10/26 08:41:16 Connecting to [voting-svc:8080]
web_1 | 2019/10/26 08:41:16 Connecting to [emoji-svc:8080]
web_1 | 2019/10/26 08:41:16 Starting web server on WEB_PORT=[8080]
voting-svc_1 | 2019/10/26 08:42:55 Voted for [:interrobang:], which now has a total of [1] votes
web_1 | 2019/10/26 08:42:56 Error serving request [&{GET /api/vote?choice=:doughnut: HTTP/1.1 1 1 map[User-Agent:[Go-http-client/1.1] Accept-Encoding:[gzip]] {} 0 [] false localhost:8089 map[choice:[:doughnut:]] map[] map[] 172.19.0.1:33281 /api/vote?choice=:doughnut: 0xc0002858c0}]: rpc error: code = Unknown desc = ERROR
voting-svc_1 | 2019/10/26 08:42:57 Voted for [:poop:], which now has a total of [1] votes
voting-svc_1 | 2019/10/26 08:42:58 Voted for [:dancer:], which now has a total of [1] votes

I got an error message of web_1.

The docker-compose

version: '3'
services:
web:
image: buoyantio/emojivoto-web:v8
environment:
- WEB_PORT=8080
- EMOJISVC_HOST=emoji-svc:8080
- VOTINGSVC_HOST=voting-svc:8080
- INDEX_BUNDLE=dist/index_bundle.js
ports:
- "8080:8080"
depends_on:
- voting-svc
- emoji-svc
emoji-svc:
image: buoyantio/emojivoto-emoji-svc:v8
environment:
- GRPC_PORT=8080
ports:
- "8081:8080"
voting-svc:
image: buoyantio/emojivoto-voting-svc:v8
environment:
- GRPC_PORT=8080
ports:
- "8082:8080"

I use go run main.go to run the emojivoto-vote-bot.


I also deploy the application to k8s, and got an error of web-svc,

2019/10/25 07:09:47 Connecting to [voting-svc-2.emojivoto:8080]
2019/10/25 07:09:47 Connecting to [emoji-svc-2.emojivoto:8080]
2019/10/25 07:09:47 Starting web server on WEB_PORT=[8080]
2019/10/25 07:10:08 Error serving request [&{GET /api/list HTTP/1.1 1 1 map[] {} 0 [] false web-svc-2.emojivoto.svc.cluster.local:8080 map[] map[] map[] 172.16.60.3:58724 /api/list 0xc00023ff80}]: rpc error: code = Canceled desc = context canceled
2019/10/25 07:10:08 Error serving request [&{GET /api/list HTTP/1.1 1 1 map[] {} 0 [] false web-svc-2.emojivoto.svc.cluster.local:8080 map[] map[] map[] 172.16.60.3:58742 /api/list 0xc000360040}]: rpc error: code = Canceled desc = context canceled.

What do the error means?

Remove api app

The emojivoto-api app appears to be unused, since the web app also serves api endpoints. We should remove emojivoto-api to avoid confusion.

Adding port-forward instructions to README

In my local setup I have a headless Linux machine running minikube and stuff. I ssh into the Linux box and do local dev on my desktop. It makes commands like minikube -n emojivoto service web-svc not work correctly because it can't figure out how to open a browser window.

Anyway just a quick note that for the instructions step 5 works for local, but this works for remote:
kubectl -n emojivoto port-forward svc/web-svc 8899:80 --address MYIP. Then open in your browser window http://MYIP:8899/

Thanks!

mitigate CrashLoopBackoff in lifecycle test app

Follow up from #41. Containers in the lifecycle test app intentionally exit after a given number of requests. Per kubernetes/kubernetes#57291, Kubernetes puts these pods into an exponential CrashLoopBackoff, with up to 5 minute backoff. Ideally for our testing, we need a faster restart.

One option to mitigate this would be a script that periodically runs a kubectl delete po/foo command.

Add Google Analytics to Emoji Vote web app

Not sure where we need to be placing this in the React project, maybe through import?...

=====

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-60040560-4"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-60040560-4'); </script>

docker-compose example fails on MacOS

Hey Buoyant folks πŸ‘‹

Problem

$ make deploy-to-docker-compose
docker-compose stop
docker-compose rm -vf
No stopped containers
/Library/Developer/CommandLineTools/usr/bin/make -C emojivoto-web build-container
docker build .. -t "buoyantio/emojivoto-web:v10" --build-arg svc_name=emojivoto-web
Sending build context to Docker daemon  37.67MB
Step 1/5 : FROM buoyantio/emojivoto-svc-base:v10
v10: Pulling from buoyantio/emojivoto-svc-base
91028a6d2ef7: Pull complete
21c90fa7ccf4: Pull complete
Digest: sha256:1e7039ceb589274f493d3c29f6d0e0b764795b268693ecafe127285808f63f03
Status: Downloaded newer image for buoyantio/emojivoto-svc-base:v10
 ---> f59fdbacafa2
Step 2/5 : ARG svc_name
 ---> Running in 5fcd7438e7b3
Removing intermediate container 5fcd7438e7b3
 ---> 50be637330ab
Step 3/5 : COPY $svc_name/target/ /usr/local/bin/
COPY failed: stat /var/lib/docker/tmp/docker-builder245391831/emojivoto-web/target: no such file or directory
make[1]: *** [build-container] Error 1
make: *** [deploy-to-docker-compose] Error 2

Solution
I ran the following:

$ make web
.
.
Successfully tagged buoyantio/emojivoto-web:v10

$ make emoji-svc
.
.
Successfully tagged buoyantio/emojivoto-emoji-svc:v10

$ make voting-svc
.
.
Successfully tagged buoyantio/emojivoto-voting-svc:v10

.. and then it worked.

OS, Go version, docker-compose version
MacOS, go 1.15.3 darwin, docker-compose version 1.24.1

Add favicon to Emoji Vote

Add favicon to demo app. Check with @siggy about serving resource deployment and where we need to reference in the React project.

//emoji-app-favicon.png//

emoji-app-favicon

User refinements to Emoji Vote

- [ ] Add Lato webfont 
- [ ] Link leaderboard CTA block to Conduit
- [ ] Add svg to leaderboard CTA
- [ ] Add Buoyant social experiment link
- [ ] Add trademark 2017 in footer

Emoji on leaderboard look clickable but are not

It looks like we have the same styles applied to the emoji on the home page and the emoji on the leaderboard, such that hovering over a leaderboard emoji looks like this:

screenshot

That gives the impression that the emoji is clickable, but clicking on an emoji on the leaderboard doesn't do anything. I think it would be better to remove the hover background color and pointer tooltip for the emoji on that page.

Clarity / UX tweaks

Make the following changes to make things clearer to people using the emojivoto demo application:

  • #29 the Poop page should have an explanation about why it’s broken
  • #29 add an optional step to README.md describing how to provide auto-generated load (i.e. deploying the vote-bot)
  • #36 Remove svc from names of emoji.voto deployments
  • #36 for consistency with the other configurations, vote-bot should address the web service as "web-svc.emojivoto:80", instead of "web-svc:80" as it does currently

additional test dimensions in lifecycle test environment

The test environment introduced in #41, intended to exercising route, telemetry, and
service discovery lifecycles in Conduit, includes the following:

  • conduit control + data plane
  • 1 slow-cooker, 100qps
  • 10 HTTP point-to-point servers
  • 10 gRPC terminus servers, with container restart every 600 requests (~1 minute)

We should extend this environment to exercise additional dimensions, namely:

  • #45 M number of point-to-point servers
  • #45 N number of terminus servers
  • X call-depth length via point-to-point servers
  • #45 Y discrete call graphs
  • #44 full pod restart, on an interval, rather than container
  • #49 Deployment rolling restart, on an interval
  • #51 injected vs. baseline performance
  • performance at 10qps, 100qps, 1,000qps, 10,000qps
  • #51 with and without TLS (depends on linkerd/linkerd2#1295)

The Prometheus Benchmark Grafana dashboard introduced in linkerd/linkerd2#984 should provide better performance analysis of Prometheus in Conduit.

Relates to #42.

pprof endpoints

Hey πŸ‘‹

We'd love to use emojivoto as an example workload in @polarsignals. To produce some data for Polar Signals Continuous Profiler we'de love to add pprof endpoints to each of the components. Would you be open to us adding the pprof endpoints in a similar manner as the prometheus endpoint? If you prefer we can also generalize them into a single "telemetry" port.

Let me know what you think, we're happy to take care of it!

Missing LICENSE

This repo does not have a license associated with it.

Are there plans to license this code under a standard open source license?

consider renaming web deployment

With the --single-namespace flag being added in linkerd/linkerd2#1721, emojivoto is no longer a viable demo for that configuration. This is due to a naming collision between Linkerd's web deployment and emojivoto's web deployment.

Output from --single-namespace installation:

$ bin/go-run cli install --single-namespace -l emojivoto|kubectl apply -f -
...

$ curl -sL https://run.linkerd.io/emojivoto.yml | bin/go-run cli inject -l emojivoto - | kubectl apply -f -
...
The Deployment "web" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"web-svc", "linkerd.io/control-plane-ns":"emojivoto", "linkerd.io/proxy-deployment":"web"}: `selector` does not match template `labels`

As a workaround, replace this:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  creationTimestamp: null
  name: web
  namespace: emojivoto

...with...

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  creationTimestamp: null
  name: web-svc
  namespace: emojivoto

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.