36
@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

Deploying Spring Boot applications with Docker (east bay cloud meetup dec 2014)

Embed Size (px)

Citation preview

@crichardson

Deploying Spring Boot applications with Docker

Chris Richardson

Author of POJOs in ActionFounder of the original CloudFoundry.com

@[email protected]://plainoldobjects.comhttp://microservices.io

@crichardson

Presentation goal

Deploying Spring-based microservices using

Docker

@crichardson

About Chris

@crichardson

About Chris

Founder of a buzzword compliant (stealthy, social, mobile, big data, machine learning, ...) startup

Consultant helping organizations improve how they architect and deploy applications using cloud, micro services, polyglot applications, NoSQL, ...

Creator of http://microservices.io

Organizer of @oakjug - http://bit.ly/ebjava

Co-organizer of http://meetup.com/oakland-scala

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Docker-based deployment pipeline

@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/

@crichardson

Spring-based components

@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

@crichardson

Spring Boot simplifies configuration

Spring Container

Application components

Fully configured application

ConfigurationMetadata

•Typesafe JavaConfig•Annotations•Legacy XML

Default Configuration

Metadata

Spring BootYou write less

of this

Inferred from CLASSPATH

@crichardson

Tiny Spring configurationScan for controllers

Customize JSON serialization

@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

@crichardson

The Main program

@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

@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

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Docker-based deployment pipeline

@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

@crichardson

Package service as an RPMBenefits:

Encapsulates language, framework, application server, ...

Handles dependencies

...

But

Conflicting dependency versions

Conflicting ports, ...

@crichardson

Let’s have immutable infrastructure

@crichardson

Package as AMI

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

packer.io, github.com/Netflix/aminatorcloudnative.io

@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

...

@crichardson

Package a service as a Docker image

Lightweight, OS-level virtualization mechanism

Runs on Linux (directly or via, e.g., Virtual Box)

Docker image:

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!

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

https://www.docker.com/

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Docker-based deployment pipeline

@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

@crichardson

Docker and Java

https://registry.hub.docker.com/u/dockerfile/java/

@crichardson

Dockerfile for packaging a Spring Boot application

Base image

Copy JAR into image /data is base image’s CWD

Expose 8080

Bonus question: why is the ADD command last?

@crichardson

Building the Spring Boot application copy jar to subdir so it can be

referenced by Dockerfile

Build image using ./Dockerfile

@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_svcsb_rest_svc

Map container port to host port

Run as daemon

Container name

Image nameSpecify environment

variables

@crichardson

Agenda

Introduction to Spring Boot

Why immutable infrastructure/containerization

Spring Boot and Docker

Docker-based deployment pipeline

@crichardson

My application architecture

API gateway Event

Store

Service 1

Service 2

Service ...

Event Archiver

Indexer AWS Cloud

S3

NodeJS Scala/Spring Boot

@crichardson

Jenkins-based deployment pipeline

Build & Testmicroservice

Build & TestDockerimage

Deploy Docker image

to registry

One pipeline per microservice

@crichardson

Smoke testing docker images

Smoke test

Docker daemon

ServicecontainerGET /health

POST /containers/create

creates

POST /containers/{id}/start

Docker daemon must listen on TCP port

@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!

@crichardson

CI environment runs on Docker

EC2 Instance

Jenkins Container

Artifactory container

EBS volume

/jenkins-home

/gradle-home

/artifactory-home

@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 ???

@crichardson

Summary

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

Docker is a great way to package microservices

@crichardson

@crichardson [email protected]

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