Carlos Cornejo 2016

Introduction to Docker

AGENDA - session 1

Problems and challenges

History and evolution towards containers

Reorganizing roles and responsibilities

Docker ecosystem

Docker first steps

Some history background

Three types of virtualization technologies:

  • Emulation (hardware emulation via software)
  • Virtualization (os virtualization using hypervisor)
  • Containers (apps containers)

Emulation

hardware (cpu, ram, disk, etc.) is emulated

Virtualization (VM's)

 virtualization with same hardware

e.g., VmWare, Virtualbox, Xen..

Containers

An execution environment is virtualized
e.g., Solaris Zones, Linux LXC, Docker

vs

Containers are isolated, but share OS and where appropriate bins/libraries ...

The What and Why of Containers

Containers are an encapsulation of an application with its dependencies.

Containers are fundamentally changing the way we develop, distribute, and run software.

Developers can build software locally, knowing that it will run identically regardless of host environment.

VM's vs Containers

Containers share resources with the host OS, which makes them an order of  magnitude more efficient.

Containers can be started and stopped in a fraction of a second.

Applications running in containers incur little to no overhead
to applications running natively on the host OS.

The portability of containers has the potential to eliminate a whole class of bugs caused by subtle changes in the running environment

—it could even put an end to the age-old developer refrain of

“but it works on my machine!”

Docker and Containers

Containers are an old concept.

For decades, UNIX systems have had the chroot command

that provides a simple form of filesystem isolation. FreeBSD, Solaris, etc..

First in 2001 Virtuozzo container technology, then Google with CGroups and The Linux Containers (LXC) project started in 2008.

Finally, in 2013, Docker brought the final pieces to the
containerization puzzle, and the technology began to enter the mainstream.

Docker is the solution the the matrix hell

The solution ;-)

Why do Developers Care?

  • Build once…(finally) run anywhere
    • A clean, safe and portable runtime environment for your app.
    • No worries about missing dependencies, packages and other pain points during subsequent deployments.
    • Automate testing, integration, packaging…anything you can script.
    • Cheap, zero-penalty containers to deploy services.
    • Instant replay and reset of image snapshots.

Why do Ops Care?

  • Configure once…run anything
    • Make the entire lifecycle more efficient, consistent and repeatable.
    • Eliminate inconsistencies between development, test and production environments.

    • Support segregation of duties.

    • Significantly improves the speed and reliability of continuous deployment and continuous integration systems.

    • Because the containers are so lightweight it addresses significant performance, costs, deployment and portability issues normally associated with VMs.

Reorganizing roles and responsibilities

Docker ecosystem

Docker Machine

Provides a CLI to quickly provision a Docker Host.

Core component for the docker ecosystem to manage the life cycle of a container.

Docker Machine installs and configures Docker hosts on local or remote resources.

Docker Compose

Describe your stack with one file.

Docker Compose is a tool for building and running applications composed of

multiple Docker containers.

Docker Registry

Store and distribute your docker container images.

Docker Hub makes it easy: hub.docker.com

Docker Swarm

Docker’s Orchestration, Clustering and Management solution.

Exposes several Docker Engines as a single virtual Engine.

Production ready

Docker first steps

Anatomy of a Dockerfile

FROM java:8-jre

ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME

ENV TOMCAT_TGZ_URL https://www.apache.org/tomcat/tomcat-latest.tar.gz

RUN set -x \
	&& curl -fSL "$TOMCAT_TGZ_URL" -o tomcat.tar.gz \
	&& tar -xvf tomcat.tar.gz \
	&& rm tomcat.tar.gz*

EXPOSE 8080

CMD ["catalina.sh", "run"]

Introduction to Docker session 2

AGENDA - session 2

Docker architecture

How images get built

Docker + Jenkins

2014-04-15 00:37Z image/svg+xml

The Docker Architecture

How Images Get Built

We build new images through Dockerfiles and via the docker build command

