Vous êtes sur la page 1sur 22

Docker 101

Introduction aux containers

Arnaud de
Nous sommes l’architecte Alcabas - 11/06/2019
vos infrastructures
Formateur: Arnaud Alcabas (aalcabas@fr.scc.com)

Pod-cidr 172.18.X.0/24

Nom d'hôtes IP RIE Admin IP LAN Admin Student


formation-moc-stagiaire-1 100.67.226.212 192.168.226.9 Annie
formation-moc-stagiaire-2 100.67.226.149 192.168.226.2 Mahmoud
formation-moc-stagiaire-3 100.67.226.190 192.168.226.12 JC
formation-moc-stagiaire-4 100.67.226.206 192.168.226.10 Bertrand
formation-moc-stagiaire-5 100.67.226.205 192.168.226.7 Serge
formation-moc-stagiaire-6 100.67.226.208 192.168.226.13 Clément
formation-moc-stagiaire-7 100.67.226.191 192.168.226.11 Bruce
formation-moc-stagiaire-8 100.67.226.207 192.168.226.5 Marie-Odile
formation-moc-stagiaire-9 100.67.226.199 192.168.226.8 Edouard

user: cloudadm mdp: Formation201906


T: +33 6 26 94 64 85 E: aalcabas@fr.scc.com france.scc.com Nous sommes l’architecte de vos infrastructures
Container
Définition

La vision commerciale:
• Virtualisation d’OS
• Perception d’environnement isolé et indépendant
• Package déclaratif
• Unité de déploiement «universelle»
• Idéal pour le développement et les tests

La réalité:
• Les mêmes idées que la virtualisation, mais sans virtualisation
• Un « super chroot » s’appuyant sur les mécanismes kernel linux d’isolation
• Principe d'infrastructure consistante et répétable
• Faible overhead par rapport à une VM

Nous sommes l’architecte de vos infrastructures


Mécanisme Kernel
Les outils sous le capot

• Mount namespace (Linux 2.4.19) - vue FS


• PID namespace (Linux 2.6.24) - x PID/process
• Net namespace (Linux 2.6.19-2.6.24) - vues réseaux
• User namespace (Linux 2.6.23-3.8)
• IPC namespace (Linux 2.6.19-2.6.30) - communication entre process
• UTS namespace (Linux 2.6.19) - host et domain
• cgroups (Linux 2.6.24) - gérer la limitation de ressource
• AUFS/BTRFS: FS/couche, mode union, copy on write
En somme, tous les éléments kernel nécessaires sont en place depuis
Linux 2.6.32, mais vraiment stable depuis 3.10
Nous sommes l’architecte de vos infrastructures
Tour d’horizon Il existe d’autres moteurs de containers
La technologie container

Docker n’est que l’évolution d’une • LXD


technologie aussi vieille que • RKT
l’informatique • Railcar
• UNIX chroot (1982) • CRI-O
• BSD Jail (1998) • gVisor
• ParallelsVirtuozzo (2001) • Frakti ( cas particulier)
• Solaris Containers (2005)
• Linux LXC (2008) La version opensource de docker est Moby et
• Docker (2013) s’appuie sur:
• containerd
L’OCI a défini un standard pour la • runc
technologie container
Nous sommes l’architecte de vos infrastructures
Container vs VM
Différence d’isolation

Nous sommes l’architecte de vos infrastructures


Un container à la main
3) chroot: Alpine Linux RootFS
1) cgroup: pwd ➔ /root/
yum install libcgroup-tools -y mkdir rootfs
cgcreate -g cpu,memory:mygroup curl -sSL https://tinyurl.com/y3dpu9ru | tar xz -C rootfs
cgset -r memory.limit_in_bytes=100000000 mygroup chroot $(pwd)/rootfs /bin/ash
cgset -r cpu.shares=512 mygroup pwd ➔ /
cgset -r cpu.cfs_period_us=1000000 mygroup
cgset -r cpu.cfs_quota_us=2000000 mygroup
cgexec -g memory:mygroup python
Python 2.7.5 (default, Jul 13 2018, 13:06:57) 4) tout ensemble:
>>> huge_list = [0] * 10000000000 cgexec -g cpu,memory:mygroup \
Traceback (most recent call last): unshare -uinpUrf --mount-proc \
File "<stdin>", line 1, in <module> /usr/sbin/chroot $(pwd)/rootfs /bin/ash
MemoryError

5) mode facile: runc


2) unshare: yum-config-manager \
echo 640 > /proc/sys/user/max_user_namespaces --add-repo \
unshare -uinpUrf --mount-proc /bin/bash https://download.docker.com/linux/centos/docker-ce.repo
ps -ef yum install containerd.io –y
UID PID PPID C STIME TTY TIME CMD runc spec
root 1 0 0 18:30 pts/0 00:00:00 /bin/bash runc run mycontainer
root 10 1 0 18:30 pts/0 00:00:00 ps -ef
Nous sommes l’architecte de vos infrastructures
Commandes de base
• Utilisation de docker
– Sudo ou non ? Groupe docker ➔ usermod -aG docker <utilisateur>

