Utilisation de Docker

0. Remarques

Résumé

En plus de la machine virtuelle nous allons utiliser docker pour séparer les différentes applications. Le but de ce TP est d'installer 5 conteneurs :

  1. un docker mysql qui servira de base de donnée;
  2. un docker phpmyadmin pour piloter cette base;
  3. un docker nginx qui sera le serveur web de base et servira aussi en tant que proxy inverse en assurant la répartition des requêtes dans les différents conteneurs;
  4. un docker owncloud qui servira de serveur de partage de fichiers
  5. et éventuellement un docker onlyoffice qui permettra l'édition en ligne des fichiers.

Objectifs

Notation

Nous allons noter ces TPs en fonction du travail accompli. Pour cela, il faut impérativement noter votre binôme et l'adresse IP de votre VM dans les cases prévues de tomuss : BinomeTpDocker et IPTpDocker.

Première séance

Nous vous proposons un fichier de test qui sera utilisé pour vérifier votre avancement. Ce fichier est ici. C'est un script python. La version actuelle a été testée et fonctionne sur l'image des VMs utilisées, le fichier à exécuter s'appelle verif.py. Il vérifie pour le moment les dockers jusqu'à la fin de la partie IV (sans la partie cachée).

Seconde séance

Le TP sera noté de la même manière. Vous devez aller le plus loin possible, le script sera passé pour la plupart d'entre vous le samedi 17/11 vers 14h. Pour les étudiants en 1/3 temps, ce script sera réutilisé samedi soir (après 22h).

Comme pour la première séance, il sera possible d'améliorer le travail si vous terminez le TP avant le prochain TP de l'UE (7/12). La note obtenue alors sera inférieure à 11/20.

Les notes sont en ligne sur tomuss. Le script utilisé est ici. Comme il faut étreindre les dockers entre la première partie et le compose, il est déconseillé de tout tester en une seule fois.

## pour tester la fin de la première partie
$./verif owncloud
## pour tester la partie compose
$./verif compose

Attention, la case ResultTP2-Owncloud contient la valeur obtenue par le script moins 9 (les 9 premiers points qui étaient déjà vérifié dans le premier TP).

Le système de test du login a un bug. Il arrive assez souvent que le login est rejeté car owncloud considère que la série des action a faire pour se connecter n'a pas été respectée. Si votre le test donne :

OK      un serveur web semble répondre à l'adresse http://192.168.77.18/
OK      http://192.168.77.18/ semble un site owncloud
Not OK  Le login ne semble pas possible ici http://192.168.77.18//login la réponse est --2018-11-21 14:19:44--  http://192.168.77.18/login
 Connecting to 192.168.77.18:80... connected.
 HTTP request sent, awaiting response... 
   HTTP/1.1 412 Precondition failed
   Server: nginx/1.15.6
   Date: Wed, 21 Nov 2018 14:19:44 GMT
   Content-Type: application/json; charset=utf-8
   Content-Length: 31
   Connection: keep-alive
   Expires: Thu, 19 Nov 1981 08:52:00 GMT
   Cache-Control: no-cache, must-revalidate
   Pragma: no-cache
   Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
   X-Content-Type-Options: nosniff
   X-XSS-Protection: 1; mode=block
   X-Robots-Tag: none
   X-Frame-Options: SAMEORIGIN
   X-Download-Options: noopen
   X-Permitted-Cross-Domain-Policies: none
 2018-11-21 14:19:44 ERROR 412: Precondition failed.
 
OK      On semble pouvoir se connecter en tant qu'admin
Not OK  Je ne trouve pas l'utilisateur admin
Not OK  On ne trouve pas le module calendar
Not OK  On ne peut pas se déconnecter l'url est http://192.168.77.18/
Not OK  Onlyoffice ne semble pas fonctionner (et on compte 3 fois)
Not OK  Onlyoffice ne semble pas fonctionner (et on compte 3 fois)
Not OK  Onlyoffice ne semble pas fonctionner (et on compte 3 fois)

Il faut patienter et recommencer plus tard. De même, owncloud se mettant en place lentement, il est conseillé de ne pas lancer le script peut de temps après le démarrage des dockers.

Avant de commencer

Vous devez détruire vos VMs créées la dernière fois (sauf cas particuliers). À partir de maintenant, merci de ne pas faire de snapshot de vos machines, normalement, vous conservez dans vos rapports les commandes nécessaires au bon fonctionnement du TP.

I. Installation d'un premier docker : mysql

Comme pour beaucoup de serveurs connus, il existe plusieurs images qui permettent l'installation de mysql très simplement.

Il faut savoir reconnaître rapidement la qualité d'une image, dans l'exemple de mysql vous avez 2 possibilités (nous excluons mariadb)1). :