user@local# docker build -t efc/fo-web .
#
# Super simple example of a Dockerfile
#
FROM ubuntu:latest
MAINTAINER Carlos M. Cornejo "ccornejo@blah.com"

RUN apt-get update
RUN apt-get install -y python python-pip wget
RUN pip install Flask

ADD hello.py /home/hello.py

WORKDIR /home

Image Layers

Each instruction in a Dockerfile results in a new image layer

The new layer is created by starting a container using the image of the previous layer, executing the Dockerfile instruction and saving a new image

They're like git commits or changesets for filesystems.

How Images Get Built

How Images Get Built

Caching

Docker caches each layer in order to speed up the building of images

The cache is used for an instruction if:

  • The previous instruction was found in the cache and
  • there is a layer in the cache that has exactly the same instruction and parent layer (even spurious spaces will invalidate the cache).

Also, in the case of COPY and ADD instructions, the cache will be invalidated if the checksum or metadata for any of the files has changed.

If you need to invalidate the cache, you can run docker build with the

--no-cache argument

How Images Get Built

Base Images

It's important to decide which base image to start from

This step is very important and need to be thought through

  • You may want to start from a tiny os image (i.e. busybox)
  • full os image (i.e. ubuntu)
  • just a framework (i.e. java)
  • also to remember which version we want.
  • Docker hub is your best buddy here

Continous Integration/Continous Delivery hype

the automation challenge

traditional ci/cd

ci/cd with docker

Docker + Jenkins

jenkins + docker ci pipeline management

We want to set up Jenkins so that:

Any code change triggers the pipeline 

Builds and provisions new docker images

Runs integration test and if all passes ok then it pushes to a docker registry.

Promotes those stable images to QA/Sandbox so the relevant people can test it

Builds the artifact/s

Runs unit test and code quality checks

Docker + Jenkins CI life-cycle

Jenkins is on the rescue

Jenkins plugins

Docker Hub Notification: Triggers downstream jobs when a tagged container is pushed to Docker Hub

Docker Traceability: identifies which build pushed a particular container, displays on Jenkins builds page

Docker Custom Build Environment: specifies customized build environments as Docker containers

Docker: Use a docker host to dynamically provision a slave, run a single build, then tear-down

Build and Publish : builds projects that have a Dockerfile and pushes the resultant tagged image to Docker Hub

Jenkins plugins

Docker Traceability

Jenkins plugins

Pipeline plugin

Continuous Delivery as Code

Configuration in Source Repositories

Reusable Definitions

stage 'compileAndUnit'
node {
    git branch: 'master', url: 'https://github.com/lordofthejars/starwars.git'
    gradle 'clean test'
    stash excludes: 'build/', includes: '**', name: 'source'
    stash includes: 'build/jacoco/*.exec', name: 'unitCodeCoverage'
    step([$class: 'JUnitResultArchiver', testResults: '**/build/test-results/*.xml'])
}

stage 'codeQuality'
parallel 'pmd' : {
    node {
        unstash 'source'
        gradle 'pmdMain'
        step([$class: 'PmdPublisher', pattern: 'build/reports/pmd/*.xml'])
    }

}, 'jacoco': {
    node {
        unstash 'source'
        unstash 'unitCodeCoverage'
        gradle 'jacocoTestReport'
    }
}

Less click-and-type, more code

Jenkins plugins

Docker Pipeline integration

docker.withRegistry('https://lordofthejars-docker-continuous_delivery.bintray.io', 'd4fc3fa9-39f7-47ea-a57c-795642f90989') {
    git 'git@github.com:lordofthejars/busybox.git'
    def newApp = docker.build "lordofthejars-docker-continuous_delivery.bintray.io/lordofthejars/javatest:${env.BUILD_TAG}"
    newApp.push()
}

docker.image('lordofthejars/javatest').withRun {c ->
    sh './executeTests.sh'
}

Pipeline View

Jenkins DSL

That's all folks!! any questions???

Introduction to Docker

By Carlos María Cornejo Crespo

Introduction to Docker

  • 1,351