SaLUG! @ Manifatture KNOS
26 Febbraio 2015
What is docker?
Docker is an open-source engine that automates the deployment of any application as a lightweight, portable, self-sufficient container that will run virtually anywhere.
How is this different from Virtual Machines?
Reference: https://www.docker.com/whatisdocker/
What is docker?
Common use cases for Docker include:
- Automating the packaging and deployment of applications
- Creation of lightweight, private PAAS environments
- Automated testing and continuous integration/deployment
- Deploying and scaling web apps, databases and backend services
Reference: https://www.docker.com/resources/usecases/
To run properly, docker needs the following software to be installed at runtime:
The docker daemon requires Linux kernel version >= 3.10 (older versions are known to have bugs which cause data loss and frequently panic under certain conditions)
$ curl -sSL https://get.docker.com/ubuntu/ | sudo sh
Reference: https://docs.docker.com/installation/ubuntulinux/
The Docker Engine consists of two parts:
- a daemon, a server process that manages all the containers
- a client, which acts as a remote control for the daemon.
The client part can reach the daemon on a socket file or on a tcp port.
$ sudo docker
Usage: docker [OPTIONS] COMMAND [arg...]
A self-sufficient runtime for linux containers.
...
Commands:
attach Attach to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders from a container's filesystem to the host path
create Create a new container
diff Inspect changes on a container's filesystem
...
$ docker version
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.4.1
Git commit (client): a8a31ef
OS/Arch (client): linux/amd64
Server version: 1.5.0
Server API version: 1.17
Go version (server): go1.4.1
Git commit (server): a8a31ef
$ ps aux | grep docker
root 3078 0.0 0.1 1820024 11848 ? Ssl feb02 1:40 /usr/bin/docker -d
...
$ sudo docker images
$ ls /var/run/docker.sock -l
srw-rw---- 1 root docker 0 feb 2 17:02 /var/run/docker.sock
$ adduser $USER docker
$ getent group docker
docker:x:999:rpl
$ groups
rpl ... docker
$ docker search ubuntu | less
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Official Ubuntu base image 1307 [OK]
dockerfile/ubuntu Trusted automated Ubuntu (http://www.ubunt... 44 [OK]
ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 40 [OK]
ubuntu-upstart Upstart is an event-based replacement for ... 21 [OK]
...
$ docker pull busybox:latest
busybox:latest: The image you are pulling has been verified
ea13149945cb: Pull complete
4986bf8c1536: Pull complete
511136ea3c5a: Pull complete
df7546f9f060: Pull complete
Status: Downloaded newer image for busybox:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
busybox latest 4986bf8c1536 6 weeks ago 2.433 MB
$ docker save ubuntu:latest > ubuntu-`date +%Y%m%d`.dockersave
$ file ubuntu-20150219.dockersave
ubuntu-20150219.dockersave: POSIX tar archive
$ cat ubuntu-20150219.dockersave | docker load
## or
$ docker load -i ubuntu-20150219.dockersave
docker images looks a lot like a git repository for full container images:
$ sudo docker history busybox
IMAGE CREATED CREATED BY SIZE
4986bf8c1536 6 weeks ago /bin/sh -c #(nop) CMD [/bin/sh] 0 B
ea13149945cb 6 weeks ago /bin/sh -c #(nop) ADD file:8cf517d90fe79547c4 2.433 MB
df7546f9f060 4 months ago /bin/sh -c #(nop) MAINTAINER J
$ sudo docker images --tree
Warning: '-tree' is deprecated, it will be removed soon. See usage.
- 8d967df12c0d Virtual Size: 295.5 MB Tags: trusty:20141212, trusty:latest
- 8b5754c2e11d Virtual Size: 295.5 MB
- 8c6263dca696 Virtual Size: 295.5 MB
- 1cba02ff71f7 Virtual Size: 368.9 MB Tags: ansibled-trusty:latest
- d9b4665877b9 Virtual Size: 529.9 MB Tags: platform-node-0-11:latest
- 964c55090d7e Virtual Size: 587.8 MB Tags: platform-go:latest
- c7b801168dd3 Virtual Size: 524.3 MB Tags: platform-lamp:latest
- 404c64b5478f Virtual Size: 607.1 MB Tags: my-webserver-base:latest
$ sudo docker images --viz | dot -Tpng > docker_viz.png
Warning: '--viz' is deprecated, it will be removed soon.
See usage.
$ sudo docker run ubuntu echo "Hello World!"
Hello World!
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52c3d85d2c69 ubuntu:14.04 echo 'Hello World' About a minute ago Exited (0) About a minute ago angry_turing
$ sudo docker run -i -t ubuntu bash -l
root@c49630b27b95:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 18160 1896 ? Ss 15:43 0:00 bash -l
root 8 0.0 0.0 15568 1140 ? R+ 15:43 0:00 ps aux
root@c49630b27b95:/#
$ sudo docker ps
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c49630b27b95 ubuntu:14.04 bash -l 2 minutes ago Up 2 minutes clever_euclid
mount from docker host into docker container on run:
$ sudo docker run -v $HOME/PROJECTS/app:/mnt:rw $IMAGE /mnt/run_my_app.sh
mount and expose to the environment ssh-auth socket file
$ sudo docker run -i -t \
-v $SSH_AUTH_SOCK:/run/ssh-auth.sock \
-e "SSH_AUTH_SOCK=/run/ssh-auth.sock" \
ubuntu \
bash -l
run container and remove its cached writable layer on exit:
$ sudo docker run --rm $IMAGE $COMMAND
$ sudo docker diff $CONTAINER
C /root
A /root/CREATED_IN_DOCKER_CONTAINER
C /var/log
D /var/log/dmesg
docker containers looks a lot like a git working tree (but diff is not as much powerful)
commit container into a new image layer:
$ sudo docker commit $CONTAINER $IMAGE_NAME_TAG
FROM ubuntu
ENV HOME=/root
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install python-pip -y
Dockerfile commands reference: https://docs.docker.com/reference/builder/
FROM: https://docs.docker.com/reference/builder/#from
...
## 2 RUN commands create 2 layers:
RUN apt-get update
RUN apt-get install python-pip -y
...
## This creates a single layer:
RUN apt-get update && \
apt-get install python-pip -y
Every Dockerfile command generates a new image layer (some of the layers are fake metadata layers, e.g. FROM or ENV)
...
RUN apt-get update && \
apt-get install python-pip -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
We can reduce the size of the layers removing cache and temp files in the same RUN command that creates the layer.
FROM ubuntu
ENV HOME=/root
ENV DEBIAN_FRONTEND=noninteractive
ADD ./assets/sources.list /etc/apt/sources.list
RUN apt-get update && \
apt-get install python-pip -y
ADD: https://docs.docker.com/reference/builder/#add
COPY: https://docs.docker.com/reference/builder/#copy
$ docker build -t mywebapp:latest .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu
---> 5506de2b643b
Step 1 : ENV HOME /root
---> Running in 9feda31a0167
---> 478ce805ee75
Removing intermediate container 9feda31a0167
Step 2 : ENV DEBIAN_FRONTEND noninteractive
---> Running in 31d607ee4be2
---> 3f28cd94092c
Removing intermediate container 31d607ee4be2
Step 3 : RUN apt-get update && apt-get install python-pip -y
---> Running in a32957dd280f
Ign http://archive.ubuntu.com trusty InRelease
Ign http://archive.ubuntu.com trusty-updates InRelease
...
Setting up python-pip (1.5.4-1) ...
Processing triggers for libc-bin (2.19-0ubuntu6.5) ...
Processing triggers for ca-certificates (20130906ubuntu2) ...
Updating certificates in /etc/ssl/certs... 164 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
---> 8992e8d867c4
Removing intermediate container d1e129b6c440
Successfully built 8992e8d867c4
the build context is packed and streamed from the docker client to the docker daemon (e.g. the docker daemon could be on a different machine which is connected using a TCP socket):
$ docker build .
Uploading context 18.829 MB
Uploading context
Step 0 : FROM busybox
...
you can create a .dockerignore
file which force the exclusion of files that match
the defined patterns:
.git
tmp
*~
docker inspect
images metadata$ docker inspect ubuntu:latest | less
[{
"Architecture": "amd64",
"Author": "",
"Comment": "",
"Config": {
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [ "/bin/bash" ],
"CpuShares": 0,
"Cpuset": "",
"Domainname": "",
"Entrypoint": null,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"ExposedPorts": null,
"Hostname": "f4f502dce15c",
"Image": "51a9c7c1f8bb2fa19bcd09789a34e63f35abb80044bc10196e304f6634cc582c",
...
docker inspect
containers metadata$ docker inspect $CONTAINER_NAME_OR_ID | less
[{
"AppArmorProfile": "",
"Args": [],
"Config": {
"AttachStderr": true,
"AttachStdin": false,
"AttachStdout": true,
...
},
...
"NetworkSettings": {
...
"IPAddress": "172.17.0.11",
},
...
"State": {
...
"Running": true,
...
},
...
$ docker inspect -f '{{ .NetworkSettings.IPAddress }}: {{ .State.Running }}' \
$CONTAINER_NAME_OR_ID
172.17.0.11: true
Network ports (tcp or udp) can be exposed from a container, they can be declared in the Dockerfile
...
EXPOSE 22 80 53/udp
and/or from the command line (using the -p
option on the docker run
command.
$ docker run ... -p 8080:80 -p 8053:53/udp $IMAGE
...
CMD ["/path/to/executable", "param1"]
The main purpose of a CMD is to provide defaults for an executing container.
...
#### exec form
ENTRYPOINT ["/path/entry", "param1"]
#### shell form
ENTRYPOINT /path/entry param1
An ENTRYPOINT allows you to configure a container that will run as an executable.