Le Blog Utux

HTTP 200 GET /

Docker-compose et le COMPOSE_PROJECT_NAME

Rédigé par uTux 2 commentaires

Docker-compose est un outil permettant d'utiliser docker à l'aide d'un simple fichier .yml, facilitant ainsi grandement la vie et les interactions entre les containers d'un même service. Mais il n'est pas exempt de bugs ou de défauts de conception.

Le défaut dont je vais parler concerne le nommage des containers. Prenons par exemple deux projets docker : projet1 et projet2 avec l'arborescence suivante :

.
├── projet1
│   └── src
│       └── docker-compose.yml
└── projet2
    └── src
        └── docker-compose.yml

Nos docker-compose.yml sont identiques et commandent le lancement d'un simple container nginx :

# projet1/src/docker-compose.yml
version: '3'
services:

  nginx:
    image:
        nginx:latest

Et :

# projet2/src/docker-compose.yml
version: '3'
services:

  nginx:
    image:
        nginx:latest

Voyons ce qui arrive lorsque je démarre mon projet1 :

utux@docker:~/projet1/src$ docker-compose up -d
Creating src_nginx_1 ... 
Creating src_nginx_1 ... done

On voit que notre container a été nommé src_nginx_1 suivant la logique suivante : $dossier_$service_$numero. Très bien. Démarrons maintenant le projet2 :

utux@docker:~/projet2/src$ docker-compose up -d
src_nginx_1 is up-to-date

docker-compose dit que le container existe déjà alors que non ! En fait il applique le même raisonnement et veut nommer le container src_nginx_1 aussi alors qu'il existe déjà ! C'est un défaut de conception et c'est problématique car en cas de modification sur l'un des projets, docker-compose va recréer les containers, et donc écraser ceux de l'autre...

Pour palier à ce problème, plusieurs solutions sont possibles :

  • Nommer différemment votre dossier de travail. Ce n'est pas toujours possible car on peut avoir un environnement de dev et un environnement de prod avec les mêmes chemins.
  • Utiliser l'attribut container_name mais c'est un peu fastidieux car il faut le faire sur tous les services du docker-compose.yml
  • Utiliser la variable d'environnement COMPOSE_PROJECT_NAME. Malheureusement on ne peut pas la définir dans le docker-compose.yml malgré les demandes répétées des utilisateurs (ici et ) il faut la mettre dans un fichier .env dans votre projet.

Exemple d'utilisation du COMPOSE_PROJECT_NAME :

.
├── projet1
│   └── src
│       ├── docker-compose.yml
│       └── .env
└── projet2
    └── src
        ├── docker-compose.yml
        └── .env

Avec nos fichiers .env :

# projet1/src/.env
COMPOSE_PROJECT_NAME=projet1

Et :

# projet2/src/.env
COMPOSE_PROJECT_NAME=projet2

Démarrons maintenant notre projet1 puis notre projet2 :

utux@docker:~$ cd projet1/src/
utux@docker:~/projet1/src$ docker-compose up -d
Creating network "projet1_default" with the default driver
Creating projet1_nginx_1 ... 
Creating projet1_nginx_1 ... done
utux@docker:~/projet1/src$ cd ../../projet2/src/
utux@docker:~/projet2/src$ docker-compose up -d
Creating network "projet2_default" with the default driver
Creating projet2_nginx_1 ... 
Creating projet2_nginx_1 ... done

Cette fois les deux projets cohabitent bien et ne se marchent plus sur les pieds. La preuve :

utux@docker:~/projet2/src$ docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                    NAMES
eacabeb7e961        nginx:latest                     "nginx -g 'daemon ..."   4 seconds ago       Up 2 seconds        80/tcp                   projet2_nginx_1
9477b31d2035        nginx:latest                     "nginx -g 'daemon ..."   16 seconds ago      Up 14 seconds       80/tcp                   projet1_nginx_1

En conclusion il ne faut pas avoir une confiance aveugle en docker-compose, qui est un outil bien pratique mais manifestement sujet à des défauts de conception. Imaginez ce genre de confusion de nommage, voire d'écrasement de containers en production. Utilisez COMPOSE_PROJECT_NAME et testez vos projets en pré-production avant de déployer sur la prod.

Docker, Ansible, NixOS : le savoir (re)faire

Rédigé par uTux 4 commentaires

