Top Banner
@crichardson Deploying Spring Boot applications with Docker Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson [email protected] http://plainoldobjects.com http://microservices.io
56
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Deploying Spring Boot applications with DockerChris Richardson

Author of POJOs in Action Founder of the original CloudFoundry.com

@crichardson [email protected] http://plainoldobjects.com http://microservices.io

Page 2: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Presentation goal

Deploying Spring-based microservices using

Docker

Page 3: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

About Chris

Page 4: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

About Chris

Founder of a startup that’s creating a platform for developing

event-driven microservices (http://bit.ly/trialeventuate)

Page 5: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

For more information

https://github.com/cer/event-sourcing-examples

https://github.com/cer/microservices-examples

http://microservices.io

http://plainoldobjects.com/

https://twitter.com/crichardson

Page 6: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Using Docker Compose to deploy infrastructure

Using Docker Compose to launch your application

Docker-based deployment pipeline

Page 7: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

User registration microservices

User Registration

Service

RabbitMQ

MongoDB

POST /user

{ emailAddress: "[email protected]", password: "xyz"}

NewUserNotification

User Management Service Email Service

Exchange

Queue Queue

User Registration

Web App

RegistrationForm

Confirmation page

http://plainoldobjects.com/category/spring-boot/

Page 8: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Spring-based components

Page 9: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Building microservices with Spring Boot

Makes it easy to create stand-alone, production ready Spring applications

Automatically configures Spring using Convention over Configuration

Externalizes configuration

Generates standalone executable JARs with embedded web server

Provides a standard foundation for all your microservices

Page 10: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Spring Boot simplifies configuration

Spring Container

Application components

Fully configured application

Configuration Metadata

•Typesafe JavaConfig •Annotations •Legacy XML

Default Configuration

Metadata

Spring BootYou write less

of this

Inferred from CLASSPATH

Page 11: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Tiny Spring configurationScan for controllers

Customize JSON serialization

Page 12: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

About auto-configurationBuilds on Spring framework features

@EnableAutoConfiguration - triggers the inclusion of default configuration

@Conditional - beans only active if condition is satisfied

Conditional on class defined on class path

e.g. Mongo Driver implies Mongo beans

Conditional on bean defined/undefined

e.g. define Mongo beans if you haven’t

Page 13: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

The Main program

Page 14: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Building with Gradle

buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.8.RELEASE") } }

apply plugin: 'scala' apply plugin: 'spring-boot'

dependencies { compile "org.springframework.boot:spring-boot-starter-web" compile "org.springframework.boot:spring-boot-starter-data-mongodb" compile "org.springframework.boot:spring-boot-starter-amqp" compile "org.springframework.boot:spring-boot-starter-actuator"

testCompile "org.springframework.boot:spring-boot-starter-test" } ...

Ensures correct dependencies

Page 15: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Running the microservice

$ java -jar build/libs/spring-boot-restful-service.jar --server.port=8081 ... 2014-12-03 16:32:04.671 INFO 93199 --- [ main] n.c.m.r.main.UserRegistrationMain$ : Started UserRegistrationMain. in 5.707 seconds (JVM running for 6.553)

$ curl localhost:8081/health {"status":"UP", "mongo":{"status":"UP","version":"2.4.10"}, "rabbit":{"status":"UP", ...} }

Built in health checks

Command line arg processing

Page 16: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Using Docker Compose to deploy infrastructure

Using Docker Compose to launch your application

Docker-based deployment pipeline

Page 17: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Spring Boot simplifies deployment

Spring Boot creates self-contained JAR file

No separate application server to install/configure

Externalize configuration = immutable application

Just need Java

But which version of Java? 7.x? 8.y?

And, what about the other applications?

Tomcat, Play, NodeJS, ...

Deploying a system is complex

Page 18: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Package service as an RPMBenefits:

Encapsulates language, framework, application server, ...

Handles dependencies

...

But

Conflicting dependency versions

Conflicting ports, ...

Page 19: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Let’s have immutable infrastructure

Page 20: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Package as AMI

http://boxfuse.com/learn/why.html

packer.io, github.com/Netflix/aminator cloudnative.io

Page 21: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Service-as-AMI is great BUT...

Building is so slow!

Booting is so slow!

AMIs aren’t portable - need to build for multiple platforms

Heavy-weight: Not practical to run multiple VMs on a developer machine

...

Page 22: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Package a service as a Docker image

Lightweight, OS-level virtualization mechanism

Runs on Linux

directly

via, e.g., Virtual Box

https://www.docker.com/

Page 23: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Docker images

Portable application packaging format

Self-contained, read-only file-system image of an operating system + application

Layered structure = sharing and caching ⇒ very, very fast

5 seconds to package application!

Page 24: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Docker container

Running Docker image

Group of sandboxed processes

Builds on control groups and namespaces

Contains entire OS but typically the only process is the application (JVM) ⇒ fast startup

Page 25: Developing and deploying applications with Spring Boot and Docker (@oakjug)

Boot2docker

Docker on the Mac (and Windows)

Runs Docker in a small VirtualBox VM

http://boot2docker.io/

Shares /User with VM

Page 26: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Using Docker Compose to deploy infrastructure

Using Docker Compose to launch your application

Docker-based deployment pipeline

Page 27: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Packaging a Spring Boot application as a Docker image

Install Java

Install application JAR file

Configure image to run Java on startup

Handle externalized configuration

Page 28: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Docker and Java

https://registry.hub.docker.com/_/java/

Page 29: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

FROM java:openjdk-8u45-jdk MAINTAINER [email protected] EXPOSE 8080 CMD java -jar spring-boot-restful-service.jar ADD build/spring-boot-restful-service.jar .

Dockerfile for packaging a Spring Boot application

Base image

Copy JAR into image

Expose 8080

Bonus question: why is the ADD command last?

Startup command

Page 30: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Building the Spring Boot application

copy jar to subdir so it can be referenced by Dockerfile

Build image using ./Dockerfile

Page 31: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Running the Spring Boot container

docker  run  -­‐d  -­‐p  8080:8080    -­‐e    SPRING_DATA_MONGODB_URI=mongodb://192.168.59.103/userregistration    -­‐e  SPRING_RABBITMQ_HOST=192.168.59.103    -­‐-­‐name  sb_rest_svc  sb_rest_svc

Map container port to host port

Run as daemon

Container name

Image nameSpecify environment

variables

Page 32: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Testing the REST API

$  curl  -­‐v  -­‐d  '{"emailAddress":  "[email protected]"}'  -­‐H  "content-­‐type:  application/json"  http://${DOCKER_HOST_IP}:8080/user  

{"id":"5561f726e4b0b15173726b96","emailAddress":"[email protected]"}

Page 33: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Using Docker Compose to deploy infrastructure

Using Docker Compose to launch your application

Docker-based deployment pipeline

Page 34: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Problem

Typical application needs a database

Many apps also need a message broker

Other projects need even more than that

Zookeeper, Kafka, DynamoDB

Making sure every developer installs the correctly version = PITA

Page 35: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

A couple of years ago Vagrant was the cool way to do this

VMs are

so ye

sterda

y!

Page 36: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Using Docker is easier and much more efficient

Page 37: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Using shell scripts

$  docker  run  -­‐d  -­‐p  5672:5672  -­‐p  15672:15672  -­‐-­‐name  rabbitmq  dockerbile/rabbitmq  

$  docker  run  -­‐d  -­‐p  27017:27017  -­‐-­‐name  mongodb  dockerbile/mongodb  mongod  -­‐-­‐smallbiles

Not bad but we can do better!

Page 38: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

About Docker Compose

Tool for defining and running an application consisting of multiple docker containers

Create a docker-compose.yml

Declarative system definition

Commands to start, stop, and remove containers

https://docs.docker.com/compose/

Page 39: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Docker-compose.yml

rabbitmq:      image:  dockerbile/rabbitmq      ports:          -­‐  "5672:5672"          -­‐  "15672:15672"  mongodb:      image:  dockerbile/mongodb      ports:          -­‐  "27017:27017"      command:  mongod  -­‐-­‐smallbiles

Page 40: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Using Docker Compose$  docker-­‐compose  up  -­‐d  Recreating  docker_mongodb_1...  Recreating  docker_rabbitmq_1...  

$  docker-­‐compose  stop  Stopping  docker_rabbitmq_1...  Stopping  docker_mongodb_1...

$  docker-­‐compose  rm  Going  to  remove  docker_rabbitmq_1,  docker_mongodb_1  Are  you  sure?  [yN]  y  Removing  docker_mongodb_1...  Removing  docker_rabbitmq_1...  

Page 41: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Using Docker Compose to deploy infrastructure

Using Docker Compose to launch your application

Docker-based deployment pipeline

Page 42: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Let’s imagine that you want to run your distributed app (e.g. end-to-end testing)

Page 43: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

java -jar app1.jar java -jar app2.jar

Lots of scripting :-(

Page 44: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

docker run -d … app1 docker run -d … app2

Lots of scripting :-(

Page 45: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Docker-compose.yml - part 1restfulservice:      image:  java:openjdk-­‐8u45-­‐jdk      working_dir:  /app      volumes:          -­‐  spring-­‐boot-­‐restful-­‐service/build/libs:/app      command:  java  -­‐jar  /app/spring-­‐boot-­‐restful-­‐service.jar      ports:          -­‐  "8081:8080"      links:          -­‐  rabbitmq          -­‐  mongodb      environment:          SPRING_DATA_MONGODB_URI:  mongodb://mongodb/userregistration          SPRING_RABBITMQ_HOST:  rabbitmq

Link to other containers

Make the jar file available inside container

Page 46: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Docker-compose.yml - part 2web:      image:  java:openjdk-­‐8u45-­‐jdk      working_dir:  /app      volumes:          -­‐  spring-­‐boot-­‐webapp/target:/app      command:  java  -­‐jar  /app/spring-­‐boot-­‐user-­‐registration-­‐webapp-­‐1.0-­‐SNAPSHOT.jar      ports:          -­‐  "8080:8080"      links:          -­‐  restfulservice      environment:          USER_REGISTRATION_URL:  http://restfulservice:8080/user  

Link to the other container

hostname of other container

Page 47: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Page 48: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Using Docker Compose to deploy infrastructure

Using Docker Compose to launch your application

Docker-based deployment pipeline

Page 49: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

My application architecture

API gateway Event

Store

Service 1

Service 2

Service ...

Event Archiver

Indexer AWS Cloud

S3

NodeJS Scala/Spring Boot

Page 50: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Jenkins-based deployment pipeline

Build & Test microservice

Build & Test Docker image

Deploy Docker image

to registry

One pipeline per microservice

Page 51: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Smoke testing docker images

Smoke test

Docker daemon

Service containerGET /health

POST /containers/create

creates

POST /containers/{id}/start

Docker daemon must listen on TCP port

Page 52: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Publishing Docker images

docker tag service-${VERSION}:latest \ ${REGISTRY_HOST_AND_PORT}/service-${VERSION}

docker push ${REGISTRY_HOST_AND_PORT}/service-${VERSION}

docker/publish.sh

Pushing only takes 25 seconds!

Page 53: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

CI environment runs on Docker

EC2 Instance

Jenkins Container

Artifactory container

EBS volume

/jenkins-home

/gradle-home

/artifactory-home

Page 54: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Updating production environment

Large EC2 instance running Docker

Deployment tool:

1. Compares running containers with what’s been built by Jenkins

2. Pulls latest images from Docker registry

3. Stops old versions

4. Launches new versions

One day: use Docker clustering solution and a service discovery mechanism,

Most likely, AWS container service

Mesos and Marathon + Zookeeper, Kubernetes or ???

Page 55: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

Summary

Spring Boot is a great way to build Spring-based microservices

Docker is a great way to package microservices

Docker-compose is a super useful development tool

Page 56: Developing and deploying applications with Spring Boot and Docker (@oakjug)

@crichardson

@crichardson [email protected]

http://plainoldobjects.com http://microservices.io