• Syntaxe de la commande
– A l'ancienne:
• $ docker <command> <options> <image> <commande>

– Exemple:
• $ docker run hello-world

• Avec les regroupements logiques (management commands) depuis la version


1.13:
• $ docker <management command> <command> <options> <image> <commande>

– Exemple:
• $ docker container run hello-world

Nous sommes l’architecte de vos infrastructures


Commandes de base
• $ docker container run -i -t centos /bin/bash
– run : on veut lancer le conteneur
– -i -t : on veut un terminal et être interactif avec lui (peut-être reduit en -it)
– centos : l'image à utiliser pour ce conteneur
– /bin/bash : on lance bash

• En quoi consiste le démarrage du container:


– Recherche de l'image
– Construction du système de fichiers au sens Linux
– Démarrage du container
– Configuration de l'adresse IP du container
– Capture des messages entrées-sorties

Nous sommes l’architecte de vos infrastructures


Les images docker (docker hub)
– Dépôt public (push/pull gratuit)
– Dépôt d'images officielles et d'images tiers,
• Systèmes d'exploitation:
– debian, ubuntu, centos ...
• Mention spéciale:
– alpine: Micro-distribution
– alpine:3.9 : 4.5 Mo
– ubuntu:16:04 : 184 Mo
• Services conteneurisés:
– php, nginx, mariadb, ...
– Collection de services supplémentaires :
• Builds automatisés (lier des dépôts github/bitbucket pour lancer un build suite a un
commit)
– store.docker.com: Réferentiel d'image version entreprise
Nous sommes l’architecte de vos infrastructures
Les commandes de base
• Les images peuvent avoir des tags :
– Les tags symbolisent des différences de version d'une image
– C'est le tag :latest qui est utilise par défaut
• Les images disposent de trois espaces de nom :
– Racine : ubuntu (en réalité library/ubuntu)
– Utilisateur et organisations : myorg/myimage
– Auto-hébergées (le serveur) : localhost:5000/myapache
• Listing, récupération, commit et suppression d’image
– docker images
– docker pull nginx:latest
– docker tag nginx:latest repo-interne:5000/my-nginx:latest
– docker push repo-interne:5000/my-nginx:latest
– docker rmi nginx:latest
Nous sommes l’architecte de vos infrastructures
Manipuler un container existant
• Instancie un conteneur a partir d'une image en mode interactif
docker container run -i -t centos /bin/bash
docker container run -i -t --rm --name myUbuntu ubuntu /bin/bash

• Lance un conteneur en arrière plan • Manipulation container


docker run -d ubuntu docker exec -it myUbuntu /bin/bash
docker start myUbuntu
• Afficher les containers actifs (-a pour ALL) docker stop myUbuntu
docker ps docker kill myUbuntu
docker rm myUbuntu
• Logs du container actifs
docker logs myUbuntu • Infos sur le container
docker inspect myUbuntu

Nous sommes l’architecte de vos infrastructures


Le réseau

• Au démarrage du daemon docker:


– création du bridge "docker0"
– une adresse IP prive ainsi qu'une adresse MAC sont assignées au bridge
– configuration des tables de routage (route et iptables)
• Toute création de container entraine la création de deux paires d'interfaces:
– une dans le container : eth*
– une autre dans la machine hôte : veth*
– toutes les deux reliées au bridge et fonctionne comme un pipe
– génération d'une adresse IP ainsi qu'une adresse MAC pour le container
– configuration de la route par défaut dans le container

Nous sommes l’architecte de vos infrastructures


Réseau dans un container à la main
• Démarrer 2 sessions sur l’host et dans l’une, démarrer un container avec:
cgexec -g cpu,memory:mygroup unshare -uinpUrf --mount-proc /usr/sbin/chroot $(pwd)/rootfs /bin/ash