L'informatique, comme tous les métiers, demande un savoir-faire, celui-ci vient avec l'expérience et la pratique. Mais s'il y a un autre point qui est important et souvent négligé, c'est de savoir refaire. Je vais expliquer.

Imaginez-vous administrateur système dans une entreprise, on vous charge d'installer un serveur web pour afficher une simple page html. Vous allez alors installer Debian + Apache puis placer le fichier html à la racine, rien de difficile jusque là.

Imaginez ensuite qu'au bout de 2 mois ce fichier html soit remplacé par un fichier php un peu plus avancé, vous allez alors installer libapache2-mod-php5 là encore c'est facile. Par la suite le fichier évolue encore et vous oblige à installer des modules, par exemple php5-gd et php5-curl.

Puis le serveur vit sa vie et au bout de 2 ans on vous demande d'en mettre en place un deuxième avec exactement le même rôle. Et là ça se complique car 2 ans c'est long et vous avez probablement oublié tout ce que vous et vos collègues avez fait pour configurer ce serveur au fur et à mesure. S'il est facile d'identifier que apache2 et php5 sont présents, en revanche les modules sont beaucoup moins évidents, surtout si vous avez utilisé des gestionnaires tiers tels que pecl, cpan, pip.

L'une des grandes problématiques est donc de trouver un moyen pour garder une trace et refaire rapidement toutes les étapes qui ont accompagné la vie du serveur. Alors bien sûr le grand classique est d'utiliser un wiki, mais qui vous garanti que ce qu'y s'y trouve représente bien ce qui est en production ? Personne n'est à l'abri d'une modification "urgente" en prod non rapportée sur le wiki.

Une solution que l'on retrouve souvent et qui est appliquée dans Ansible, Docker et NixOS, c'est d'éliminer toutes les manipulations sur la prod. On y touche plus, à la place on travaille sur un fichier de recette, que l'on va ensuite deployer et jouer. Sur Ansible ce sont les playbook, sur docker les Dockerfile, et sur NixOS le fichier configuration.nix.

Cela parait beaucoup plus propre et ça l'est, c'est une rigueur pas forcément naturelle qui paye sur le long terme. Néanmoins ce n'est pas toujours évident, une manipulation rapide à faire sur un serveur peut se transformer en plusieurs minutes voire heures de devops dans Ansible. Let's Encrypt est un exemple, son automatisation n'est pas simple car vous allez devoir gérer deux cas différents selon la présence ou non d'un certificat. En effet certbot peut soit utiliser le mode standalone et donc couper Nginx (car nécessité du port 80) ou alors utiliser le mode webroot et justement passer par Nginx + vhost de votre site, or ce dernier a justement besoin du certificat pour démarrer. Et quid du cas de Docker où vous devez créer un nouveau container et le relier à l'existant juste pour renouveler vos certificats.

En conclusion le boulot de sysadmin, développeur ou devops n'est pas seulement de faire ou réparer les choses mais également de prévoir l'avenir, s'imposer une rigueur même si elle parait contre-productive sur le moment. J'aurai probablement l'occasion de parler de plus en détail de Docker et de NixOS dans de prochains articles, restez branchés.

Tri des articles, Docker et Ansible

Rédigé par uTux 2 commentaires

Un petit article rapide pour signaler que :

  • J'ai fait du tri et mis hors ligne des articles que je juge peu flatteurs, peu pertinents ou obsolètes. Ce sont principalement ceux écrits sur un coup de tête ou relatifs à l'actualité. J'ai la chance d'être le dictateur de ce blog donc j'en profite pour réécrire l'histoire.
  • Le blog ne tourne plus Docker car j'aimerai refaire les images et containers de manière plus propre en me basant sur l'expérience que j'ai acquis dans cette techno. Docker est pratique et bien pensé, le problème est qu'il est peut-être trop accessible donc on trouve de tout et n'importe quoi et souvent des mauvaises pratiques ou des usages détournés.
  • J'ai réinstallé mon serveur car il a subit de nombreux bidouillages notamment pour Docker et je voulais repartir sur une base propre. J'en ai profité pour faire sa configuration avec Ansible, avec un playbook pour les bases (timezone, locales, reseau, hostname, paquets), un autre pour installer la stack web (nginx, php-fpm, letsencrypt, ufw) et enfin un pour déployer mes sites web (avec génération du certificat let's encrypt au passage). Je peux donc le gérer sans devoir y mettre les pieds en SSH, j'en reparlerai peut être plus tard :)

