{{ https://www.docker.com/sites/all/themes/docker/assets/images/Logo-Docker.svg?240}} ====== Docker ====== {{ http://sdz-upload.s3.amazonaws.com/prod/upload/Schema-conteneur-VM.png?320}} Docker propose des conteneurs logiciels, les conteneurs partagent le même système d'exploitation (noyaux, processus d'initialisation, drivers réseaux ...). ===== Principes ===== Docker propose un certains nombre d'images « standard » notamment: * Ubuntu * Debian * CentOS Toute les images sont dérivé de ces trois **images via un système d'héritage**. Chaque image est créé depuis l'état de base d'une de ces images et y ajoute des fonctionnalités (installation d'un logiciel, configuration d'un automatisme…) et il est possible de faire hériter une image d'une autre image qui hérite elle même d'une autre image et cela de façon infini. De plus Docker offre un mécanisme très intéressant pour minimiser la taille de disque nécessaire à la mise en place de ces images. Docker met en place le **système de fichier UnionFS** (//a layered copy-on-write filesystem, which means that the container image's filesystem is a culmination of multiple read-only filesystem layers. And these layers are shared between running containers//) pour le système de fichier de ses conteneurs et de ses images. Celui-ci permet de monter plusieurs systèmes de fichier sur un unique point de montage dans un ordre précis, le fichier utilisé pour un chemin sera le dernier monté. Docker propose un **dépôt communautaire** appelé le [[https://hub.docker.com/|Hub Repository]] qui propose les images de base des différentes distributions mais aussi des images officiels empaquetant des logiciels près à l'emploi comme MySQL ou PHP ... Voir aussi le pendant en mode Dockerfile http://dockerfile.github.io La pile Docker est composer d'une daemon (//needs root privileges//) qui s'occupe de faire "tourner" les conteneurs, et d'un client (//no root privileges//) pour interagir avec le daemon (//via a RESTful API on default port 2375//). L'isolation des conteneurs est réalisée avec les ''Namespaces'' ([[https://www.kernel.org/doc/Documentation/namespaces/|namespace doc]]) du noyau Linux, la limitation des ressources avec les ''Control groups'' (cgroups [[https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt|v1]] / [[https://www.kernel.org/doc/Documentation/cgroup-v2.txt|v2]]). Aussi par défaut, modifiable avec ''--cap-add'' ''--privileged'' ''--security-opts'', l'utilisateur ''root'' est limité, certains privilèges lui sont retirés: * Mount/unmount devices * Managing raw sockets * Filesystem operations such as creating device nodes and changing file ownerships Deux modes de fonctionnements pour les conteneurs: le **mode interactif et le mode daemon**. Le mode interactif lance le conteneur au premier plan et vous permet d'intéragir avec lui, tandis que le mode daemon lance le conteneur en arrière plan et rend la main. Docker recommande un seul processus par conteneur. Mais la commande ''exec'' (//docker v1.3+//) permet d'injecter un processus pour se "connecter" à un conteneur en exécution. Docker affecte une adresse ip à chacun des conteneurs. Pour faciliter les connexions entre eux il y a les ''links'' de la forme ''--link CONTAINER_IDENTIFIER:ALIAS''. La construction d'image Dockerfile peut-être décrite dans un fichier **[[#Dockerfile]]** (//like a Makefile//). ===== Documentation ===== * [[https://docs.docker.com/engine/userguide/|Docker Engine user guide]] * [[https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/|Best practices for writing Dockerfiles]] [[https://blog.imirhil.fr/2016/10/09/docker-container-hell.html|Docker et la tendance de la conteneurisation : a-t-elle vraiment été en production ?]] 2016-10-09 Cheat sheets: * [[https://github.com/wsargent/docker-cheat-sheet|Docker Cheat Sheet]] by wsargent * [[https://www.cheatography.com/aabs/cheat-sheets/docker-and-friends/|docker-and-friends]] by Andrew Matthews (aabs) Tutos * Livre Blanc Docker en français par TheCodingMachine (DAVID NEGRIER, juin 2015): [[http://www.thecodingmachine.com/livre-blanc/docker/|Docker, à quoi ça sert ?]] * Cours en construction sur OpenClassRooms: [[https://openclassrooms.com/courses/2958481?status=waiting-for-publication|Mettre en place des conteneurs logiciel avec docker…]] par Pierre Pélisset Livres: * [[https://www.packtpub.com/virtualization-and-cloud/build-your-own-paas-docker|Build Your Own PaaS with Docker]] 22€ * [[https://www.packtpub.com/virtualization-and-cloud/learning-docker|Learning Docker]] 36€ * [[https://dockerbook.com/|The Docker Book]] by James Turnbull - 10$ epub/pdf ==== Installation ==== * Ubuntu: https://docs.docker.com/engine/installation/linux/ubuntulinux/ * Debian: https://docs.docker.com/engine/installation/linux/debian/ $ cat /etc/apt/sources.list.d/docker.list # Docker # https://docs.docker.com/engine/installation/debian/#debian-jessie-80-64-bit # # PGP Key: # apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D deb https://apt.dockerproject.org/repo debian-jessie main Ajouter son user au group docker $ sudo groupadd docker # Adds the docker group (s'il n'existe pas déjà) $ sudo gpasswd -a $(whoami) docker # Adds the current user to the docker group $ sudo service docker restart # logout / login for changes takes effect ==== Commandes ==== === docker run === Lancer un conteneur: # mode interactif: # -i active le mode interactif, # -t active le mode tty qui permet d'afficher la sortie standard docker run -t -i ubuntu:latest if you are running short-term foreground processes, add ''--rm'' option. Voir [[https://docs.docker.com/engine/reference/run/|reference/run]] === docker start === Relancer un container arrếté (exited) docker start -i === docker ps === Lister les conteneurs: # -a pour tous les conteneurs, quelque soit leur statut (up, exited, terminated) docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ... === docker inspect === # docker inspect ... === docker exec === Pour lancer un nouveau processus dans un conteneur en cours d'exécution, par exemple un shell pour inspecter son état de santé : # $ docker exec -it bash ... === docker images === * Docker [[https://docs.docker.com/engine/reference/commandline/images|images]] Usage: docker images [OPTIONS] [REPOSITORY[:TAG]] List images -a, --all Show all images (default hides intermediate images) --digests Show digests -f, --filter=[] Filter output based on conditions provided --help Print usage --no-trunc Don't truncate output -q, --quiet Only show numeric IDs === docker commit === [[https://docs.docker.com/engine/reference/commandline/commit/|commit reference]] === docker save === docker save -o ou docker save | bzip2 > -o === docker cp === Pour copier un fichier du container vers le host; docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH === docker volume rm === docker volume rm [OPTIONS] VOLUME [VOLUME...] ==== Dockerfile ==== * [[https://docs.docker.com/engine/reference/builder/|Dockerfile reference]] * [[https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/|Best practices for writing Dockerfiles]] ===== Orchestration ===== With **Docker Machine**, we have provisioned the Docker daemons. With **Docker Swarm**, we can rest assured that we'll be able to control our containers from anywhere and that they'll remain available if there are any failures. **Docker Compose** helps us compose our distributed applications on top of this cluster. * http://blog.docker.com/2014/12/announcing-docker-machine-swarm-and-compose-for-orchestrating-distributed-apps/ ==== Swarm ==== Ajoute au Docker client des fonctionnalités (libswarm) de gestion de cluster. https://github.com/docker/swarm/ ==== Compose (docker-composer) ==== Docker Compose permet de créer et configurer un ensemble de conteneurs avec un fichier YAML. * Documentation: [[https://docs.docker.com/compose/|Docker compose]] * Source: https://github.com/docker/compose Tutos / Exemples: * [[https://github.com/EtreRe/docker-compose-baseimage|Nginx, PHP FPM, MariaDB and Memcache with Docker Compose based on Baseimage Flatten]] ==== Docker Machine ==== https://github.com/docker/machine $ machine create -d [infrastructure provider] [provider options] [machine name] ==== Docker Desktop ==== https://docs.docker.com/desktop/ ==== Rancher ==== [[http://rancher.com/rancher/|Rancher]] natively supports and manages all of your Kubernetes, Mesos, and Swarm clusters. ===== Images Docker ===== ==== nginx-proxy & acme-companion ==== * https://github.com/nginx-proxy/nginx-proxy https://github.com/jwilder/nginx-proxy * https://github.com/nginx-proxy/acme-companion C'est le reverse proxy pour d'autres containers fournissant des services web. Accompagné de ''acme-companion'' on obtient le HTTPS LetsEncrypt automatique. acme-companion is a lightweight companion container for nginx-proxy. It handles the automated creation, renewal and use of LetsEncrypt SSL certificates for proxied Docker containers through the ACME protocol. * Automated creation/renewal of Let's Encrypt (or other ACME CAs) certificates using acme.sh. * Let's Encrypt / ACME domain validation through http-01 challenge only. * Automated update and reload of nginx config on certificate creation/renewal. * Support creation of Multi-Domain (SAN) Certificates. * Creation of a Strong Diffie-Hellman Group at startup. * Work with all versions of docker. {{ https://raw.githubusercontent.com/nginx-proxy/acme-companion/main/schema.png?460 }} Les 2 dans un docker-compose et le tour est joué: volumes: conf: vhost: html: dhparam: certs: acme: services: nginx-proxy: image: nginxproxy/nginx-proxy container_name: nginx-proxy ports: - "80:80" - "443:443" volumes: - conf:/etc/nginx/conf.d - vhost:/etc/nginx/vhost.d - html:/usr/share/nginx/html - dhparam:/etc/nginx/dhparam - certs:/etc/nginx/certs:ro - /var/run/docker.sock:/tmp/docker.sock:ro network_mode: bridge acme-companion: image: nginxproxy/acme-companion container_name: nginx-proxy-acme volumes_from: - nginx-proxy volumes: - certs:/etc/nginx/certs:rw - acme:/etc/acme.sh - /var/run/docker.sock:/var/run/docker.sock:ro network_mode: bridge Il suffit ensuite de lancer des containers avec les ENV qui vont bien: docker run -d -p 8000:8000 --name dokuwiki -v $(pwd)/data:/data \ --env "VIRTUAL_HOST=backup-01.comptoir.net" \ --env "VIRTUAL_PORT=8000" \ --env "LETSENCRYPT_HOST=toto.comptoir.net" \ --env "LETSENCRYPT_EMAIL=toto@comptoir.net" \ crazymax/dokuwiki:latest Et voilà le container ''dokuwiki'' est automatiquement prit en charge par ''nginx-proxy'' et sont certificat https généré par ''acme-companion'' :-) Il reste un mauvais point: le container ''dokuwiki'' est accessible (LISTEN) sur le ''host'', il faut donc activer et configurer un firewall.\\ J'ai essayé avec des ''network'' mais ne suis pas arrivé à isoler les container vhosts. On le voit sur le port ''32771'' : # netstat -tanp | grep LISTEN tcp 0 0 0.0.0.0:30001 0.0.0.0:* LISTEN 670/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 937/exim4 tcp6 0 0 :::32771 :::* LISTEN 22408/docker-proxy tcp6 0 0 :::80 :::* LISTEN 21823/docker-proxy tcp6 0 0 :::30001 :::* LISTEN 670/sshd tcp6 0 0 ::1:25 :::* LISTEN 937/exim4 tcp6 0 0 :::443 :::* LISTEN 21811/docker-proxy ==== webdevops ==== Dockerfiles from WebDevOps for PHP, Apache and Nginx (with PHP5 and PHP7) https://hub.docker.com/r/webdevops/ https://github.com/webdevops/Dockerfile ==== mariadb ==== https://hub.docker.com/_/mariadb/ https://github.com/docker-library/mariadb Exemple pour accéder au serveur mysql depuis l'hôte: $ docker exec -it mysqladmin -u root -p variables ==== etherpad-lite ==== By tvelocity: * https://hub.docker.com/r/tvelocity/etherpad-lite/ * https://github.com/tvelocity/dockerfiles/tree/master/etherpad-lite By Etherpas team: * https://github.com/ether/etherpad-docker Une image fullstack (Etherpad-lite, Nodejs, MariaDb, Abiword & Tidy): * [[https://framagit.org/Cyrille37/docker-etherpadlite-fullstack|docker-etherpadlite-fullstack]] ==== openssh ==== Easily launch two hosts waiting for you on SSH port 22, with docker-compose -> https://gitlab.com/Artefacts/docker-openssh-hosts ===== Tips & tricks ===== ==== Mise à jour ==== En cas de mise à jour de l'application, nous recréerons l'image en empaquetant la mise à jour de l'application, puis nous détruiront le conteneur pour le relancer avec l'image mis à jour. > Il est possible mais pas conseiller de faire la mise à jour d'une application dans un conteneur, on préférera mettre à jour l'image puis recréer un conteneur avec l'image mis à jour. Exemple: docker pull mysql docker stop my-mysql-container docker rm my-mysql-container docker run --name=my-mysql-container --restart=always \ -e MYSQL_ROOT_PASSWORD=mypwd -v /my/data/dir:/var/lib/mysql -d mysql ==== Copier une image ==== Pour utiliser une image construite sur une machine il faut l'exporter et l'importer sur l'autre machine. # Export docker save cyrille/seriously:v1 | gzip -9 > cyrille-seriously-v1.tgz # Import gunzip cyrille-seriously-v1.tgz | docker load Loaded image: cyrille/seriously:v1 # Pour les images sans tag: docker tag 4e1a2b349b09 some/project:v1 ==== Faire le ménage ==== Show docker disk usage : $ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 42 4 3.469GB 3.038GB (87%) Containers 11 0 177.4MB 177.4MB (100%) Local Volumes 6 3 688.1MB 266.4MB (38%) Build Cache 0 0 0B 0B [[https://docs.docker.com/engine/reference/commandline/system_prune/|docker system prune]] $ sudo docker system prune WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all dangling images - all dangling build cache Are you sure you want to continue? [y/N] y ... * Remove all stopped containers : ''docker container prune'' * Remove unused images : ''docker image prune'' * Remove all unused networks : ''docker network prune'' ==== Container’s configuration ==== * [[http://blog.octo.com/en/docker-containers-configuration/|Docker container’s configuration]] ==== Intégration système ==== === Démarrage du système === Comment démarrer les conteneurs au démarrage du système ? * [[https://docs.docker.com/engine/admin/host_integration/|Automatically start containers]] * [[https://docs.docker.com/engine/reference/run/#restart-policies-restart|Restart policies (--restart)]] === Limites système === * [[https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources|Runtime constraints on resources]] * memory, swap, access, ... == Memory == WARNING: Your kernel does not support memory limit capabilities. Limitation discarded. Il faut activer cgroup.memory Dans /etc/default/grub modifier: GRUB_CMDLINE_LINUX="cgroup_enable=memory" Puis run update-grub2 reboot Et vérifier : $ cat /proc/cgroups ==== Multi Process Docker Images ==== * [[http://tech.paulcz.net/2014/12/multi-process-docker-images-done-right/|Multi Process Docker Images Done Right]] by Paul Czarkowski * [[https://docs.docker.com/engine/admin/using_supervisord/|Using Supervisor with Docker]] on docs.docker.com Supervisord is a very lightweight process manager. ==== Setting up an apt-cacher ==== When you have multiple Docker servers, or when you are building multiple unrelated Docker images, you might find that you have to download packages every time. This can be prevented by having a caching proxy in-between the servers and clients. It caches packages as you install them. If you attempt to install a package that is already cached, it is served from the proxy server itself, thus reducing the latency in fetching packages and greatly speeding up the build process. Let's write a Dockerfile that sets up an apt-caching server as a caching proxy server: FROM ubuntu VOLUME ["/var/cache/apt-cacher-ng"] RUN apt-get update ; apt-get install -yq apt-cacher-ng EXPOSE 3142 RUN echo "chmod 777 /var/cache/apt-cacher-ng ;" + "/etc/init.d/apt-cacher-ng start ;" + "tail -f /var/log/apt-cacher-ng/*" >> /init.sh CMD ["/bin/bash", "/init.sh"] This Dockerfile installs the apt-cacher-ng package in the image and exposes port 3142 (for the target containers to use). Build the image using this command: $ sudo docker build -t shrikrishna/apt_cacher_ng Then run it, binding the exposed port: $ sudo docker run -d -p 3142:3142 --name apt_cacher shrikrishna/apt_cacher_ng To see the logs, run the following command: $ sudo docker logs -f apt_cacher Using the apt-cacher while building your Dockerfiles: So we have set up an apt-cacher. We now have to use it in our Dockerfiles: FROM ubuntu RUN echo 'Acquire::http { Proxy "http://:3142"; };' >> /etc/apt/apt.conf.d/01proxy In the second instruction, replace the '''' command with your Docker host's IP address (at the docker0 interface) ==== Docker Compose ==== * Here is a docker compose for Laravel (example) : https://github.com/edbizarro/ambientum