Import d'images stables

Lors de l’import d’une image dans un Dockerfile à l’aide de la directive FROM, il est important de spécifier la version de l’image importée ; sinon la dernière version (latest) est importée, ce qui peut poser des problèmes de stabilité.

Exécution de commandes dans un conteneur

Auparavant, l’exécution de commandes dans un conteneur était réalisée par l’utilisation de supervisord ; cette pratique ne correspond plus aux pratiques employées actuellement par l’association. L’exécution de commandes dans un conteneur est désormais réalisée par l’utilisation de l’instruction CMD associé à un ENTRYPOINT si nécessaire dans le Dockerfile du conteneur.

Installation de paquets par ordre alphabétique

Pour éviter d’installer deux fois un paquet, lors de l’installation de plusieurs paquets en une instruction, il convient de les installer dans l’ordre alphabétique.

Réduction du nombre de couches

Un Dockerfile est composé de différentes couches. Une couche correspond à une instruction exécutée par le Dockerfile. Lorsqu’un conteneur est lancé, il va accéder aux commandes du conteneur en remontant les différents niveaux. À la manière de l’héritage en programmation, si un conteneur cherche a appeler une commande qu’il ne connaît pas, il va remonter à sa classe mère et ainsi de suite. Or, ces accès réduisent la vitesse d’exécution de la commande. Il faut donc veiller à réduire au maximum le nombre de couches d’un conteneur et privilégier les instructions avec plusieurs commandes:

# Exemple:
RUN echo "deb http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list && \
wget -O- https://www.dotdeb.org/dotdeb.gpg | apt-key add - && \
apt-get update -y && apt-get install -y php7.0 php7.0-fpm php7.0-gd php7.0-xml nginx supervisor curl tar


Passage de paramètres à un conteneur

Les images Docker de l’association comportent une instruction ENTRYPOINT qui permet de lancer un script à l’instanciation de l’image ; le script entrypoint.sh associé à chaque conteneur initialise dans son conteneur les variables d’environnement qui sont nécessaires.

Contrôle de la santé d'un conteneur

Afin de faciliter la supervision de l’état d’un conteneur, il convient d’inclure dans les images Docker une instruction HEALTHCHECK contenant une commande permettant de vérifier la santé du conteneur.

Options lors de l'instanciation d'images

Certaines options permettent de désactiver des fonctionnalités importantes d’isolation fournies par Docker au lancement d’un conteneur. Ces options ne doivent pas être utilisées. Elles comportent :

  • –privileged : donne toutes les capabilities et lui permet de dépasser les limites qui lui seraient normalement imposées par son cgroup ; cela expose l’hôte à des attaques de type déni de service par l’absence de limitation sur la consommation de ressources et cela donne accès au conteneur à des capabilities dont il n’a pas nécessairement besoin et qui sont vecteurs de risques
  • –security-opt : désactive l’utilisation de seccomp. seccomp est une fonctionnalité du noyau Linux permettant de limiter le nombre d’appels systèmes disponibles à un conteneur ; la désactivation de ces limiations met donc l’hôte à risque

Montage de volumes

Lors de la rédaction d’images, on peut être tenté d’exposer des volumes sur des images “temporaires”. Par exemple, un conteneur nginx auquel on va exposer le volume /var/www/html. Le problème de cette pratique est que si l’on veut créer une image dokuwiki basée sur cette image nginx, il ne sera pas possible d’écrire par dessus le volume /var/www/html. Même si au sein du Dockerfile on spécifie des commandes pour remplacer le contenu de l’image, au final, le contenu du dossier restera celui de l’image mère. Il convient également de ne pas monter de volume sensible (par exemple /etc) dans un conteneur, parce que les conteneurs peuvent par défaut modifier les volumes montés avec des privilèges root. Ainsi, il ne faut surtout pas monter la socket Docker (/var/run/docker/sock) dans un conteneur.

Présence d'informations confidentielles dans un Dockerfile ou un docker-compose.yml

Il convient de ne pas saisir d’informations confidentielles, telles que des mots de passe ou des clés SSH, dans des fichiers tels que des Dockerfiles ou docker-compose.yml ; ces fichiers sont souvent versionnés et parfois moins protégés. Pour ces raisons, il convient pour passer des paramètres tels que des mots de passe à un conteneur d’utiliser des variables d’environnement comme mentionné plus haut.

Spécifier un utilisateur lors de l'exécution de commandes

Dans un Dockerfile, une commande exécutée par une directive RUN est exécutée par le compte root du conteneur par défaut. Il convient d’exécuter aussi peu de commandes que possible avec le compte root ; pour se faire, il est possible d’utiliser la directive USER.

Réaliser des images minimales

Chaque élément d’une image peut être un facteur de vulnérabilité ; même un paquet en apparence inoffensif peut dépendre d’une librairie contenant une vulnérabilité. Pour cette raison, il convient de réaliser des images aussi légères que possibles en évitant d’installer des paquets superflus ou en supprimant les paquets installés pour un besoin temporaire (par exemple pour compiler un programme) une fois qu’ils sont obsolètes. Pour ce dernier besoin, il peut être intéressant d’avoir recours à des multi-stage builds.

Documenter les paramètres nécessaires

Chaque Dockerfile peut nécessiter le passage de paramètres tels que des mots de passe ; lorsque c’est le cas, il convient de les documenter dans le point d’entrée du conteneur et de leur y assigner une valeur par défaut.

  • technique/docker/general/tips.1601490621.txt.gz
  • de qduchemi