La documentation de la seconde est beaucoup plus fournie et elle semble proposer un grand nombre d'options de configuration, c'est cette dernière que vous allez choisir.

Notez le mot de passe de l'administrateur.

Lors du lancement un grand nombre d'informations sont affichées. En fait, par défaut le lancement bloque le terminal et affiche tous les résultats de la commande. Parmi ces derniers vous pouvez noter la ligne GENERATED ROOT PASSWORD: … qui contient le mot de passe administrateur de la base. Dans la suite, vous utilisez sans doute l'option -d pour lancer le docker de manière détachée, les informations ne seront plus affichées, mais conservées et disponible via la commande docker log ….

Il est toujours possible d'installer le client mysql sur votre VM, mais ici, on va utiliser celui qui se trouve dans le docker. En effet, on peut toujours ajouter un processus au conteneur via la commande docker exec …

Partage de volumes

mysql est une base de données qui stocke ces données dans le répertoire /var/lib/mysql. Dans la configuration actuelle, ce répertoire est interne au docker et difficile d'accès. Cela peut poser des problèmes si vous souhaitez changer le docker sans perdre les données stockées. Pour éviter cela, vous allez donc recréer le docker en partageant le répertoire de stockage avec la machine hôte. Pour cela il faut utiliser l'option -v du docker run.

II. Gestion des adresses et installation d'une interface à mysql : phpMyAdmin

mysql n'est qu'un serveur de base de donnée, on ne peut l'utiliser que via des commandes SQL. Pour simplifier son utilisation, on ajoute en général une interface comme le logiciel phpMyAdmin. C'est une interface web permettant simplement de faire la plupart des opérations sur le serveur. Il est basé sur un code en php et donc un serveur capable de l'interpréter.

Vous allez utiliser le docker phpMyAdmin pour mettre en place l'interface. Dans la documentation ne suivez pas la méthode Usage with linked server qui est dépréciée. Utilisez la méthode avec un serveur externe.

Gestion du réseau et liaison entre les dockers

Ce système de configuration n'est pas utilisable, car il demande d'entrer dans le docker ou ses fichiers de configuration une adresse qui est gérée par docker. Cela signifie par exemple que si vous programmez un service web pour utiliser la base de donnée, ce dernier devra être modifié si par hasard le docker est recrée avec une autre adresse. Pour remédier à cela vous allez utiliser la possibilité de créer des réseaux et de choisir les adresses des dockers.

En effet, il est possible de choisir les adresses IPs des dockers, de choisir la valeur de leurs variables d'environnement ou de paramétrer leur fichier /etc/hosts.

La solution présentée ici n'est pas totalement idéale, car il faut refaire le docker dockpma si l'adresse du docker dockbdd est modifiée. Il existe des solutions plus souples présentées plus loin.

III. Configuration des dockers

En général pour configurer un service, il est nécessaire de modifier des fichiers. Mais ces fichiers sont internes au docker donc difficiles d'accès. De plus, les outils d'édition les plus courants (nano, vim, emacs …) ne font pas parti d'un conteneur classique ce qui complique encore cette modification. Pour résoudre le problème, on peut :

  1. Pré-configurer le docker via le Dockerfile ou les outils de création (voir plus tard);
  2. Copier des fichiers entre la VM et le docker;
  3. Utiliser le partage des répertoires entre la VM et le docker.

Nous allons utiliser la dernière méthode pour configurer un proxy inverse nginx.

Le fichier de configuration principale de nginx est /etc/nginx/nginx.conf. Nous allons partir d'un fichier copié depuis un docker nginx fonctionnel .

III-bis. Problèmes à l'installation de logiciel sur la machine virtuelle

L'image utilisée pour les TP semble avoir eu un petit souci. En effet, il semble que des processus de mise a jour apt sont en train de tourner et bloquent toute commande d'installation. Si pour une installation vous avez ce problème :

ubuntu@prepa-tp-dockercompose:~$ sudo apt install unzip
E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

