Workshop

Alles in die Dose

Einführung in Docker für Entwickler

Stefan Hildebrandt / @hildebrandttk

Agenda

  • introduction
  • docker architecture
  • build images
  • run container
  • run multiple container
  • further topics
  • open space

me

  • freelance consultant
    • development
    • DevOps
    • agile development
  • 10+ years in it
  • from Oldenburg (Oldb)
  • married, 3 kids

and you?

docker: what is it

image

  • executable package
  • like a "chroot" filesystem
  • declared variables
  • some metadata

container

  • running instance of an image
  • assigned variables
  • some metadata

process isolation

  • only processes within same container visible

network

  • every container has a separated network interface
    • no port collisions
  • options for different network topologies

management tools

  • lifecycle
  • distribution
  • monitoring

based on

  • Linux Kernel Namespaces
  • iptables
  • AUFS / btfs / ZFS / OverlayFS / Device Mapper

differences to vms

  • no separated kernel
  • only one process, no background services (syslog, mail, ssh, ..)
    • less overhead (cpu, memory, startup time)

use cases

deployment and distribution

  • build an image
  • transfer to stages
  • deploy same way
  • no external runtime dependencies
    • except kernel, disk space, network

development and testing infrastructure

  • distribution of application infrastructure
    • databases
    • services
    • runtime
  • distribution of application

distribution of tools and utils

  • special versions of tools
  • handle complex setups
  • unix tools on windows

in depth

docker-engine

  • frontend for containerd
  • multi host networking
  • scaling
  • abstraction of concrete container specification

containerd

  • manage container lifecycle
    • image transfer
    • container execution
    • supervision
    • networking
  • independent container runtime
  • industry standard
  • targets:
    • simplicity
    • robustness
    • portability

runc

  • used by containerd
  • implements OCI specification
  • spawning and running containers

cli client

  • written in golang
  • communication to local or remote engine via unix or tcp (tls) socket
  • native on linux, windows and osx

images

  • contains required libs
  • multiple layers
  • naming: <repository/>name<:tag>
    • repository
    • name
    • tag
      • the version
      • "latest" as default

layers

  • every change results in one layer
  • reuse of layers by different containers

container

  • running / runnable instance of an image
  • assigned parameters for
    • ip
    • port mappings
    • volumes
    • ...

Docker (CE) on Linux

Docker (CE) on Linux

  • current version of
    • Ubuntu (18.04, 17.10, 16.04, 14.04) (x86_64, arm, System Z, IBM Power)
    • Fedora (26, 27, 28) (x86_64)
    • Debian (10, 9, 8.0, 7.7) (x86_64, arm)
    • CentOS (7) (x86_64)
  • best user experience
  • no vms
  • stable not only for development
  • many containers, big images: use dedicated partition for /var/lib/docker

Docker on Windows

Docker for Windows

  • requires Windows 10 (Pro/EE/Edu)
  • seamless integration
  • uses Hyper-V to run Alpine Linux for linux containers
    • Virtual Box and Vmware stop working
  • only one docker vm
  • possibility to run windows containers
  • best user experience on windows

Docker Toolbox

  • uses Virtual Box (or Vmware)
  • docker daemon within VM only via IP accessible
  • long history
  • known tool support
  • some configurations have to be done within default-VM

VM with full linux installation

  • ...

docker on OS X

Docker for Mac (HyperKit)

  • uses HyperKit to run Alpine Linux for linux containers
  • only one docker vm

docker-machine

  • setup and manage remote hosts (or vms) with docker
  • use on client pc to work on docker instance in data centers

installation

installation

  • any questions?
  • Windows / OS X
  • linux: use repos above
    • do we have multiple debian/ubuntu users?

Hello World

Hello World

docker run busybox echo "Hello World"

docker cli

docker cli

docker help

  • lists commands and options
docker help #general help
docker ps --help #help for command ps
docker help ps #help for command ps
docker cli

docker ps

  • listing of (stopped) container
docker ps #running only
docker ps -a #all containers
docker cli

docker run

  • creates an container from an image
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run -it busybox /bin/sh
docker cli