• Session host
echo 1 > /proc/sys/net/ipv4/ip_forward
yum install bridge-utils –y • Session container
brctl add br0
C_PID=$(ps -ef | grep -m1 unshare | awk '{print $2}’) ip link set up dev veth0
ip link add veth0 type veth peer name veth0 netns $C_PID ip addr add 172.16.0.2/16 dev veth0
brctl addif br0 veth0 ip route add default via 172.16.0.1
ip link set up br0 ping 8.8.8.8
ip link set up veth0
ip addr add 172.16.0.1/16 dev br0
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -o br0 -j ACCEPT
iptables -A FORWARD -i br0 -j ACCEPT
ping 172.16.0.2

Nous sommes l’architecte de vos infrastructures


Les types de réseau
• Il y a en fait plusieurs type de mise en réseau. Le réseau par défaut est de type bridge
(via docker0).

• Mais il est aussi possible de connecter un conteneur au réseau du host sans Namespace
(--network=host) ou sans réseau (--network=none)

$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ae7f1107b7a6 bridge bridge local
1dcfa3617b4e host host local
96b455c9e62f none null local

• Il est aussi possible de créer plusieurs réseau de type bridge avec des subnet différents
pour isoler certains conteneurs et d’ajouter plusieurs « NIC » à un conteneur en
multipliant les flag --network lors du docker run.

Nous sommes l’architecte de vos infrastructures


Le conteneur quel usage?
• Philosophiquement, n’exécute qu'un seul processus a la fois: un
container = une application (ou processus)

• pas d’exécution de daemons, de services, ssh, etc.

• même le processus init n'existe pas (namespace)

• sinon il faut prévoir l'utilisation des outils particuliers tels que


supervisord, forever, ...

• Notion de microservices, stateless/statefull, cloud-ready


Nous sommes l’architecte de vos infrastructures
Les volumes
• Conserver des données quand un conteneur est supprimé
• Partager des fichiers/dossiers entre conteneurs
• Partager des fichiers/dossiers entre hôtes et conteneurs

• Volumes anonymes (docker inspect pour avoir les infos du volume):


– $ docker run -t -i -v /data ubuntu /bin/bash

• Volumes nommés :
– $ docker volume create --name dataVolume
– $ docker run -t -i -v dataVolume:/data:rw ubuntu /bin/bash

• Montage depuis le système hôte :


– $ docker run -t -i -v $(PWD):/data:ro ubuntu /bin/bash
Nous sommes l’architecte de vos infrastructures
La construction d’image
• Il existe 3 méthodes pour construire une image docker:
– image import : charge une archive de fichiers, comme couche de base
$ docker import rootfs.tar monimage:montag

– container commit : crée une nouvelle couche (+ image associée) depuis un


conteneur
$ docker commit moncontainer monimage:montag

– image build : script de suite de commandes de création automatisée


d'image, s’appuyant sur un fichier descriptif ➔ Dockerfile
$ docker build monfolder -t monimage:montag

Nous sommes l’architecte de vos infrastructures


Le language du Dockerfile
• Les instructions les plus utilisées sont peu nombreuses :
– Image de base (ou scratch) : FROM
– Environnement : LABEL, MAINTAINER, ENV, USER, WORKDIR, ARG
– Ajouts de fichiers (contexte) : ADD, COPY
– Commande à la construction de l'image : RUN
– Commandes au lancement du conteneur : CMD, ENTRYPOINT
– Ports/volumes accessibles: EXPOSE, VOLUME
– Autres commandes: ONBUILD, STOPSIGNAL, HEALTHCHECK, SHELL
– ...

https://docs.docker.com/engine/reference/builder/
Nous sommes l’architecte de vos infrastructures
Demo bottom ➔ up
• Build d’un rootfs centos
cat > chroot-centos7.repo << EOF
[centos7-chroot-base]
name=CentOS-7-Base
baseurl=http://mirror.centos.org/centos/7/os/x86_64
gpgcheck=0
[centos7-chroot-epel]
name=Extra Packages for Enterprise Linux 7
baseurl=http://dl.fedoraproject.org/pub/epel/7/x86_64
gpgcheck=0
EOF

mkdir test

yum install -y -c chroot-centos7.repo --disablerepo=* --enablerepo=centos7-chroot-base --enablerepo=centos7-


chroot-epel --disableplugin=* --installroot=$(pwd)/test bash bash-completion vim-minimal yum iproute iputils
rootfiles sudo

cd test && tar czvf ../centos-rootfs.tgz . && cd ..


docker import centos-rootfs.tgz centos:custom

Nous sommes l’architecte de vos infrastructures


Demo bottom ➔ up
• Modification de l’image créée
docker run -it --name temporaire centos:custom /bin/bash
cat<<EOF> /hello
#!/bin/bash
while true; do echo "hello"; sleep 1; done
EOF
chmod +x /hello
exit
docker commit temporaire centos:custom2

• Ajout d’un entrypoint via Dockerfile


cat<<EOF> Dockerfile
FROM centos:custom2
ENTRYPOINT ["/hello"]
EOF
docker build . -t centos:hello
docker run --name montest -d centos:hello
docker logs montest -f

Nous sommes l’architecte de vos infrastructures


Multistage build • Etre capable d'avoir plusieurs FROM dans un
cat<<EOF>hello.go
package main Dockerfile
import "fmt"
func main() {
• Récupérer des artefacts issus des "stages"
fmt.Println("hello world")
} précédents.
EOF
cat<<EOF>Dockerfile
• L’intérêt réside dans la réduction du poids d'une image
FROM golang:latest AS builder
COPY hello.go /
RUN cd / && go build -o hello hello.go • Utile pour des artefacts "construits" dans des stages
FROM alpine:latest
de l'image (ou pour réduire des installations trop
COPY --from=builder /hello /
CMD ["/hello"] lourdes)
EOF
docker build . –t test:go
• Nécessite une version récente de docker (17.05)
docker run –it test:go

docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test go 8765259e19c2 About a minute ago 7.53MB
golang latest 1ef078f0da9e 12 hours ago 774MB
alpine latest 055936d39205 4 weeks ago 5.53MB

Nous sommes l’architecte de vos infrastructures

Vous aimerez peut-être aussi