Introduction à Docker

Introduction à Docker

Préambule

Ces slides ont été utilisés pour animer un TD à l'INSA de Lyon.

C’est un extrait de la formation
Docker pour les développeurs.

Principes de base

Fonctionnement de Docker

Docker allows you to package an application with all of its dependencies into a standardized unit for software development.

https://www.docker.com/what-docker

Architecture

Isolation

Architecture

VM
Docker

Architecture

Linux

En développement

MongoDB

PostgreSQL

MySQL

AsciiDoctor

RabbitMQ

ActiveMQ

ActiveMQ

Docker

En production

Docker en production

En production

Cluster avec Docker

Ecosystème

  • Docker Engine Docker Engine
  • Docker Engine Docker Registry / Hub
  • Docker Compose Docker Compose
  • Docker Machine Docker Machine
  • Docker Swarm Docker Swarm
  • …​
Docker Ecosystem

Premiers pas

Installation sous Linux

  • Client
    • Application Linux
  • Serveur
    • Daemon Linux.
Linux

Installation sous Linux

apt-get purge lxc-docker*
apt-get purge docker.io*
curl -fsSL https://get.docker.com/ | sh

Installation sous Linux

# Clés GPG
curl -fsSL https://download.docker.com/linux/ubuntu/gpg              \
   | sudo gpg --dearmor -o /usr/.../docker-archive-keyring.gpg

# Déclarer la source
 echo                                                                \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/...]  \
  https://download.docker.com/linux/ubuntu                           \
  $(lsb_release -cs) stable"                                         \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# C'est bon, on peut installer Docker
apt update
apt install docker-ce

Installation sous Linux

sudo docker help ...
sudo addgroup $USER docker
docker help ...

Installation sous Linux

installation remote
export DOCKER_HOST=docker.sewatech.fr

Installation sous MacOS

  • Client
    • Application MacOS
  • Serveur
    • Linux VM
Windows

Docker Desktop

  • Docker Engine
  • Docker Compose
  • Docker Content Trust
  • Kubernetes
  • Credential Helper
  • Docker Dashboard
  • Development Environments
    (preview)
  • Multi-arch : run et build
    (amd64, arm64v8,…​)
  • $$
    (sous certaines conditions)

Docker Desktop

  • for Mac
    • Processeur Intel
    • MacOS >= 3 dernières versions
    • Double-click, Drag & Drop,…​
  • for Apple silicon
    • Processeur Apple silicon
    • Rosetta 2 optionnel
    • Double-click, Drag & Drop,…​
Docker for Mac

Docker Desktop

brew install --cask docker
brew cask install docker-toolbox

Docker Desktop

brew install docker
brew install docker-compose
brew install docker-machine
brew install ...

Installation sous Windows

  • Client
    • Application Windows
  • Serveur
    • Linux VM
Windows

Docker Desktop

  • for Windows
    (WSL2 backend)
    • WSL2 activé
    • Windows 64bits, 10 ou 11
    • Next, next, next,…​
  • for Windows
    (Hyper-V backend)
    • Hyper-V activé
    • Windows 64bits, 10 ou 11
    • Next, next, next,…​
Docker for Windows

Docker Desktop

choco install docker-desktop
choco install docker-cli
choco install docker-engine

Installation

  • Windows Containers
    • Hyper-V activé
    • Windows 64bits, 10 ou 11
    • Windows Server ⩾ 2016
Windows Container
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider
Restart-Computer -Force
docker container run microsoft/dotnet-samples:dotnetapp-nanoserver
Hors périmètre pour cette formation

Installation

~$ docker version
Client: Docker Engine - Community
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.16.12
 Git commit:        e91ed57
 Built:             Mon Dec 13 11:45:33 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Client: Docker Engine - Community
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.16.12
 Git commit:        e91ed57
 Built:             Mon Dec 13 11:45:33 2021
 OS/Arch:           linux/amd64

Récupérer une image

docker image pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world

c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabd
Status: Downloaded newer image for hello-world:latest

Démarrer un conteneur

docker container run hello-world
Hello from Docker!
This message shows that your installation appears to be working
correctly.

To generate this message, Docker took the following steps:
 1. ...
 2. ...
 3. ...
 4. ...

To try something more ambitious, you can run an
Ubuntu container with:
 $ docker run -it ubuntu bash

...

Conteneurs

Run interactif

docker container run -it alpine
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine

Digest: sha256:c1ce85a0f7126a3b5cbf7c57676b01b37
Status: Downloaded newer image for alpine:latest
/#

Run détaché

docker container run -d httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
386a066cd84a: Already exists
a11d6b8e2fac: Pull complete
c22afc84eb8c: Pull complete
Digest: sha256:10fd24b8d20ffd15cb21d4
Status: Downloaded newer image for httpd:latest
alexis@host ~$

Isolation des conteneurs