docker start

  • start a existing container
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker cli

docker stop

  • stop a running container
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker cli

docker kill

  • kills a running container
docker kill [OPTIONS] CONTAINER [CONTAINER...]
docker cli

docker rm

  • removes stopped container
docker rm
docker rm -f #kills container before delete it

images

images

  • a stack of filesystem snapshots
  • compressed on transfer
docker cli

docker images

  • lists all local images
  • filter and pattern support for scripting
docker images
docker images -a #lists also intermediate images
docker cli

docker rmi

  • delete an image
docker rmi [CONTAINER ID|CONTAINER NAME]
docker rmi a # delete image id starting with a, if only ONE image exists
docker cli

docker tag

  • create a new name for an image
docker tag [EXISTING_CONTAINER_ID|EXISTING_CONTAINER_NAME] \
            [NEW_CONTAINER_NAME[:NEW_CONTAINER_VERSION]]

Registry

Registry

  • central repository for images
  • hub.docker.io central public instance
  • different on promise solutions
  • payed cloud solutions
  • bundles with docker hosting
docker cli

docker pull

  • fetches an images from a registry
docker pull [CONTAINER_NAME] # fetches an image from hub.docker.io
docker pull [PRIVATE_REGISTRY]/[CONTAINER_NAME] # private registry
docker cli

docker push

docker push [CONTAINER_NAME] # pushes an image to hub.docker.io (account required)
docker push [PRIVATE_REGISTRY]/[CONTAINER_NAME] # private registry

build containers

example

  • start container with bash
  • create some message
  • exit
  • run same container again and check message
docker cli

docker commit

  • creates an image of a stopped container
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker cli

docker inspect

  • dispays meta information about any local docker object
docker inspect <container_id>|<image_id>|<network_id>

Dockerfile

  • reproducible builds
  • flat file
Dockerfile

FROM

  • describes the base image
FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
FROM debian
FROM ubuntu:16.04
FROM ubuntu:xenial
FROM ubuntu:latest
FROM ubuntu:17.04
FROM ubuntu:devel
FROM registry/ubuntu:devel
FROM dreg.h9t.eu/ubuntu:devel
Dockerfile

COPY

  • copy local file to image
  • The <src> path must be inside the context of the build
  • not src directory, just its contents
