Slide 1

Slide 1 text

Creating microservices architectures using node.js and Kubernetes

Slide 2

Slide 2 text

CTO at seedtag Paul Goldbaum Who is this guy?! @paulgoldbaum

Slide 3

Slide 3 text

Our original stack Symfony 2 MongoDB Physical servers hosted at OVH PHP 5.6

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Our current stack MongoDB + Google Datastore Kubernetes through Google Container Engine Node.js + Express Apache Spark

Slide 7

Slide 7 text

Don’t do it*

Slide 8

Slide 8 text

Why do we need a microservices platform?

Slide 9

Slide 9 text

Platform

Slide 10

Slide 10 text

Load Balancer Deployment manager Log handler Process supervisor Service discovery Service communication Storage manager

Slide 11

Slide 11 text

Abstract away differences between services Isolate apps from each other Reserve resources in shared execution environment Wrap as executable unit

Slide 12

Slide 12 text

Provides deployment, scaling and management of containerized applications Works on some of the main public and private cloud providers and on-premise Serves as a layer of abstraction over the infrastructure Container cluster manager built by Google after Borg

Slide 13

Slide 13 text

Putting services into production

Slide 14

Slide 14 text

var express = require('express'); var app = express(); app.get('/', function(req, res) { res.send('Hello World!'); }) app.listen(3000, function() { console.log('Application running on port 3000!'); })

Slide 15

Slide 15 text

apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hello-world spec: replicas: 2 template: metadata: labels: app: hello-world spec: containers: - name: main image: hello-world:v1 kubectl create -f hello-world.yaml

Slide 16

Slide 16 text

kubectl set image deployment/hello-world main=hello-world:v2

Slide 17

Slide 17 text

var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('Hello World!'); }) app.get('/status', function (req, res) { res.sendStatus(200); }) app.listen(3000, function() { console.log('Application running on port 3000!'); })

Slide 18

Slide 18 text

… spec: containers: - name: hello-world image: hello-world:v1 ports: - containerPort: 3000 readinessProbe: httpGet: path: /status port: 3000 periodSeconds: 5

Slide 19

Slide 19 text

Service B

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

… var ready = true; app.get('/status', function (req, res) { if (ready) { res.sendStatus(200); } else { res.sendStatus(500); } }) process.on('SIGTERM', function () { ready = false; setTimeout(function() { server.close(function () { process.exit(0); }); }, 10000); }); …

Slide 22

Slide 22 text

Choosing programming languages

Slide 23

Slide 23 text

Small services give us flexibility when choosing languages/frameworks

Slide 24

Slide 24 text

We can now use right tool for the right job but…

Slide 25

Slide 25 text

status endpoint / connection drain docker build test environment app instrumentation Custom NodeJS Microservices Framework … now what?

Slide 26

Slide 26 text

Creating a new microservice should be EASY

Slide 27

Slide 27 text

Communicating microservices

Slide 28

Slide 28 text

GET /users HTTP/1.1 App A App B ? Synchronous communication

Slide 29

Slide 29 text

Synchronous communication using Kubernetes services App A Service B App B App B App B

Slide 30

Slide 30 text

apiVersion: v1 kind: Service metadata: name: hello-world spec: ports: - port: 3000 targetPort: 3000 selector: app: hello-world

Slide 31

Slide 31 text

Synchronous communication using Kubernetes services App A Service B App B App B App B

Slide 32

Slide 32 text

Synchronous communication using Kubernetes services App A Service B App B App B App B Circuit Breaker

Slide 33

Slide 33 text

App A App B Message bus OMG LOL Asynchronous communication

Slide 34

Slide 34 text

Monitoring services

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Prometheus Labels can be added to time series to allow grouping of data by any criteria Provides powerful query operators Allows to use queries to generate alerts Time-series database created by SoundCloud

Slide 37

Slide 37 text

ALERT my_request_rate IF sum(rate(http_requests_total{kubernetes_name=“hello-world”}[1m])) < 100 FOR 5m LABELS { severity = "urgent" }

Slide 38

Slide 38 text

Connects to many different backend such as Prometheus, Graphite, InfluxDB, Elasticsearch, … Great for having your stats up on a screen in the office Web-based dashboard creator for visualizing time-series and application metrics

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

kube-state-metrics node-exporter Feeding data into our system express-prom-bundle

Slide 41

Slide 41 text

Service A Service B Service C

Slide 42

Slide 42 text

Instrumented apps send spans to Zipkin Outgoing requests are marked with a correlation ID Zipkin joins spans from a single correlation ID together to form traces Distributed tracing system by Twitter

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

Measure everything! Microservices are hard, imply a lot more operations work Creating a custom microservices framework is key to agility Conclusions

Slide 45

Slide 45 text

[email protected] Do you want to help us change the world of online advertising. Join us! Thank you! Contact: [email protected] - @paulgoldbaum