/# ls -l /
drwxr-xr-x   2 root root 4096 Nov  4 18:30 bin
drwxr-xr-x   2 root root 4096 Sep 12 04:09 boot
drwxr-xr-x   5 root root  380 Dec  6 23:37 dev
drwxr-xr-x  41 root root 4096 Dec  6 23:37 etc
drwxr-xr-x   2 root root 4096 Sep 12 04:09 home
drwxr-xr-x   9 root root 4096 Nov 27  2014 lib
drwxr-xr-x   2 root root 4096 Nov  4 18:28 mnt
drwxr-xr-x   2 root root 4096 Nov  4 18:28 opt
dr-xr-xr-x 137 root root    0 Dec  6 23:37 proc
...

Isolation des conteneurs

alexis@host ~$ ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 34:f3:9a:9a:8f:b7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.52/24 brd 192.168.11.255 scope global wlp2s0
/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 ...
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0

Isolation des conteneurs

alexis@host:~$ ss -lnt

State   Recv-Q  Send-Q  Local Address     Peer Address
LISTEN  0       4096    127.0.0.1:53      0.0.0.0:*
LISTEN  0       0       [::]:5000         [::]:*
LISTEN  0       0       [::]:8000         [::]:*
...
/# netstat -lnt

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address  Foreign Address  State

Cycle de vie

container lifecycle

Cycle de vie

docker container kill elegant_brahmagupta
docker container stop elegant_brahmagupta

Cycle de vie

docker container run --restart=always ...
docker container run --restart=unless-stopped ...
docker container run --restart=on-failure:3 ...

Cycle de vie

docker container ls
docker container ls -a
docker container ls --filter status=exited

Cycle de vie

docker container rm elegant_brahmagupta
docker container rm 72371f
docker container run -d --rm httpd

Cycle de vie

docker container rm $(docker container ls -f status=exited)
# avec confirmation
docker container prune

# sans confirmation
docker container prune --force

Cycle de vie

docker container inspect elegant_brahmagupta
docker container inspect                           \
            --format "{{ .RestartCount }}"         \
            elegant_brahmagupta
docker container inspect                                     \
          --format "{{json .NetworkSettings.Networks }}"     \
          elegant_brahmagupta

Cycle de vie

docker container exec elegant_brahmagupta          \
                      touch /app/marker
docker container exec -it elegant_brahmagupta bash

Cycle de vie

docker container logs elegant_brahmagupta
docker container logs --tail 10 elegant_brahmagupta
docker container logs --follow elegant_brahmagupta

Legacy commands

avant 1.13

depuis 1.13

docker run

docker container build

docker …​

docker container …​

docker ps

docker container ls

Images

Commande commit

docker container commit elegant_brahmagupta sw/app
docker container run sw/app

Commande build

docker image build -t sw/app .
docker container run sw/app

Commande build

docker image build -t sw/app --file Dockerfile-v2 .
docker image build -t sw/app                       \
          https://github.com/sewatech/app.git
docker image build -t sw/app app.tar.gz

Dockerfile, en-tête

FROM httpd
MAINTAINER Alexis Hassler <alexis.hassler@sewatech.fr>

Dockerfile, shell

RUN apt-get update

Dockerfile, environnement

Ces directives s’appliquent pour le build et le run.

Dockerfile, contenu

COPY site/ /var/www/

Dockerfile, exécution

ENTRYPOINT ["/start.sh"]
CMD ["/start.sh"]
ENTRYPOINT ["/start.sh"]
CMD ["--env=default"]

Dockerfile, exécution

docker container run sw/app --env=dev
docker container run -it debian bash

Dockerfile, échanges

Dockerfile, variables

...
ARG userid=1000
...
USER ${userid}
...
ARG userid
...
USER ${userid:1000}
docker image build --build-arg userid=500 .

Dockerfile, autres métadonnées

LABEL version="1.0"
docker image ls --filter ...
docker image inspect ...
docker container inspect ...

Dockerfile, autres métadonnées

ONBUILD ADD src /app/src
ONBUILD RUN build.sh /app/src

Taille des images

fs layers ro

Taille des images

docker image build -t demo/layers .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM debian
 ---> 73e72bf822ca
Step 2 : RUN apt-get update
 ---> 33b20b7674a7
Step 3 : RUN apt-get install -y wget unzip
 ---> 859c09d07c42
Step 4 : RUN wget http://bit.ly/tomcat85
 ---> 6a209ff5aea1
Step 5 : RUN unzip tomcat85
 ---> 054d0880c62e
Step 6 : RUN rm tomcat85
 ---> 23b9aa4066c0
Successfully built 23b9aa4066c0

Taille des images

docker image ls
REPOSITORY    TAG     IMAGE ID      CREATED       SIZE
demo/layers  latest  23b9aa4066c0  18 hours ago  196.7 MB

Système de fichiers en couches

docker image history demo/layers
IMAGE        CREATED BY                                SIZE
23b9aa4066c0 /bin/sh -c rm tomcat85                    0 B
054d0880c62e /bin/sh -c unzip tomcat85                 13.14 MB
6a209ff5aea1 /bin/sh -c wget http://bit.ly/tomcat85    9.9 MB
859c09d07c42 /bin/sh -c apt-get install -y wget unzip  40.8 MB
33b20b7674a7 /bin/sh -c apt-get update                 9.861 MB
73e72bf822ca /bin/sh -c (nop)  CMD ["/bin/bash"]       0 B
<missing>    /bin/sh -c (nop) ADD file:41ea5187c50115  123 MB