COPY <src>... <dest>
COPY ["<src>",... "<dest">
COPY hello/world.txt /
COPY ["hello world.txt", "/" ]
COPY "*world.txt" /tmp/
COPY hello?world.txt /Hello_World.TXT
COPY * /home/
COPY hello /root/
Dockerfile

ADD

  • like COPY
  • auto unpacking of TAR-Files (local sources)
  • URL support
ADD <src>... <dest>
ADD ["<src>",... "<dest">
FROM busybox
ADD hello/world.txt /
ADD ["hello world.txt", "/" ]
ADD "*world.txt" /tmp/
ADD hello?world.txt /Hello_World.TXT
ADD * /home/
ADD hello /root/
COPY hello-world.tar.gz /var/spool
ADD hello-world.tar.gz /var/www
Dockerfile

WORKDIR

  • basedir within the image
  • will be created, if not exists
  • affects RUN, CMD, ENTRYPOINT, COPY, ADD and WORKDIR
WORKDIR /a
WORKDIR c
FROM busybox
WORKDIR /a
ADD hello/world.txt .
WORKDIR /b
ADD hello?world.txt Hello_World.TXT
WORKDIR /c
ADD * ./
WORKDIR d
COPY hello-world.tar.gz .
WORKDIR /e
ADD hello-world.tar.gz ./

.dockerignore

  • like .gitignore
  • works on all ADD/COPY sources
    • except of tar content
Dockerfile
*.txt
hello-world/world.txt
hello/world.txt
!hello*.txt
Dockerfile

RUN

  • shell command(s) execute on build time
RUN <command> #executed with /bin/sh -c
RUN ["executable", "param1", "param2"]
RUN apt-get update && apt-get install -y dnsutils
RUN chmod 755 /*.sh && \
  sleep 1 && \
  /hello-world.sh
Dockerfile

ENTRYPOINT

  • default command to start
ENTRYPOINT ["executable"]
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2 #
Dockerfile

CMD 1 2 3

  • like command by container run
CMD ["executable","param1","param2"]

CMD command param1 param2 #

ENTRYPOINT ["executable"]
CMD ["param1","param2"] #( default parameters to ENTRYPOINT)
Dockerfile

ENV

FROM busybox
ENV foo /bar
WORKDIR ${foo}   # WORKDIR /bar
ADD . $foo       # ADD . /bar
COPY \$foo /quux # COPY $foo /quux

ARG

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD  /code/run-app
ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version

examples as zip

Rule #1:

only one process
per container

one process

  • one foreground process
  • output on stout
  • receives stop/kill signal

more then one process

function _term() {
   echo "Stopping container."
   echo "SIGTERM received, shutting down!"
   service myservice stop
}
function _kill() {
   echo "SIGKILL received, shutting down!"
   service myservice stop
}
trap _term SIGTERM
trap _kill SIGKILL

the docker network

default networks

docker network ls

User-defined networks

  • many options
    • docker network create --driver [bridge|host|overlay|...] <networkname>
    • docker network rm <networkname>
  • assign container to different networks
    • simulate dmz
    • define environment for autodiscovery
    • docker run --network=<networkname>
    • docker network connect [OPTIONS] <networkname> <container>

Port Mapping

  • docker can flexible handle port bindings
  • usable ports are specified on image build time
  • mapping to host on container creation
Dockerfile

EXPOSE

  • only exposed ports can bound to public interfaces
EXPOSE <port> [<port>...]
docker cli

docker run -p

  • maps container port to a local port (and interface)
-p [[<ip>:]<hostPort>:]containerPort[:<options>] #specified port
-P #All ports
Dockerfile

VOLUME

  • mount point for data exchange
  • content on build time was used as template on creation time
VOLUME ["/data"]
docker cli

docker run --volume

  • external data storage
  • independent lifecycle
  • faster then layered storage
--volume <volume>:<mount point>
--volume test:/data #mounts a docker volume to /data
--volume /tmp/test:/data #mounts directory /tmp/test to /data

orchestration of containers

application configuration

  • Environment variables
  • Volumes with configfiles
  • Discovery with etcd, consul, ...

exercises

Spring Boot

  • spring boot petclinic Adjusted copy
  • run with mysql against mysql container
    • dreg.h9t.eu/mysql:5.7
  • docker petclinic
    • dreg.h9t.eu/openjdk:8
  • docker petclinic with linked mysql db
Dockerfile

HEALTHCHECK

  • command and timing parameters to check health status
HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE #disables checks of parent image
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--start-period=DURATION (default: 0s)
--retries=N (default: 3)
HEALTHCHECK --interval=1s --timeout=1s --start-period=60s --retries=60 \
  CMD /healthcheck.sh

docker-compose

docker-compose

  • description file for all runtime parameters
    • for one or more containers
    • incl. network
  • command-line tool for handling containers

docker-compose cli

  • build
  • up
  • start
  • ps
  • stop
  • down

docker-compose.yml: Top-Level

  • version: '3.3'
  • services:
  • configs:
  • volumes:
  • networks:

docker-compose.yml: services

  • image:
  • depends_on:
  • links:
  • external_links:
  • ports:
  • configs:
  • dns:
  • dns_search:
  • extra_hosts:
  • entrypoint:
  • command:
  • healthcheck:
  • logging:

docker-compose.yml: networks

services:
  some-service:
    networks:
      new:
        aliases:
         - alias1
         - alias3
      legacy:
        aliases:
         - alias2
networks:
  new:
  legacy:

docker-compose.yml: ports

ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"
 - "6060:6060/udp"

example

nginx:
  build: "nginx"
  ports:
    - "10.42.0.1:80:80"
    - "10.42.0.1:443:443"
  volumes:
    - /mnt/docker-registry/files/:/var/www/html/files
  links:
    - registryDreg:registryDreg
    - gitLab:gitLab

exercises

  1. Containers from lession one with docker-compose
  2. proxy some app with nginx/apache
  3. selenium cluster

alternatives to pure docker files

docker-compose

  • passing args to a Dockerfile
    build:
      context: .
      args:
        buildno: 1
        password: secret
  • cache management
    cache_from:
        - alpine:latest
        - corp/web_app:3.14

fabric8 - docker-maven-plugin

  • configure mainClass in maven-jar-plugin
  • create maven-assembly file my-app
<plugin>
  <groupId>io.fabric8</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <configuration>
    <images>
      <image>
        <name>tk/hildebrandt/project/java:${project.version}</name>
        <alias>hello-world</alias>
        <build>
          <from>dreg.h9t.eu/openjdk:8</from>
          <assembly>
            <descriptorRef>my-app</descriptorRef>
          </assembly>
          <cmd>java -jar /${project.name}-${project.version}.jar</cmd>
        </build>
        <run>
          <wait>
            <log>Service Started!</log>
          </wait>
        </run>
      </image>
    </images>
  </configuration>
  <executions>
    <execution>
      <id>docker:start</id>
      <phase>install</phase>
      <goals>
        <goal>run</goal>
      </goals>
    </execution>
  </executions>
</plugin>

gradle plugin

gradle plugin

example

persistent data

  • one node
    • volume
  • distributed cluster
    • distributed data stores
    • distributed SAN-Systems
    • proprietary solutions
    • ...

Security

limit access

  • docker daemon runs as root
  • processes within container can run as root
  • volume mounts for proc, sys and dev can used for privilege escalation
  • user level tools to limit access

user

  • ROOT == ROOT
  • root privileges on kernel level
    • privilege escalation
  • use different user in container!
Dockerfile

USER

  • USER directive
  • set user for next steps
  • last user will be the application user
USER root
RUN mkdir /test
USER myappuser
Dockerfile

ONBUILD

  • instruction call on build time of a child image
ONBUILD [INSTRUCTION]
Dockerfile

STOPSIGNAL

  • changes stop signal send by "docker stop"
STOPSIGNAL signal

limit resources

cpu

  • --cpus=<value>
  • --cpu-period=<value>
  • --cpu-quota=<value>
  • --cpuset-cpus
  • --cpu-shares

memory

  • linux kernel will kill process on exceeded memory
    • not clear which one
  • --memory=
  • ...
  • docker kills container when limit was exceeded
  • java container need in most cases 1.5x MX
    • some changes with java 10

Hosting

docker swarm

  • docker native
  • client: docker-compose
  • cluster management
  • auto recovering
  • auto scaling
  • based on docker health checks
  • shared secrets and configs
docker swarm

Example

kubernetes

  • cloud platform
  • monitoring
  • cluster management
  • auto recovering
  • auto scaling

Mesos/Marathon

  • marathon is a container platform on top of Mesos and DC/OS
  • cluster management
  • monitoring
  • auto recovering
  • auto scaling
  • distributed storage

Docker Machine

  • cli for creating docker hosts on different hosting services
  • drivers for
    • Amazon Web Services
    • Microsoft Azure
    • Digital Ocean
    • Exoscale
    • Google Compute Engine
    • Microsoft Hyper-V
    • OpenStack
    • Rackspace
    • IBM Softlayer
    • Oracle VirtualBox
    • VMware vCloud Air
    • VMware Fusion
    • VMware vSphere
    • VMware Workstationv
    • Grid 5000

other cloud services

windows containers

further topics

Dockerfile

LABEL

  • Additional Metadata
  • Useful for automation
LABEL com.example.version="0.0.1-beta"
LABEL vendor="ACME Incorporated"
LABEL com.example.version="0.0.1-beta" \
      vendor="ACME Incorporated"
Dockerfile

SHELL

  • changes the shell to execute commands
SHELL /bin/bash

Open Space

Slides

h9t.eu/s/eidfe

Stefan Hildebrandt - consulting.hildebrandt.tk

  • Beratung, Coaching und Projektunterstützung
  • Java EE
  • Buildsysteme gradle und maven/ant-Migration
  • Testautomatisierung
  • Coach in agilen Projekten
  • DevOps
Datenschutz Impressum