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

  • Published on
    28-Jul-2015

  • View
    724

  • Download
    1

Embed Size (px)

Transcript

1. @crichardson Deploying Spring Boot applications with Docker Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson chris@chrisrichardson.net http://plainoldobjects.com http://microservices.io 2. @crichardson Presentation goal Deploying Spring-based microservices using Docker 3. @crichardson About Chris 4. @crichardson About Chris Founder of a startup thats creating a platform for developing event-driven microservices (http://bit.ly/trialeventuate) 5. @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 6. @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 7. @crichardson User registration microservices User Registration Service RabbitMQ MongoDB POST /user { emailAddress: "foo@bar.com", password: "xyz" } NewUserNotication User Management Service Email Service Exchange Queue Queue User Registration Web App Registration Form Confirmation page http://plainoldobjects.com/category/spring-boot/ 8. @crichardson Spring-based components 9. @crichardson Building microservices with Spring Boot Makes it easy to create stand-alone, production ready Spring applications Automatically congures Spring using Convention over Conguration Externalizes conguration Generates standalone executable JARs with embedded web server Provides a standard foundation for all your microservices 10. @crichardson Spring Boot simplies conguration Spring Container Application components Fully congured application Conguration Metadata Typesafe JavaCong Annotations Legacy XML Default Conguration Metadata Spring Boot You write less of this Inferred from CLASSPATH 11. @crichardson Tiny Spring conguration Scan for controllers Customize JSON serialization 12. @crichardson About auto-conguration Builds on Spring framework features @EnableAutoConguration - triggers the inclusion of default conguration @Conditional - beans only active if condition is satised Conditional on class dened on class path e.g. Mongo Driver implies Mongo beans Conditional on bean dened/undened e.g. dene Mongo beans if you havent 13. @crichardson The Main program 14. @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 15. @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 16. @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 17. @crichardson Spring Boot simplies deployment Spring Boot creates self-contained JAR le No separate application server to install/congure Externalize conguration = 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 18. @crichardson Package service as an RPM Benets: Encapsulates language, framework, application server, ... Handles dependencies ... But Conicting dependency versions Conicting ports, ... 19. @crichardson Lets have immutable infrastructure 20. @crichardson Package as AMI http://boxfuse.com/learn/why.html packer.io, github.com/Netix/aminator cloudnative.io 21. @crichardson Service-as-AMI is great BUT... Building is so slow! Booting is so slow! AMIs arent portable - need to build for multiple platforms Heavy-weight: Not practical to run multiple VMs on a developer machine ... 22. @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/ 23. @crichardson Docker images Portable application packaging format Self-contained, read-only le-system image of an operating system + application Layered structure = sharing and caching very, very fast 5 seconds to package application! 24. @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 25. Boot2docker Docker on the Mac (and Windows) Runs Docker in a small VirtualBox VM http://boot2docker.io/ Shares /User with VM 26. @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 27. @crichardson Packaging a Spring Boot application as a Docker image Install Java Install application JAR le Congure image to run Java on startup Handle externalized conguration 28. @crichardson Docker and Java https://registry.hub.docker.com/_/java/ 29. @crichardson FROM java:openjdk-8u45-jdk MAINTAINER chris@chrisrichardson.net EXPOSE 8080 CMD java -jar spring-boot-restful-service.jar ADD build/spring-boot-restful-service.jar . Dockerle for packaging a Spring Boot application Base image Copy JAR into image Expose 8080 Bonus question: why is the ADD command last? Startup command 30. @crichardson Building the Spring Boot application copy jar to subdir so it can be referenced by Dockerle Build image using ./Dockerle 31. @crichardson Running the Spring Boot container dockerrun-d-p8080:8080 -eSPRING_DATA_MONGODB_URI=mongodb://192.168.59.103/userregistration -eSPRING_RABBITMQ_HOST=192.168.59.103 --namesb_rest_svc sb_rest_svc Map container port to host port Run as daemon Container name Image name Specify environment variables 32. @crichardson Testing the REST API $curl-v-d'{"emailAddress":"foo@bar.com"}'-H"content-type:application/json" http://${DOCKER_HOST_IP}:8080/user {"id":"5561f726e4b0b15173726b96","emailAddress":"foo@bar.com"} 33. @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 34. @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 35. @crichardson A couple of years ago Vagrant was the cool way to do this VM s are so yesterday! 36. @crichardson Using Docker is easier and much more efcient 37. @crichardson Using shell scripts $dockerrun-d-p5672:5672-p15672:15672--namerabbitmqdockerbile/ rabbitmq $dockerrun-d-p27017:27017--namemongodbdockerbile/mongodbmongod-- smallbiles Not bad but we can do better! 38. @crichardson About Docker Compose Tool for dening and running an application consisting of multiple docker containers Create a docker-compose.yml Declarative system denition Commands to start, stop, and remove containers https://docs.docker.com/compose/ 39. @crichardson Docker-compose.yml rabbitmq: image:dockerbile/rabbitmq ports: -"5672:5672" -"15672:15672" mongodb: image:dockerbile/mongodb ports: -"27017:27017" command:mongod--smallbiles 40. @crichardson Using Docker Compose $docker-composeup-d Recreatingdocker_mongodb_1... Recreatingdocker_rabbitmq_1... $docker-composestop Stoppingdocker_rabbitmq_1... Stoppingdocker_mongodb_1... $docker-composerm Goingtoremovedocker_rabbitmq_1,docker_mongodb_1 Areyousure?[yN]y Removingdocker_mongodb_1... Removingdocker_rabbitmq_1... 41. @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 42. @crichardson Lets imagine that you want to run your distributed app (e.g. end-to-end testing) 43. @crichardson java -jar app1.jar java -jar app2.jar Lots of scripting :-( 44. @crichardson docker run -d app1 docker run -d app2 Lots of scripting :-( 45. @crichardson Docker-compose.yml - part 1 restfulservice: 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 le available inside container 46. @crichardson Docker-compose.yml - part 2 web: 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 47. @crichardson 48. @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 49. @crichardson My application architecture API gateway Event Store Service 1 Service 2 Service ... Event Archiver Indexer AWS Cloud S3 NodeJS Scala/Spring Boot 50. @crichardson Jenkins-based deployment pipeline Build & Test microservice Build & Test Docker image Deploy Docker image to registry One pipeline per microservice 51. @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 52. @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! 53. @crichardson CI environment runs on Docker EC2 Instance Jenkins Container Artifactory container EBS volume /jenkins- home /gradle-home /artifactory- home 54. @crichardson Updating production environment Large EC2 instance running Docker Deployment tool: 1. Compares running containers with whats 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 ??? 55. @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 56. @crichardson @crichardson chris@chrisrichardson.net http://plainoldobjects.com http://microservices.io