Docker : Tutoriel pour manipuler les conteneurs

Posté par  (site web personnel) . Édité par NeoX, Davy Defaud, tuiu pol et Benoît Sibaud. Modéré par Nÿco. Licence CC By‑SA.
35
30
mar.
2014
Virtualisation

Docker (présenté ici‐même la semaine dernière) est un logiciel à mi‐chemin entre la virtualisation applicative et l’automatisation.
Il a l’avantage de ne virtualiser que la partie application et pas du tout la partie système ni le noyau.
Il étend le principe des conteneurs Linux (LXC).

Docker Inc. (anciennement Dotcloud) qui développe Docker, propose aussi un système minimaliste (CoreOS), Docker pouvant virtualiser aussi bien une application qu'un système complet. NdM : comme signalé dans un commentaire, Docker Inc. n'est pas à l'origine de CoreOS, qui est géré par CoreOS, Inc.

Installation (Debian/Ubuntu)

Créer le fichier /etc/apt/sources.list.d/docker.list et écrire ça dedans :

deb http://get.docker.io/ubuntu docker main

Télécharger la clé GPG et installer le paquet :

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
apt-get update
apt-get install lxc-docker

Manipulation d’images

Prendre une Debian sur le dépôt officiel de Docker et se connecter dessus :

docker pull debian
docker run -i -t debian /bin/bash

Faire tout ce qu’on veut sur la nouvelle image

root@xxxxxx# ...

Et sauvegarder les changements

root@xxxxxx# exit
docker commit xxxxxx le_nom_de_l_image

Supprimer les images :

docker rmi id_ou_nom_de_l_image

Création d’images par Dockerfile

Les principales directives des fichiers Dockerfiles :

  • MAINTAINER : nom et courriel de mainteneur du conteneur ;
  • FROM : image de base (Ubuntu, Debian) ;
  • VOLUME : point de montage ;
  • RUN : commande à exécuter pour installer le conteneur ;
  • ENTRYPOINT : commande qui s’exécute au démarrage du conteneur (une seule sera exécutée) ;
  • CMD : commande qui s’exécute au démarrage du conteneur ;
  • ADD : copier un fichier du répertoire courant dans le système de fichiers du conteneur ;
  • USER : utilisateur qui exécute les commandes dans le conteneur ;
  • EXPOSE : port(s) à exposer à l’extérieur.

Manipuler un conteneur

JOB1=$(docker run -d conteneur)
docker logs $JOB1
docker stop $JOB1

Voir les conteneurs qui tournent :

docker ps

ou

docker ps -a

Supprimer un ou tous les conteneurs :

docker rm $JOB1
docker rm id_du_conteneur
docker rm `docker ps -a -q`

Construire un conteneur

Créer un fichier nommé Dockerfile avec les directives Docker, puis :

docker build -t nom_du_conteneur .

Exemple de Dockerfile : LAMP - MariaDB

Dockerfile

# lamp (d'un M qui veut dire Maria)
# Pour Debian Wheezy
#
# VERSION 0.0.1
#

FROM debian:wheezy
MAINTAINER Nico Dewaele "nico@adminrezo.fr"

ENV DEBIAN_FRONTEND noninteractive

# Depots, mises a jour et installs de Apache/PHP5

RUN echo "deb http://ftp.fr.debian.org/debian/ wheezy main non-free contrib" > /etc/apt/sources.list
RUN (apt-get update && apt-get upgrade -y -q && apt-get dist-upgrade -y -q && apt-get -y -q autoclean && apt-get -y -q autoremove)
RUN apt-get install -y -q vim ssh supervisor python-software-properties apache2 libapache2-mod-php5 php5-cli php5-mysql

# Installation et configuration de MariaDB

RUN apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
RUN add-apt-repository 'deb http://mirrors.linsrv.net/mariadb/repo/5.5/debian wheezy main'
RUN apt-get update && apt-get install -y mariadb-server
RUN service mysql start
RUN mysql -v -uroot -e'UPDATE user SET host = "%" WHERE user = "root" LIMIT 1; DELETE FROM user WHERE user = "root" AND host != "%"' mysql
RUN service mysql stop

# Config de Apache

ADD foreground.sh /etc/apache2/foreground.sh
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2

# Verification de PHP

ADD index.php /var/www/index.php
#RUN rm /var/www/index.html

# Demarrage des services

RUN mkdir -p /var/log/supervisor
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ADD start.sh /start.sh

EXPOSE 80 22
# Si MariaDB doit être exposée à l'extérieur
# EXPOSE 3306

CMD ["/bin/bash", "-e", "/start.sh"]

foreground.sh

#!/bin/bash

