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
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
- 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)
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
- frontend for containerd
- multi host networking
- scaling
- abstraction of concrete container specification
- manage container lifecycle
- image transfer
- container execution
- supervision
- networking
- independent container runtime
- industry standard
- targets:
- simplicity
- robustness
- portability
- 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
- 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
- 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
- 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
- uses HyperKit to run Alpine Linux for linux containers
- only one docker vm
- setup and manage remote hosts (or vms) with docker
- use on client pc to work on docker instance in data centers
installation
- any questions?
- Windows / OS X
- linux: use repos above
- do we have multiple debian/ubuntu users?
Hello World
docker run busybox echo "Hello World"
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
- 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
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
- 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
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
- 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
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>
- reproducible builds
- flat file
FROM
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
- 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/
- 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
- 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 ./
- like .gitignore
- works on all ADD/COPY sources
Dockerfile
*.txt
hello-world/world.txt
hello/world.txt
!hello*.txt
- 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
ENTRYPOINT ["executable"]
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2 #
- like command by container run
CMD ["executable","param1","param2"]
CMD command param1 param2 #
ENTRYPOINT ["executable"]
CMD ["param1","param2"] #( default parameters to ENTRYPOINT)
FROM busybox
ENV foo /bar
WORKDIR ${foo} # WORKDIR /bar
ADD . $foo # ADD . /bar
COPY \$foo /quux # COPY $foo /quux
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
Rule #1:
only one process
per container
one process
- one foreground process
- output on stout
- receives stop/kill signal
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
- 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
EXPOSE
- only exposed ports can bound to public interfaces
EXPOSE <port> [<port>...]
docker cli
- maps container port to a local port (and interface)
-p [[<ip>:]<hostPort>:]containerPort[:<options>] #specified port
-P #All ports
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, ...
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
- 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
alternatives to pure docker files
- 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>
persistent data
- one node
- distributed cluster
- distributed data stores
- distributed SAN-Systems
- proprietary solutions
- ...
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
- use different user in container!
USER
- USER directive
- set user for next steps
- last user will be the application user
USER root
RUN mkdir /test
USER myappuser
ONBUILD
- instruction call on build time of a child image
ONBUILD [INSTRUCTION]
STOPSIGNAL
- changes stop signal send by "docker stop"
STOPSIGNAL signal
- --cpus=<value>
- --cpu-period=<value>
- --cpu-quota=<value>
- --cpuset-cpus
- --cpu-shares
- linux kernel will kill process on exceeded memory
- --memory=
- ...
- docker kills container when limit was exceeded
- java container need in most cases 1.5x MX
- some changes with java 10
- docker native
- client: docker-compose
- cluster management
- auto recovering
- auto scaling
- based on docker health checks
- shared secrets and configs
- cloud platform
- monitoring
- cluster management
- auto recovering
- auto scaling
- marathon is a container platform on top of Mesos
and DC/OS
- cluster management
- monitoring
- auto recovering
- auto scaling
- distributed storage
- 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
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"
SHELL
- changes the shell to execute commands
SHELL /bin/bash
- Beratung, Coaching und Projektunterstützung
- Java EE
- Buildsysteme gradle und maven/ant-Migration
- Testautomatisierung
- Coach in agilen Projekten
- DevOps