name: inverse layout: true class: center, middle, inverse --- # Introduction à Docker ## Sébastien Douche — @sdouche .footnote[https://github.com/sdouche/presentation-docker] --- layout: false .left-column[ ## Qui suis je ? ] .right-column[ 39 ans. Français. Pas très intelligent mais j'aime comprendre. - Geek depuis 1984 - Fan de Logiciels Libres depuis 1995 - Développeur (Python, Go, Dart, Rust) - Sysadmin (Linux / BSD) - Responsable technique chez un éditeur logiciel français depuis 2007 - Speaker (Git, Python, Go, Dart, organisation, management...) - Intéressé par le Lifehacking - Adore les jeux de sociétés modernes - Motard (Honda CBR RR) - Aime l'humour noir, le second degré et les blagues pourries ] --- template: inverse # Objectif --- class: center, middle Automatiser le déploiement d'environnements sous forme de conteneurs *légers*, *portables* et *auto-suffisants*. .footnote[http://www.docker.io] --- class: center, middle ## Quel est le problème ? ![](img/the_challenge.jpeg) --- class: center, middle ## La solution Docker ![](img/docker_container.jpeg) --- class: center, middle ![](img/container.jpeg) --- class: center, middle ![](img/container2.jpeg) --- template: inverse # Histoire du conteneur --- class: middle Le premier bateau porte-conteneur, le Ideal-X, part le 26 avril 1956 du port de Newark (New Jersey) vers le port de Houston (Texas). A son bord, 58 conteneurs de 35 pieds. .footnote[35 pieds était le standard USA des camions] --- class: center, middle ![](img/ideal-x.jpeg) --- class: middle Invention de Malcom McLean (1914-2001), magnat dans le transport routier, qui avait calculé que le coût passerait de 5.83$ la tonne à 0.16$ en passant par Ideal-X. Les containeurs ont donc **réduit les coûts de transport cargo de 90%**. Il fonda la société SeaLand, rachetée en 1999 par Maersk, leader mondial du conteneur. --- class: center, middle ![](img/book.jpeg) --- template: inverse # Caractéristiques d'un conteneur --- class: center, middle ## Agnostique sur le contenu --- class: center, middle ## Agnostique sur le transporteur --- class: center, middle ## Isolation --- class: center, middle ## Automatisation --- template: inverse # Docker --- ## Projet jeune * 18/01/2013 : 1er commit * 01/02/2013 : 1ere démo en ligne * 21/03/2013 : 1ere démo à Pycon US * 23/03/2013 : .blue[Version 0.1] * 26/03/2013 : Ouverture du dépôt GitHub * 23/04/2013 : .blue[Version 0.2] * 06/05/2013 : .blue[Version 0.3] * 03/06/2013 : .blue[Version 0.4] * 25/06/2013 : Rejoint la fondation Linux * 18/07/2013 : .blue[Version 0.5] (top, mount) * 23/08/2013 : .blue[Version 0.6] (-privileged, LXC conf) * 19/09/2013 : Partenariat avec Red Hat * 29/10/2013 : Société renommée en Docker * 26/11/2013 : .blue[Version 0.7] (noyau standard, device-mapper, name, links) * 21/01/2014 : Levée de 15M$ * 04/02/2014 : .blue[Version 0.8] (MacOSX, BTRFS experimental, ONBUILD) --- ## Mais très actif Dans le Top 15 sur GitHub. Au 25/09/2013: 3389 commits, 975 PR et 169 contributeurs. Au 13/02/2014: 6183 commits, 4103 PR et 334 contributeurs. --- ## Pré-requis * Kernel 3.8+ (avec Cgroups et namespaces) ou RHEL 2.6.32 * AUFS (ou device-mapper / VFS) * LXC * 64 bits http://docs.docker.io/en/latest/installation/ --- template: inverse # LXC --- class: center, middle ## Permet d'.blue[isoler] l'exécution des applications dans des contexte d'éxécution (VE). ### "chroot on steroids” --- class: center, middle ![](img/archiisolateur.png) --- class: center, middle ## L'intérêt du conteneur est son faible footprint --- template: inverse ## Namespace --- class: center, middle ## Service fournit par le noyau Linux pour gérer l'isolation --- ## Le Mount namespace (Linux 2.4.19) Gère l'isolation des points de montage du système de fichier vus par un groupe de process : * les points de montage ne sont plus globaux mais spécifiques au namespace * les points de montage peuvent être propagés * racine propre (chroot) --- ## Le PID namespace (Linux 2.6.24) Gère l'isolation des ID de process : * PID 1 init-like par namespace * chaque namespace a sa propre numération PID (isolation de l'hôte) * le process d'un namespace ne peut envoyer de systemcall sur un autre process d'un autre PID namespace * gestion de pseudo-filesystem (ex : /proc) vu par le PID namespace qui le monte * un process possède plusieurs PID : un dans le namespace, un en dehors (process vu par l'hôte), davantage en cas de namespaces imbriqués --- ## Le Net namespace (Linux 2.6.19-2.6.24) Gère l'isolation du réseau. Chacun possèdant : * ses interfaces * ses ports * sa table de routage * ses règles de firewall (iptables) * son répertoire /proc/net * INADDR_ANY (0.0.0.0) .footnote[Il est possible de créer des «pair interfaces» (visibles de l'intérieur et de l'extérieur)] --- ## Le User namespace (Linux 2.6.23-3.8) Gère l'isolation des utilisateurs et des groupes en : * séparant les droits selon les différents namespaces * rendant sûr le partage de namespace à des process sans privilège --- ## Le IPC namespace (Linux 2.6.19-2.6.30) Gère l'isolation des ressources IPC : - semaphores - message queues - shared memory segments .footnote[Depuis Linux 2.6.30, il gère aussi les files de messages POSIX] --- ## Le UTS namespace (Linux 2.6.19) Gère l'isolation des identifiants de nom et de domaine. UTS vient de la structure "utsname" passée à l'appel système uname(). UTS voulant dire "UNIX Time-sharing System". --- template: inverse ## Control Groups (cgroups) --- class: center, middle ## Service fourni par le noyau pour gérer la limitation de ressource --- class: center, middle ## On peut voir cela comnme un ulimit pour un groupe de process. --- class: center, middle ## Très pratique car permet de suivre finement des process (systemd l'utilise) et plus généralement pour limiter vos process. --- ## Pseudo-fichiers pour manipuler le groupe ```bash # root@srv1:/sys/fs/cgroup# ls -1 blkio cpu cpuacct cpuset devices freezer hugetlb memory perf_event ``` --- ## Installation de LXC ```bash $ sudo aptitude install lxc lxc-templates ``` --- ## Templates ```bash $ dpkg -L lxc-templates /usr/share/lxc/templates/lxc-altlinux /usr/share/lxc/templates/lxc-oracle /usr/share/lxc/templates/lxc-sshd /usr/share/lxc/templates/lxc-debian /usr/share/lxc/templates/lxc-alpine /usr/share/lxc/templates/lxc-opensuse /usr/share/lxc/templates/lxc-fedora /usr/share/lxc/templates/lxc-archlinux /usr/share/lxc/templates/lxc-busybox /usr/share/lxc/templates/lxc-ubuntu /usr/share/lxc/templates/lxc-ubuntu-cloud ``` --- ## Verification du noyau ```bash $ sudo lxc-checkconfig Kernel configuration not found at /proc/config.gz; searching... Kernel configuration found at /boot/config-3.8.0-31-generic --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: missing Network namespace: enabled Multiple /dev/pts instances: enabled --- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled Macvlan: enabled Vlan: enabled File capabilities: enabled ``` --- ## Exemple de création de VM ```bash $ sudo lxc-create -n test -t ubuntu Checking cache download in /var/cache/lxc/raring/rootfs*amd64 ... Downloading ubuntu raring minimal ... I: Retrieving InRelease I: Failed to retrieve InRelease I: Retrieving Release I: Retrieving Release.gpg ... 'ubuntu' template installed 'test' created ``` --- ## Lancement ```bash $ sudo lxc-start -name test ``` --- template: inverse # AUFS --- class: middle ## Supporte le mode union ```bash $ mount -t aufs -o dirs=/path/to/files1:/path/to/files2 none /path/to/files ``` ## Supporte le Copy On Write (COW) ```bash $ mount -t aufs -o br=/tmp=rw:/bin:ro /srv ``` --- template: inverse # Docker --- ## Terminologie Quelques mots clés : * index : répertoire public (https://index.docker.io/) * image : conteneur en lecture seule (snapshot) * conteneur : élement manipulable * run : créer un conteneur (à partir d'une image) --- ## Installation Ubuntu ```bash sudo sh -c "curl https://get.docker.io/gpg | apt-key add -" sudo sh -c "echo deb http://get.docker.io/ubuntu docker main \ > /etc/apt/sources.list.d/docker.list" sudo apt-get update sudo apt-get install lxc-docker ``` *Note* : Docker est écrit en Go, cela veut dire qu'il n'installe qu'un binaire. --- ## Lancement de Docker ```bash $ sudo /usr/bin/docker -d & ``` --- ## Vérification de l'installation ```xml $ docker Usage: docker [OPTIONS] COMMAND [arg...] A self-sufficient runtime for linux containers. Commands: attach Attach to a running container build Build a container from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders from the containers filesystem to the host path diff Inspect changes on a container's filesystem events Get real time events from the server export Stream the contents of a container as a tar archive history Show the history of an image images List images import Create a new filesystem image from the contents of a tarball info Display system-wide information insert Insert a file in an image inspect Return low-level information on a container kill Kill a running container login Register or Login to the docker registry server logs Fetch the logs of a container port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT top Lookup the running processes of a container ps List containers ... ``` --- ## Commande search Rechercher une image : ```xml $ sudo docker search ubuntu NAME DESCRIPTION STARS OFFICIAL TRUSTED stackbrew/ubuntu XXX 34 ... crashsystems/gitlab-docker XXX 11 [OK] dockerfile/ubuntu XXX 7 [OK] ... ``` Officiel : provient de la société Docker Trusted : traçabilité --- ## Commande pull Récupération d'une image Ubuntu (par défaut avec le tag *lastest*) : ```xml $ sudo docker pull stackbrew/ubuntu Pulling repository stackbrew/ubuntu 3aa646e4f1d2: Download complete 0e5997dad26c: Download complete ddc094db4e2b: Download complete 24ba2ee5d982: Download complete 511136ea3c5a: Download complete b74728ce6435: Download complete 46e4dee27895: Download complete cc7385a89304: Download complete 0ce1be727978: Download complete ``` --- ## Commande history Vérification de son contenu : ```xml $ sudo docker history stackbrew/ubuntu IMAGE CREATED CREATED BY SIZE 3aa646e4f1d2 8 weeks ago /bin/sh -c #(nop) ADD p... 125.9 MB b74728ce6435 8 weeks ago /bin/sh -c #(nop) MAINT... 0 B 511136ea3c5a 8 months ago 0 B ``` --- ## Commande images Lister les images : ```xml $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE stackbrew/ubuntu 13.10 24ba2ee5d982 8 weeks ago 144.6 MB stackbrew/ubuntu saucy 24ba2ee5d982 8 weeks ago 144.6 MB stackbrew/ubuntu raring 0e5997dad26c 8 weeks ago 133.6 MB stackbrew/ubuntu 13.04 0e5997dad26c 8 weeks ago 133.6 MB stackbrew/ubuntu 12.10 ddc094db4e2b 8 weeks ago 127.6 MB stackbrew/ubuntu quantal ddc094db4e2b 8 weeks ago 127.6 MB stackbrew/ubuntu 12.04 3aa646e4f1d2 8 weeks ago 125.9 MB stackbrew/ubuntu latest 3aa646e4f1d2 8 weeks ago 125.9 MB stackbrew/ubuntu precise 3aa646e4f1d2 8 weeks ago 125.9 MB ``` --- ## Commande run (1) Lancement d'un shell : ```xml sudo docker run -i -t stackbrew/ubuntu /bin/bash root@419eed6ff306:/# ``` --- ## Commande run (2) Lancer une commande : ```xml $ sudo docker run stackbrew/ubuntu /bin/echo hello world hello world ``` --- ## Commande run (3) Lancer une application : ```xml $ ID=$(sudo docker run -d stackbrew/ubuntu /bin/sh \ -c "while true; do echo hello world; sleep 1; done") $ echo $ID f684fc88aec3 ``` --- ## Commande run (4) On peut nommer un conteneur : ```xml $ sudo docker run -d -name redis sdouche/redis ``` --- ## Commande run (5) Et lier deux conteneurs : ```xml $ sudo docker run -t -i -link redis:db -name webapp ubuntu bash ``` --- ## Commande ps Lister les conteneurs lançés : ```xml $ sudo docker ps ID IMAGE COMMAND CREATED f684fc88aec3 stackbrew/ubuntu:latest /bin/sh *c while tru 33s ago ``` **Note** : option -a pour voir tous les conteneurs. --- ## Commande logs Afficher la console : ```xml $ docker logs f684fc88aec3 hello world hello world hello world hello world hello world ``` --- ## Commande attach Attacher un conteneur : ```xml $ docker attach f684fc88aec3 hello world hello world hello world ``` --- ## Commande stop Arrêter un conteneur : ```xml $ docker stop f684fc88aec3 ``` **Note** : la commande pour lancer est... start. --- ## Exposer un port Associer un port du conteneur avec un port de la machine hôte : ```xml $ sudo docker run -d -p 8888:80 ubuntu ``` **Note** : par défaut, les ports du conteneur ne sont accessibles que depuis la machine hôte --- ## Exposer un volume Monter le répertoire d'un autre conteneur : ```xml $ ID=(sudo docker run -d -v /srv stackbrew/ubuntu) $ sudo docker run -d -volumes-from=$ID stackbrew/ubuntu ``` --- ## Commande commit Enregistre la différence entre l'image et le conteneur : ```xml $ sudo docker run -i -t stackbrew/ubuntu /bin/bash root@419eed6ff306:/# apt-get install nginx ... $ sudo docker commit -m "Ubuntu with Nginx" f684fc88aec3 sdouche/nginx ``` --- template: inverse # Dockerfile --- class: center, middle ## Langage de script pour automatiser la création d'images Tutorial : http://www.docker.io/learn/dockerfile/ --- ## Exemple simple ```xml FROM ubuntu:quantal MAINTAINER Sebastien Douche sdouche@gmail.com RUN echo "deb http://fr.archive.ubuntu.com/ubuntu quantal main " \ > /etc/apt/sources.list RUN apt-get update RUN apt-get install -y nginx ENTRYPOINT ["nginx"] EXPOSE 80 ``` --- ## Résultat ```xml $ sudo docker build -t sdouche/nginx . Uploading context 10240 bytes Step 1 : FROM ubuntu ---> 8dbd9e392a96 Step 2 : MAINTAINER Sebastien Douche sdouche@gmail.com ---> Using cache ---> 1ed956422d1e Step 3 : RUN echo "deb http://fr.archive.ubuntu.com/ubuntu quantal main" > /etc/apt/sources.list ---> Running in 0f306df45690 ---> 769ee79eb920 Step 4 : RUN apt-get update ---> Running in ab6e03a4b456 ... ---> 70c4d6981ec2 Step 5 : RUN apt-get install -y nginx-full ---> Running in 4f9b62e09cef ... ---> 3fdbac5a8b0b Step 6 : ENTRYPOINT ["nginx"] ---> Running in 887a4e981b5b ---> 641d26bd702a Step 7 : EXPOSE 80 ---> Running in fedd77ac26f7 ---> 9d0045d5fa7a Successfully built 9d0045d5fa7a ``` --- ## Commande diff Affiche les différences avec le conteneur père : ```xml $ sudo docker diff 769ee79eb920 2013/10/05 03:01:25 GET /v1.5/containers/769ee79eb920/changes C /dev A /dev/kmsg C /etc/apt/sources.list ``` --- ## Commande push Pousser une image sur l'index (ici avec le compte sdouche) : ```xml $ sudo docker push sdouche/nginx ``` --- ## Commande import / export Exporter : ```xml $ sudo docker export 9d0045d5fa7a > container-nginx.tgz ``` Importer : ```xml $ sudo docker import http://example.com/image.tgz example $ cat example.tgz | sudo docker import - example $ sudo tar -c . | docker import - exampledir ``` --- ## Documentation CLI Liste des commandes : http://docs.docker.io/en/latest/reference/commandline/ --- ## API http://docs.docker.io/en/latest/reference/api/ * API REST * Feed des evenements * Websocket **Note** : la CLI n'est qu'un client pour l'API --- ## Clients * Python (docker-py) * Ruby (docker-client, docker-api) * Javascript (docker.io, docker-js, dockerui) * Java (docker-java) * Erlang (erldocker) * Go (go-dockerclient) --- ## Exemple avec (docker-py) Python ```python import docker # create client docker_client = docker.Client(base_url='unix://var/run/docker.sock', version="1.4") # create container container = docker_client.create_container('ubuntu', None, detach=True) container_id = container.get('Id') # start Container docker_client.start(container_id) # get Ip address meta = docker_client.inspect_container(container_id) ip = meta.get('NetworkSettings').get("IPAddress") # stop container docker_client.stop(container_id) ``` --- ## Docker Index Dépôt public des images (+ metadonnées) https://index.docker.io/ --- ## Registry Index privé https://github.com/dotcloud/docker-registry --- template: inverse # Ecosystème --- ## MacOS * boot2docker est une distribution Linux légere (~27MB en RAM et se lance en ~5s), dérivée de la distribution Tiny Core Linux et conçue pour Docker. http://boot2docker.io/ --- ## GUI * Dockland - Yet another docker web UI https://github.com/dynport/dockland * Shipyard – a web UI for Docker https://github.com/ehazlett/shipyard * DockerUI – Web interface to interact with the Docker Remote API https://github.com/crosbymichael/dockerui --- ## Hébergement * flynn https://flynn.io/ * Orchard https://orchardup.com/ * Stardock https://stackdock.com/ * Tutum http://www.tutum.co/ * Quay https://quay.io/ --- ## Orchestration * Serf http://www.serfdom.io/ * Maestro NG https://github.com/signalfuse/maestro-ng * Shipper https://github.com/mailgun/shipper --- ## Intégration continue * Shippable https://www.shippable.com/ * Drone https://github.com/drone/drone --- ## Environnement de dev * fig http://orchardup.github.io/fig/ --- ## Autres * IAAS : OpenStack * SCM : Chef / Puppet / Salt / Ansible * OS : CoreOS --- ## Docker 1.0 Ce qui est prévu : * Architecture pluggable * Support OpenVZ, FreeBSD Jails, Solaris Zones * Meilleur support des distributions non Ubuntu * Support de BTRFS (déjà là en beta) * Intégration avec Libvirt * Gestion des Index privés payants sur docker.io --- template: inverse # Démo --- template: inverse ## That's all folks!