Système de fichiers en couches

docker image build -t demo/layers .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM debian
 ---> 73e72bf822ca
Step 2 : RUN apt-get update && apt-get install -y wget && ...
 ---> Using cache
 ---> ea58a71330a1
Successfully built ea58a71330a1

Système de fichiers en couches

apt-get remove -y unzip wget
apt-get remove -y ca-certificates ... libtasn1-6 openssl unzip wget

Système de fichiers en couches

fs layers sharing

Système de fichiers en couches

time docker image build -t demo/layers .
...
real    2m10.920s
user    0m0.335s
sys     0m0.252s
time docker image build -t demo/layers-bis .
...
real    0m0.254s
user    0m0.012s
sys     0m0.023s

Système de fichiers en couches

Context upload

Système de fichiers en couches

Systèmes nus

Busybox

1 Mo

Alpine

5 Mo

Debian

125 Mo

Ubuntu

130 Mo

CentOS

200 Mo

Fedora

200 Mo

Systèmes avec httpd

Busybox

1 Mo

Alpine

9 Mo

Debian

180 Mo

Ubuntu

225 Mo

CentOS

245 Mo

Fedora

275 Mo

Gérer les images

docker image ls
docker image ls -a
docker image ls --filter "dangling=true"
docker image ls --filter "dangling=false"

Gérer les images

docker image rm da7ff372b5067f5
docker image rm --no-prune da7ff372b5067f5
docker image rm --force da7ff372b5067f5

Gérer les images

docker image rm $(docker image ls -qf "dangling=true")
# uniquement sans tag
docker image prune

# y compris avec tag
docker image prune --all

# sans confirmation
docker image prune --force

Legacy commands

avant 1.13

depuis 1.13

docker build

docker image build

docker …​

docker image …​

docker rmi

docker image rm

docker images

docker image ls

Réseau

Exposition de ports

docker container run --publish-all httpd
docker container port elegant_brahmagupta
docker container run --publish 80 httpd
docker container run --publish 8888:80 httpd
docker container run --publish 127.0.0.1:8888:80 httpd

Types de réseau

docker network ls
NETWORK ID      NAME     DRIVER    SCOPE
444825ec4f4d    bridge   bridge    local
f02e3324a3b7    host     host      local
64c36868c3db    none     null      local

Types de réseau

network bridge

Types de réseau

network host

Types de réseau

network none

Communication entre conteneurs

docker container run --name db postgres
docker container run --name java --link db tomcat
# /etc/hosts
127.0.0.1   localhost
...
172.17.0.3  app 31a1bd554fd6 java

Réseaux personnalisés

network custom

Réseaux personnalisés

docker network create frontend
docker container run --net=frontend --name web sewatech/httpd
docker container run --net=frontend --name app sewatech/tomcat
network custom named
/# ping web

Réseaux personnalisés

Réseaux overlay

network overlay

Volumes

Partage de répertoire

docker container run                                          \
        --volume ${PWD}/web-content:/usr/local/apache2/htdocs \
        httpd
image/svg+xml root:root root:root

Partage de répertoire

docker container run                               \
          --volumes-from othercontainer sw/img1
docker container run                               \
          --volumes-from othercontainer sw/img2
docker container run -d                            \
          --volumes-from cont0 --name cont1 sw/img1
docker container run -d                            \
          --volumes-from cont1 --name cont2 sw/img2

Volumes nommés

docker container run --volume cli-data:/data debian
docker container run --volume /data debian
image/svg+xml root:root root:root

Volumes nommés

docker volume create --name data-vol
docker volume create --name data-vol             \
                     --driver local              \
                     --opt type=tmpfs            \
                     --opt device=tmpfs          \
                     --opt o=size=100m,uid=1000

Volumes nommés

docker volume ls
docker volume ls --filter 'dangling=true'

Volumes nommés

docker container rm --volumes cli
docker volume rm cli-data
docker volume rm                                \
       $(docker volume ls -f 'dangling=true' -q)
docker volume prune

Conteneur de données

docker container create                          \
          --volume /dbdata                       \
          --name datastore alpine /bin/true

Conteneur de données

docker container create                                      \
            --name datastore postgres

  // or (equivalent)

docker container create                                      \
            --volume /var/lib/postgresql/data                \
            --name datastore postgres

  // or (different)

docker container create                                      \
            --volume $PWD/data:/var/lib/postgresql/data      \
            --name datastore postgres
docker container run --volumes-from datastore                \
                     --name dataaccess postgres

Conteneur de données

docker container run --rm                          \
            --volumes-from datastore               \
            --volume $(pwd):/backup                \
            debian tar cvf /backup/backup.tar /data

Sécurité

image/svg+xml root:root root:root

Sécurité

USER toto
USER 1000

Sécurité

docker container run --user toto ...
docker container run --user 1000 ...
docker container run --user 1000:20 ...

Introduction à Docker

@AlexisHassler

THE END