read pid cmd state ppid pgrp session tty_nr tpgid rest < /proc/self/stat
trap "kill -TERM -$pgrp; exit" EXIT TERM KILL SIGKILL SIGTERM SIGQUIT

source /etc/apache2/envvars
apache2 -D FOREGROUND

start.sh

#!/bin/bash
supervisord

supervisord.conf

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=true

[program:httpd]
command=/usr/sbin/apache2ctl start
stopsignal=6

[program:mariadb]
command=/usr/sbin/mysqld
stdout_logfile=/tmp/%(program_name)s.stdout
stderr_logfile=/tmp/%(program_name)s.stderr
stopsignal=6

Aller plus loin

  • # ce post tombe bien...

    Posté par  (site web personnel) . Évalué à 4.

    j'ai été très intéressé par l'article sur docker d'il y a quelques jours et je comptais justement installer un petit lab sur ma machine… /mavie.

    Merci pour cette intro.

    • [^] # Re: ce post tombe bien...

      Posté par  (site web personnel) . Évalué à 2.

      Tu verras, la doc officielle est bien faite aussi.
      Sinon tu peux prendre exemple sur plein de fichiers Dockerfiles ; Il suffit de taper "Docker" dans github …

  • # Compatibilité 32 bits ?

    Posté par  . Évalué à 1.

    Docker ne supporte pas nativement les architectures 32 bits. Est ce que certains d'entre vous sont tout de même parvenus à l'installer ?

  • # CoreOS != dotCloud et autres corrections

    Posté par  (site web personnel) . Évalué à 3.

    A ma connaissance, CoreOS n'est pas du tout développé par les gens de dotCloud, l'entreprise à l'origine de Docker, dont le nom a d'ailleurs été changé en octobre dernier en Docker Inc (http://blog.docker.io/2013/10/dotcloud-is-becoming-docker-inc/).

    CoreOS n'«hypervise» pas non plus de conteneur vu qu'il n'y a tout simplement pas d'hyperviseur dans CoreOS vu que les conteneurs sont une technologie différentes des hyperviseurs et des machines virtuelles.

    Docker peut «virtualiser» (sens large) aussi bien une application qu'un système complet (toujours sans le noyau). L'intérêt de Docker réside principalement dans son mécanisme de gestion des images et des «recettes» pour les construire.

  • # Bug et interrogation

    Posté par  . Évalué à 3.

    Merci pour la dépêche. Pour l'instant je fais du LXC avec des scripts maison sur du Btrfs pour gérer les snapshots et je voulais essayer docker qui a l'air plus robuste. Il y a un truc que je n'arrive pas bien à comprendre avec docker, c'est le statut des containers vis à vis du système de snapshot.

    Par exemple, le Dockerfile donné en exemple plante au milieu (à la ligne RUN mysql…). Résultat je me retrouve avec 11 nouveaux containers (docker ps -a). Ils correspondent donc à un snapshot après chaque commande du Dockerfile ? J'en fait quoi ? Ils vont m'être inutiles. Je sais qu'ils ne consomment presque pas de place mais si ils continuent à s'empiler, je vais avoir du mal à retrouver ceux qui me sont utiles.

    L'autre truc c'est le Dockerfile donné ne contient aucun ENTRYPOINT. Cela veut-il dire que pour lancer le container crée, il faudra que j'indique à chaque fois le script start.sh ?

    • [^] # Re: Bug et interrogation

      Posté par  (site web personnel) . Évalué à 1.

      Pour supprimer tous les containers :
      docker rm `docker ps -a`

      Le entrypoint sert à effectivement à exécuter une commande au lancement de la machine :
      https://www.docker.io/learn/dockerfile/level2/

      Ici, c'est la directive CMD qui fait le boulot :
      http://docs.docker.io/en/latest/reference/builder/#cmd

      Du coup quand je lance docker run -d maria
      Je peux voir mon lamp fonctionner (docker ps me dit que les ports 80 et 22 sont en écoute).

      • [^] # Re: Bug et interrogation

        Posté par  . Évalué à 1.

        Pour supprimer tous les containers :
        docker rm docker ps -a

        Merci, ça j'arrive à le faire. Ce que je ne comprends pas c'est pourquoi je me retrouve avec 11 containers alors que j'essaye d'en créer 1.

        Ici, c'est la directive CMD qui fait le boulot :

        Du coup je ne comprend pas la différence entre CMD et ENTRYPOINT.

    • [^] # Re: Bug et interrogation

      Posté par  (Mastodon) . Évalué à 2.

      Une image ou un snapshot c'est la même chose. C'est un conteneur figé à un instant donné.

      Si la commande docker ps -a afficher 11 conteneurs, c'est que tu as lancé 11 fois la commande docker run.
      Pour utiliser un conteneur déjà lancé une fois avec docker run il faut utiliser la commande docker start.
      Il n'est pas possible de modifier les paramètres d’exécution d'un docker run. Si l'on veut faire autre chose de notre conteneur il faut créé une image avec docker commit et lancer un nouveau conteneur avec docker run.

      La commande docker build, qui permet de créer une image à partir d'un fichier Dockerfile, fait un commit après chaque RUN ce qui permet de reprendre la génération de l'image à la première erreur.

      L'intérêt de tout ça est de pouvoir très facilement lancer un grand nombre de conteneurs identiques dans un environnement totalement maîtrisé. De plus Docker permet d'affecter automatiquement un numéro de port d'écoute d'un logiciel lancé dans un conteneur. Par exemple si je demande dans mon Dockerfile de publier le port 80 de mon serveur nginx et que je lance 10 conteneur sans préciser de numéro de port destination, Docker va attribuer 10 ports aléatoires pour les 10 nginx.

      Comme Docker utilise un système de fichier unionfs, les 10 conteneurs ne prennent qu'une place sur le disque + le delta de chaque conteneur.

  • # Une présentation sur Docker

    Posté par  . Évalué à 2.

    Voici les slides de ma présentation sur Docker.

  • # MariaDB + Apache ?

    Posté par  (site web personnel) . Évalué à 1.

    Je suis quand même un peu surpris de l'exemple. Lancer un superviseur pour avoir MySQL et Apache sur le même docker, ça va un peu contre l'esprit du truc je trouve.

    MySQL et Apache communiquent par un port réseau, ils n'ont aucune raison de se trouver sur le même docker. Docker permet justement d'en séparer les environnements et d'avoir un espace dédié par service. Là on est en train de contourner l'objet même de docker.

    • [^] # Re: MariaDB + Apache ?

      Posté par  (site web personnel) . Évalué à 4.

      Tout est une question de contexte.
      Évidemment, dans l'esprit, Docker est plutôt fait pour séparer les couches logicielles mais je ne vois rien de bloquant à mettre plusieurs services sur un même container.

    • [^] # Re: MariaDB + Apache ?

      Posté par  . Évalué à 7.

      Docker peut aussi servir pour des environnement de développement et servir à avoir un environnement de développement simple à arrêter et démarrer (comme un tout).

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

      • [^] # Re: MariaDB + Apache ?

        Posté par  (site web personnel, Mastodon) . Évalué à 6.

        Pour compléter, Docker se présente ainsi : "an open source project to pack, ship and run any application as a lightweight container", ce qui peut se traduire par : "un projet open source pour enpaqueter, distribuer et exécuter n'importe quelle application sous forme de containeur".

        On parle d'application, pas de couche logicielle. Donc déployer un conteneur docker qui intègre apache / mariadb ne me choque pas dans la mesure où il s'agit d'une application autonome et indépendante du reste de l'infrastructure.

    • [^] # Re: MariaDB + Apache ?

      Posté par  . Évalué à 4.

      je suis du meme avis que mes confreres,
      je pratique la virtualisation pour isoler mes environnements de dev/test

      j'ai donc des machines virtuelles qui reproduisent le serveur de prod qui lui contient tout sur une machine.

      mais un conteneur peut aussi etre un moyen d'avoir mariadb sur un serveur qui dispose deja de postgresql et mysql
      ou d'avoir python3 là ou le serveur propose python2

    • [^] # Re: MariaDB + Apache ?

      Posté par  . Évalué à 4.

      Au contraire, ton prestataire te fourni un container avec tout dedans, tu déploies, ça tourne.
      C'est bien ça l'esprit, tout est dans le container.
      Bien sûr pour des architectures plus complexe, qui ont besoin de scalabilité, tu vas devoir faire des containers plus spécialisés.
      Bref, ça dépend de l'usage, comme d'hab.

  • # Questions

    Posté par  . Évalué à 3.

    Je ne comprends pas très bien pourquoi lancer des tonnes de commandes d'installation dans le dockerfile plutôt que d'en faire le minimum pour boostraper un système comme puppet, salt, ansible, fabric ou je ne sais quel cfengine. Il ne serait pas plus intéressant de laisser à docker le minimum (installation d'une distrib', configuration de son environnement et installation du gestionnaire de configuration puis de passer au gestionnaire de conf pour spécialiser la distrib' ? Bref l'utiliser comme un virtualiseur classique.

    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Questions

      Posté par  (site web personnel, Mastodon) . Évalué à 5.

      En fait, si tu as différents containers qui sont configurés à partir des mêmes commandes, il me semble que docker factorise ces opérations. Concrètement, ton apt-get update && apt-get upgrade sera effectué une seule fois pour tous les containers ( là où puppet et consorts l'exécuteraient n fois pour n containers).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.