A quoi ressemble Ubuntu dans Windows 10 ?

Rédigé par uTux 2 commentaires

Depuis la mise à jour anniversary de Windows 10, il est possible d'installer un sous-système ubuntu 14.04 et de lancer bash (et d'autres logiciels), ça ressemble à ça :

Impressionné ? Non ? Moi non plus, on a déjà vu ça avec Cygwin (qui existe depuis 1995 d'après Wikipedia), la différence est que c'est supporté par Microsoft et que l'on a accès aux dépôts de ubuntu. Et comme il s'agit de la 14.04, pas de systemd, dommage cela aurait pu donner lieu de bons à trolls.

Tous ces efforts de Microsoft pour se rapprocher de Linux montrent à quel point ils sont largués. Bien que Windows soit solidement implanté dans le grand public (grâce à la vente liée) et le monde professionnel (A.D, Exchange qui sont plutôt de bons outils) c'est toujours Linux qui est en tête sur les serveurs présents sur internet (web et messagerie pour ne citer que deux domaines). En tant que sysadmin je ne peux pas faire mon métier depuis Windows, cet OS n'est pas conçu pour cela : où sont dig, tcpdump, ssh , grep ? Et pourquoi est-ce que je choisirais IIS qui nécessite d'acheter une licence Windows Server ainsi qu'une machine correctement dimensionnée (gros CPU, 4GB de RAM, 80GB de disque) tout ça pour avoir moins de souplesse et de performances que Debian + Nginx qui tiennent sur 256MB de RAM et 8GB de disque ?

Dans le monde du devops, là encore Microsoft est à la ramasse. Par exemple Ansible et Docker sont des outils libres, gratuits, communautaires, documentés et simples qui ont le vent en poupe et s'appuient sur des composants qui n'existent pas sur Windows : ssh pour le premier, les containers pour le second. Et c'est génial.

En conclusion ce sous-système ubuntu dans Windows ne révolutionne rien mais vient combler un manque de Windows et il en avait grandement besoin. Reste à voir comment il se comporte et s'administre, avec le temps.

Docker >_<

Rédigé par uTux 12 commentaires

Je ne vais pas me faire des amis, mais j'ai un problème avec Docker et je vais l'illustrer en le comparant avec ezjail qui permet de gérer les jails sous FreeBSD.

Pour afficher la liste des containers dans Docker :

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
c516f8fcbc57        httpd:v5            "/bin/bash"         9 minutes ago       Up 2 seconds        80/tcp              tender_mirzakhani

Attendez, c'est pas fini ! Cette commande ne va afficher que les containers en cours d'exécution. Si on veut tout :

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
c516f8fcbc57        httpd:v5            "/bin/bash"            9 minutes ago       Up 22 seconds              80/tcp              tender_mirzakhani
974607db9cb7        httpd:v5            "apache2-foreground"   18 minutes ago      Exited (0) 8 minutes ago                       gigantic_engelbart

Et pour entrer dans un container :

$ docker exec -t -i gigantic_engelbart /bin/bash
root@974607db9cb7:/var/www/html#

Ok. Maintenant voyons comment on fait pour lister des containers avec ezjail sous FreeBSD :

ezjail-admin list
STA JID  IP              Hostname                       Root Directory
--- ---- --------------- ------------------------------ ------------------------
DR  1    127.0.1.1       jls-web-10                     /usr/jails/jls-web-10
    1    em0|192.168.0.50
DS  N/A  127.0.1.2       jls-mail-01                    /usr/jails/jls-mail-01
    N/A  em0|192.168.0.60

Et pour entrer dans un container avec ezjail :

ezjail-admin console jls-web-10
FreeBSD 10.3-RELEASE (GENERIC) #0 r297264: Fri Mar 25 02:10:02 UTC 2016

root@jls-web-10:~ #

Voilà, une seule commande simple à retenir et pas d'options superflues.

Pourquoi les commandes Docker sont-elles aussi imbuvables ? C'est un problème courrant dans l'environnement des logiciel sous Linux, on ne sait pas faire de choses simples. git est un autre exemple symptomatique, nous sommes obligés d'avoir sous la main une anti-sèche pour ne pas nous tromper dans les commandes.

Docker étant relativement récent, pourquoi ne s'est-il pas inspiré des commandes ezjail, iohyve, iocage ou lxc qui sont beaucoup plus simples et intuitives ?

Fil RSS des articles de ce mot clé