Cela signifie qu'il y a sans doute un processus apt en train de tourner. Il faut le stopper afin de poursuivre votre installation. Attention à ne pas supprimer un processus de votre binôme qui peut être justement en train de travailler sur la machine. Si vous êtes sûr de ce que vous faites :

  1. retrouver le numéro du processus fautif :
    ubuntu@prepa-tp-dockercompose:~$ ps auxf
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         2  0.0  0.0      0     0 ?        S    Oct23   0:00 [kthreadd]
    root         4  0.0  0.0      0     0 ?        I<   Oct23   0:00  \_ [kworker/0:0H]
    root         6  0.0  0.0      0     0 ?        I<   Oct23   0:00  \_ [mm_percpu_wq]
    root         7  0.0  0.0      0     0 ?        S    Oct23   0:06  \_ [ksoftirqd/0]
    ...
    root      7096  0.0  0.0   4628   920 ?        Ss   06:38   0:00 /bin/sh /usr/lib/apt/apt.systemd.daily install
    root      7109  0.0  0.0   4628  1764 ?        S    06:38   0:00  \_ /bin/sh /usr/lib/apt/apt.systemd.daily lock_is_held install
    root      7138  0.1  3.8 148192 78700 ?        S    06:38   0:16      \_ /usr/bin/python3 /usr/bin/unattended-upgrade
    _apt      7150  0.0  0.4  80116  8580 ?        S    06:38   0:00          \_ /usr/lib/apt/methods/http
      
  2. Détruisez le dernier fils des processus (ici /usr/lib/apt/methods/http)
    ubuntu@prepa-tp-dockercompose:~$ sudo kill -15 7150
    ubuntu@prepa-tp-dockercompose:~$ 
      
  3. Vérifiez qu'il n'y a plus de processus apt en cours
    ubuntu@prepa-tp-dockercompose:~$ ps aux | grep apt
    ubuntu   10485  0.0  0.0  14856  1060 pts/0    S+   10:23   0:00 grep --color=auto apt
      
  4. Relancez votre installation
    ubuntu@prepa-tp-dockercompose:~$ sudo apt install unzip
    Reading package lists... Done
    Building dependency tree       
    ...

IV. Création d'image : installation du docker owncloud

Vous allez maintenant ajouter un élément au site : owncloud. C'est un logiciel de partage de fichier. Il fonctionne un peu comme dropbox ou le drive de google. owncloud est un service web écrit en php. Il est disponible ici ou dans une version dockerisée.

La documentation propose d'utiliser en plus de ce docker un docker mysql et un docker redis. Nous n'utiliserons que mysql.

Création d'une première image

Certaines configurations ne sont pas proposées par le docker owncloud. Par exemple, celui-ci ne dispose pas de la commande sudo, or cette commande est utile pour la suite du TP4). Vous allez donc dans un premier temps modifier l'image owncloud/server

La modification d'une image se fait grâce à des fichiers de description Dockerfile. En fait, chaque création d'image correspond à un répertoire qui contient les données nécessaires à la modification ainsi que le fichier de description Dockerfile. Vous pouvez noter que la plupart des documentations de dockers sont en fait constituées par un dépôt git correspondant à ce répertoire. Comme vous pouvez le voir ici.

Nous vous proposons de commencer par ce répertoire de travail.

V. Retour sur la gestion des réseaux

Il faut maintenant faire le lien entre le docker docknginx et le docker dockowncloud. La méthode vue précédemment utilisait l'affectation de l'adresse IP pour faire ce lien. Cela suppose de détruire puis refaire le docker docknginx. Pour éviter cela, nous allons utiliser le fait que les réseaux définis par les utilisateurs permettent de créer des associations entre le nom et l'adresse des dockers5).

VI. Gestion de plusieurs dockers avec compose

Vous devez être capable de lancer un petit ensemble de services via des dockers. Mais cela n'est pas suffisant. En effet, avec la méthode actuelle, pour que le site fonctionne, il faut être capable de lancer les dockers avec les bonnes options, dans un ordre précis, avec des fichiers de configuration qui dépendent de ces options … Tout cela est difficile à distribuer. Il est donc nécessaire de faire la même chose mais de manière automatique.

En effet, pour automatiser les opérations sur les conteneurs, il est possible d'écrire une description des commandes utilisées dans un fichier, c'est le rôle de docker-compose. Docker compose est capable de faire à votre place toutes les commandes docker nécessaire à partir de ce que vous avez décrit dans un fichier docker-compose.yml.

Vous pouvez avoir une description de ces fichiers à cette adresse. Attention, l'api docker évolue rapidement, il est important de se limiter à une version pour travailler. De plus, il ne faut pas confondre la version de l'exécutable docker-compose, celle du logiciel docker et celle du fichier de description docker-compose.yml.

La version la plus importante est celle du fichier de description, elle est écrite au début du fichier :

version: '2.4'
services:
  foo:
    image: busybox

Nous vous conseillons d'utiliser pour ce TP la version de l'exemple : 2.4. C'est la dernière de la version 2. En effet la version 3 est la version qui introduit l'utilisation de cluster ce qui sera vu plus tard. La documentation conseillée est donc celle de la version 2 et il est important de vérifier que la documentation que vous consultez est bien basée sur cette version pour expliquer les problèmes.

Organisation du fichier compose

