dockerized maven

55
Dockerized Maven Matthias Bertschy (http://matthiasbertschy.info ) Delivering like a Pro with Docker 5 October, 2016

Upload: matthias-bertschy

Post on 11-Jan-2017

79 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Dockerized maven

Dockerized Maven

Matthias Bertschy (http://matthiasbertschy.info)Delivering like a Pro with Docker5 October, 2016

Page 2: Dockerized maven

who?

● working as a sysadmin since 2005● CISSP and RHCE● recently switched to DevOps● day-to-day work with OpenShift and Docker

Page 3: Dockerized maven

about this talk

how to leverage custom Docker containers to:

● handle build dependencies on local workstations● provide clean Jenkins slaves● run tests inside orchestrated deployments● run tests inside OpenShift projects

Page 4: Dockerized maven

build dependencies

Page 5: Dockerized maven

pain

● every developer is different○ workstation OS

○ development tools

● every team (microservice) is different○ programming language

○ dependencies

● building quality software requires consistency● keeping the same environment throughout the pipeline is

the key

Page 6: Dockerized maven

let's use Docker...

Page 7: Dockerized maven

Dockerfile

FROM docker.io/centos

ENV MAVEN_VERSION 3.3.3

RUN yum update -y && \

yum install -y java-1.8.0-openjdk-headless && \

tar xzf apache-maven-$MAVEN_VERSION-bin.tar.gz -C

/usr/local/ && \

mkdir -p /usr/local/apache-maven-$MAVEN_VERSION/.m2/ && \

yum clean all

COPY contrib/settings.xml

/usr/local/apache-maven-$MAVEN_VERSION/conf/

Page 8: Dockerized maven

/home/mbertschy/java

#!/bin/bash

cmd="/usr/bin/java"

cwd=`pwd`

user=`id -u`

group=`id -g`

docker run -i --privileged --user=${user}:${group}

--volume=${cwd}:${cwd} --workdir=${cwd} --entrypoint ${cmd}

--rm <mvn_container> "${@}"

Page 9: Dockerized maven

/home/mbertschy/mvn

#!/bin/bash

MAVEN_VERSION=3.3.3

cmd="/usr/local/apache-maven-${MAVEN_VERSION}/bin/mvn"

cwd=`pwd`

user=`id -u`

group=`id -g`

docker run -i --privileged --user=${user}:${group}

--volume=${cwd}:${cwd} --workdir=${cwd} --entrypoint ${cmd}

--rm <mvn_container> "${@}"

Page 10: Dockerized maven

usage

[mbertschy@devops tmp]$ /home/mbertschy/mvn validate

[mbertschy@devops tmp]$ /home/mbertschy/mvn package

[mbertschy@devops tmp]$ /home/mbertschy/java -jar target/*.jar

. ____ _ __ _ _

/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

\\/ ___)| |_)| | | | | || (_| | ) ) ) )

' |____| .__|_| |_|_| |_\__, | / / / /

=========|_|==============|___/=/_/_/_/

:: Spring Boot :: (v1.2.5.RELEASE)

...

Page 11: Dockerized maven

benefits

● build and test tools are centrally managed● different versions of tools do not interfere● workstation are configured in a breeze● developers can focus on producing quality code

Page 12: Dockerized maven

Jenkins slaves

Page 13: Dockerized maven

Jenkins: master vs slave

MASTER

● light workload

● at least one per team

(separation of duties)

● numerous / on-demand

● better virtualized

SLAVE

● heavy workload

● the need for speed

● better using bare metal

● could be shared to reduce cost

Page 14: Dockerized maven

pain

● slaves should be shared between teams for cost reasons● every team (microservice) is different

○ programming language

○ dependencies

● maintaining and upgrading a slave farm is increasingly difficult without uniformity

● building quality software requires consistency● keeping the same environment throughout the pipeline is

the key

Page 15: Dockerized maven

let's use Docker (again)...

Page 16: Dockerized maven

... there's a plugin for that!

Page 17: Dockerized maven

Docker Plugin

https://wiki.jenkins-ci.org/display/JENKINS/Docker+Plugin

● Maintainers: Kanstantsin Shautsou, Nigel Magnay● ~4000 installation per month, and growing● use a docker host to dynamically provision a slave, run a

single build, then tear-down that slave● optionally, the container can be committed, so that (for

example) manual QA could be performed by the container being imported into a local docker provider

Page 18: Dockerized maven

Dockerfile

...

RUN yum install -y openssh-server rsync && \

/usr/bin/ssh-keygen -A && \

echo "UseDNS no" >>/etc/ssh/sshd_config && \

echo "GSSAPIAuthentication no" >>/etc/ssh/sshd_config && \

echo "StrictModes no" >>/etc/ssh/sshd_config && \

rm -f /run/nologin && \

useradd -u 500 -g root -p '...' jenkins && \

mkdir /home/jenkins/workspace && \

chown jenkins:root /home/jenkins/workspace

EXPOSE 22

Page 19: Dockerized maven

configuration

Prerequisite: you need a docker host with docker.service listening on port 4243

● as a Jenkins administrator, go to Manage Jenkins● then Configure System● at the bottom of the page, you should find a button

proposing to Add a new cloud

Page 20: Dockerized maven
Page 21: Dockerized maven
Page 22: Dockerized maven
Page 23: Dockerized maven

usage

● in your Maven project configuration, you just have to Restrict where this project can be run

● and enter the correct label to match your new slave:

● you can then hit Build Now

Page 24: Dockerized maven

usage (2)

Started by upstream project

"S11N/products-md-service-api-build" build number 118

originally caused by:

Started by an SCM change

[EnvInject] - Loading node environment variables.

Building remotely on slave01-f7d02a1538bf (mvn-build) in

workspace

/home/jenkins/workspace/S11N/production-orders-service-build

[WS-CLEANUP] Deleting project workspace...

Cloning the remote Git repository

...

Page 25: Dockerized maven

benefits

● slaves are clean at every build● slaves are generic and can be reused for many build types

(mvn, npm, ...)● we can use lightweight OS for slaves (atomic CentOS)● easy maintenance● consistency

Page 26: Dockerized maven

Docker Compose

Page 27: Dockerized maven

what?

● tool for defining and running multi-container Docker applications

● great for development, testing, and staging environments● we use it for component testing on workstations

● define the services in docker-compose.yml● docker-compose up

Page 28: Dockerized maven

docker-compose.yml

---

db:

image: postgresql-94-rhel7:latest

ports:

- "5432:5432"

environment:

POSTGRESQL_USER: myuser

POSTGRESQL_PASSWORD: ********

POSTGRESQL_DATABASE: mydb

Page 29: Dockerized maven

docker-compose.yml (2)

...

product:

image: products-md-service:0.1.0-SNAPSHOT

ports:

- "18080:8080"

links:

- db

environment:

DB_URL: jdbc:postgresql://db:5432/mydb

DB_USER: myuser

DB_PASSWORD: ********

Page 30: Dockerized maven

Docker

architecture

db172.17.0.2

product172.17.0.3

workstation10.10.1.32

Page 31: Dockerized maven

pain

● links defined in docker-compose.yml are only resolvable from containers started by Compose

● testing and debugging should be performed as if the developer was inside Docker space

● building quality software requires consistency● keeping the same environment throughout the pipeline is

the key

Page 32: Dockerized maven

let's use Docker (again)...

Page 33: Dockerized maven

principle

● links defined in docker-compose.yml are only resolvable from containers started by Compose

● we already have our development environment packaged inside a container

● let's insert our developer inside the Compose world!

● we have called this pattern "the avatar"

Page 34: Dockerized maven

Docker

architecture

db172.17.0.2

product172.17.0.3

workstation10.10.1.32

avatar172.17.0.4

Page 35: Dockerized maven

docker-compose.yml

...

avatar:

image: <mvn_container>

ports:

- "2222:22"

links:

- db

- product

command: [/sbin/sshd, -D]

Page 36: Dockerized maven

usage

[mbertschy@devops tmp]$ docker-compose up -d

Creating tmp_db_1

Creating tmp_product_1

Creating tmp_avatar_1

[...]$ rsync -a -e "ssh -p 2222" ./ [email protected]/

[mbertschy@devops tmp]$ ssh -l jenkins -p 2222 127.0.0.1

[email protected]'s password:

[jenkins@e250549ee18d ~]$ pwd

/home/jenkins

[jenkins@e250549ee18d ~]$ ping db

PING db (172.17.0.2) 56(84) bytes of data.

64 bytes from db (172.17.0.2): icmp_seq=1 ttl=64 time=0.106 ms

Page 37: Dockerized maven

benefits

● tests rely on link definitions● different versions of tools do not interfere● workstation are configured in a breeze● developers can focus on producing quality code

Page 38: Dockerized maven

OpenShift

Page 39: Dockerized maven

what?

Built on opensource projects:● Docker provides the abstraction for packaging apps● Kubernetes orchestrates Docker containers

OpenShift Enterprise adds:● Source code management, builds, and deployments● Image management and promotion● Application management● Team and user tracking for large developer organizations

Page 40: Dockerized maven
Page 41: Dockerized maven

component architecture

● database:○ 1x PostgreSQL pod

○ 1x service (SQL)

● backend:○ 1x SpringBoot pod

○ 2x service (REST, gRPC)

○ 1x route

● frontend○ 1x NGINX pod (serving node.js application)

○ 1x service (HTTP)

○ 1x route

Page 42: Dockerized maven
Page 43: Dockerized maven
Page 44: Dockerized maven
Page 45: Dockerized maven

pain

● pods and services are only accessible from containers started inside the same project

● routes can only publish HTTP (v1) based protocols● tests have to access services directly (flyway scripts for

databases, message brokers, binary protocols, ...)

● building quality software requires consistency● keeping the same environment throughout the pipeline is

the key

Page 46: Dockerized maven

let's use Docker (one last time)...

Page 47: Dockerized maven

principle

● pods and services are only accessible from containers started inside the same project (until 3.3...)

● we already have our development environment packaged inside a container

● let's insert our developer inside the OpenShift project!

● this is a second use of our pattern called "the avatar"

Page 48: Dockerized maven

Dockerfile

...

# fix permissions to run inside openshift

RUN chmod 0770 /home/jenkins && \

chmod 2770 /home/jenkins/workspace && \

chmod 2770 /usr/local/apache-maven-$MAVEN_VERSION/.m2/

ADD oc-3.2.0.20-linux.tar.gz /usr/local/bin/

# when running from jenkins, plugin starts /sbin/sshd -D

# this default sleep is for OpenShift to keep pod running

CMD ["sleep", "infinity"]

Page 49: Dockerized maven

template.yml

apiVersion: v1

kind: DeploymentConfig

metadata:

name: mvn-avatar

spec:

replicas: 1

template:

spec:

containers:

image: <mvn_container>

imagePullPolicy: Always

name: mvn-avatar

Page 50: Dockerized maven
Page 51: Dockerized maven

usage

[mbertschy@devops tmp]$ oc get pods

NAME READY STATUS RESTARTS AGE

mvn-avatar-1-94snc 1/1 Running 0 6d

db-products-md-srv-1-13o5f 1/1 Running 0 6d

products-md-srv-1-lw3cb 1/1 Running 0 6d

products-md-web-1-g1fu8 1/1 Running 0 6d

[mbertschy@devops tmp]$ oc rsync ./ mvn-avatar-1-94snc:/

[mbertschy@devops tmp]$ oc rsh mvn-avatar-1-94snc

sh-4.2$ ping db-products-md-srv

PING db-products-md-srv.qa-products-md.svc.cluster.local

(172.30.46.79) 56(84) bytes of data.

^C

Page 52: Dockerized maven

usage from Jenkins

[products-md-ctest] $ /bin/sh -xe /tmp/hudson84804829430149.sh

++ oc get pod -l app=mvn-avatar --no-headers

++ awk '{print $1}'

+ avatarPod=mvn-avatar-1-94snc

+ oc rsh mvn-avatar-1-94snc mkdir -p S11N/products-md-deploy

+ oc rsync --progress=true S11N/products-md-deploy/

mvn-avatar-1-94snc:S11N/products-md-deploy/

+ oc rsh mvn-avatar-1-94snc bash -c 'cd

S11N/products-md-deploy ; source *-conf.sh || true ; export ;

mvn verify'

...

Page 53: Dockerized maven

usage from Jenkins (2)

...

+ mkdir -p S11N/products-md-ctest/cucumberOutput

+ oc rsync

mvn-avatar-1-94snc:S11N/products-md-deploy/cucumberOutput/

S11N/products-md-ctest/cucumberOutput --no-perms=true

receiving incremental file list

20161003133154.json

Page 54: Dockerized maven

benefits

● tests are run from inside OpenShift projects● native name resolution and load balancers are leveraged● developers can jump inside projects for live debugging● Jenkins integration is possible with minimal fuss

Page 55: Dockerized maven

thanks