Dans la version 2, le fichier est composé de 3 sections correspondant aux sous-commandes docker utilisées :

  1. services est la section qui donne la liste des dockers et de leurs options, cela correspond aux commandes docker run … ou docker create …
  2. networks est la section qui décrit les réseaux à utiliser. Cela correspond à la commande docker network …
  3. volumes est la section qui décrit les volumes à utiliser. Cela correspond à la commande docker volume …

Section volumes

Pour résumer, cette section correspond à la création de volumes en dehors des dockers. Jusqu'à présent, vous n'avez jamais utilisé la commande docker volumes … ce qui signifie que vous n'aurez pas à utiliser la section pour ce TP. Tous vos volumes seront des volumes de type bind, c'est à dire créés lors du docker run (section service) et partagée avec la machine hôte.

Les volumes sont des espaces de stockage persistants utilisés par les dockers. Vous pouvez les créer soit en les utilisant dans un docker soit en les créant à part via la commande docker volume…. La description de la section volumes d'un docker-compose est ici. Il faut aussi consulter la description de l'utilisation des volumes par les dockers grâce à la sous-section volumes d'un service. La documentation est .

Dans un fichier docker-compose.yml

Section networks

C'est la section qui vous permettra de créer et configurer le réseau. Correspondant à ce que vous avez fait via la commande docker network …. Vous êtes invité à consulter cette documentation, notamment la partie ipam qui permet de gérer l'intervalle d'adresse utilisé.

Section services

Cette section décrit les dockers qui devront être créés. Pour cette version, chaque service correspond à un docker et une commande docker-run …. La documentation est très fournie, vous aurez notamment besoin :

  1. De pouvoir choisir l'image à partir de laquelle le docker est créé, cela peut être
    • une image utilisable via le mot clef image;
    • une image construite via le mot clef build.
  2. D'imposer le réseau utilisé via le mot clef networks. Regardez notamment comment choisir l'adresse ip et donner un alias à ce docker.
  3. D'ajouter au docker des partages de répertoires de type bind volumes.
  4. De déclarer des variables d’environnement dans le docker environment.
  5. De mettre en place des transferts de ports réseaux entre la VM et le docker ports.
  6. De spécifier des dépendances entre les dockers depends_on.

Travail à faire

Vous devez installer docker-compose.

N'utilisez pas apt-get install docker-compose car cela installerait une ancienne version de docker sur votre VM.

Vous devez créer un ensemble de fichiers et un docker-compose.yml qui recrée l'architecture vue au début du TP.

Le répertoire doit être /home/ubuntu/compose/ et contenir tous les fichiers et partage nécessaires à cette architecture.

  ./compose/
    |_ docker-compose.yml
    |_ data/
    |    |_ mysql/
    |    |_ owncloud/
    |    |_ onlyoffice/
    |_ logs/
    |    |_ onlyoffice/
    |_ nginx/
    |    |_ nginx.conf
    |_ owncloud/
         |_ Dockerfile
         |_ pinst.sh

Vous devez faire un fichier compose qui crée des dockers équivalents aux 4 dockers et au réseau créé auparavant. Ces dockers utiliseront les mêmes ports que les précédant. Vous devez donc les éteindre (docker stop dockbdd docknginx dockpma dockowncloud). Attention à ne pas les supprimer cela poserait des problèmes pour le script de notation.

Pour résumer il faut :

Vous constaterez que les dockers créés par compose n'ont pas le nom des services. En effet, s'il n'est pas précisé par le champ container_name, compose ajoute le nom du répertoire et un numéro unique. C'est utile pour que les noms de ces dockers soient différents de ceux que vous aviez crée auparavant. Gardez les noms par défauts.

Un peu plus difficile

Il est possible de donner à owncloud la possibilité d'éditer les documents en ligne. Pour cela, il faut utiliser un autre service : onlyoffice et ajouter le plugins onlyoffice à owncloud pour lui permettre de contacter ce dernier.

Pour faire fonctionner ce service de manière automatique, il faut savoir les choses suivantes :

1)
mariadb est un fork de mysql qui est apparu après le rachat de l'entreprise par la firme oracle, il est très proche de mysql et nous ne l'utiliserons pas ici
2)
il vaut mieux être root pour cette question : sudo su
3)
ici il faut bien penser à changer le répertoire de données. En effet, la création de table et d'utilisateur n'est fait que si la base de données est nouvelle donc sans rien dans son répertoire de stockage
4)
En effet, nous souhaitons utiliser l'utilitaire en ligne de commande occ qui permet de piloter le logiciel owncloud via des scripts. Or il est important que les commandes occ soient exécutées par l'utilisateur www-data qui est aussi celui utilisé par le serveur web. L'utilisateur par défaut du docker est root, sudo nous permettra de changer cela.
5)
Vous avez deviné, nous ne savions pas ça la semaine dernière.