Docker CLI

Utiliser Docker c’est maitriser l’ensemble des commandes, pour manipuler les containers Docker. Je vais passer en revue les commandes que propose Docker et les améliorer en créeant un ensemble de Docker snippets, pour simplifier l’exploitation quotidienne de Docker.

Lors du précédent tutorial Débuter avec Docker, j’ai présenter quelques commandes de base, mais nous allons poursuivre cette découverte des commandes CLI de Docker, pour exploiter et maitriser Docker.

Liste des commandes de Docker CLI

Je vais rapidement lister les commandes Docker disponibles, en expliquant leurs rôles (informations issues des manpages Docker)

  • docker attach : Joindre à un conteneur en cours d’exécution
  • docker build : Construire une nouvelle image à partir du code source dans le PATH
  • docker commit : Créer une nouvelle image à partir des changements d’un conteneur
  • docker cp : Copier des fichiers ou des dossiers depuis le PATH d’un conteneur vers le HOSTDIR ou vers STDOUT
  • docker create : Créer un nouveau conteneur
  • docker diff : Inspectez changements sur le système de fichiers d’un conteneur
  • docker events : Obtenir des événements en temps réel depuis le serveur
  • docker exec : Exécuter une commande dans le conteneur en cours d’exécution
  • docker export : Exporter le contenu d’un système de fichiers d’une archive tar vers STDOUT
  • docker history : Afficher l’historique d’une image Docker
  • docker images : Lister des images
  • docker import : Créer une image de système de fichiers vide et y importer le contenu d’une l’archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz), puis éventuellement y ajouter une étiquette (tag)
  • docker info : Afficher l’ensemble des informations système
  • docker inspect : Afficher les informations de bas niveau sur un conteneur ou une image Docker
  • docker kill : Tuer un conteneur en cours d’exécution en utilisant SIGKILL ou un signal spécifié
  • docker load : Chargez une image à partir d’une archive tar sur STDIN
  • docker login : Inscrivez-vous ou connectez-vous à le Docker Register (HUB)
  • docker logout : Déconnexion du Docker Register (HUB)
  • docker logs : Fetch des journaux d’un conteneur
  • docker pause : Mettre en pause tous les processus dans un conteneur
  • docker port : Liste les ports d’un conteneur, ou rechercher les ports “public” NATé vers un PRIVATE_PORT
  • docker ps : Liste de conteneurs
  • docker pull : Récupérer une image ou un repository à partir du Docker HUB
  • docker push : Publier une image ou un repository vers le Docker HUB
  • docker rename : Renommer un conteneur Docker
  • docker restart : Redémarrez un conteneur en cours d’exécution
  • docker rm : Supprimer une ou plusieurs conteneurs
  • docker rmi : Supprimer une ou plusieurs images
  • docker run : Exécuter une commande dans un nouveau conteneur
  • docker save : Enregistrer une image dans une archive tar (streaming vers STDOUT par défaut)
  • docker search : Rechercher des images sur le Docker Hub
  • docker start : Lancer un ou plusieurs conteneurs arrêtés
  • docker stats : Afficher l’utilisation des ressources d’un ou plusieurs conteneurs sous la forme d’un flux
  • docker stop : Arrêtez un conteneur en cours d’exécution en envoyant SIGTERM et SIGKILL après une période de grâce
  • docker tag : Étiqueter une image dans un repository
  • docker top : Afficher les processus en cours d’exécution d’un conteneur
  • docker unpause : Réactiver tous les processus dans un conteneur
  • docker version : Afficher les informations de version Docker
  • docker wait : Bloquer jusqu'à l’arrêt du conteneur, puis imprime son code de sortie

Dans l’article précédent Débuter avec Docker, nous avons déjà utiliser beaucoup de commandes Docker :

Nous avons construit une image Docker avec la commande suivante :

docker build -t itwars/test1 .

En phase de développement d’une image, il arrive très souvent que sa création échoue (erreurs dans le Dockerfile) et on voit aparaitre à l'écran des choses curieuses quand nous lançons les commandes Docker suivantes :

docker images
docker ps -a

Docker ps exited and images none

Que ce passe-t-il quand la création d’une Image Docker échoue ?

  1. Docker crée des containers à la volée pour créer des images. Si la création se passe bien, à la fin du processus, Docker “nettoie” ses containers de build
  2. Docker crée également des images intermédiaires, pour créer une image finale, quand la création va à son terme, Docker, là encore “nettoie” ses images build

Donc c’est à nous de faire le ménage pour Docker (personnellement, j’ai créé un alias dans mon .bashrc) !

docker rm  $(docker ps -a  -q --filter "status=exited") &&
docker rmi $(docker images -q --filter "dangling=true")

Docker nous indique la liste des containers supprimés, puis la liste des images supprimées :

175887c21be4
cf1f1c3aa329
c0a941a8ddc3
Deleted:dbf3ced60ed89a1b7bacb0eb639bbbeb925253288f732a937bf61a8fb2fa3ced
Deleted:4101ab020eae1c6141f775cb1392f1e12fcd39520d7f637b69e2d766aaf0d2c6

Quelques snippets Docker radicales

  • Stopper tous les containers Docker : docker stop $(docker ps -a -q)
  • Supprimer toutes les Docker images : docker rmi $(docker images -a -q)
  • Stopper et supprimer tous les containers Docker : docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)
  • Stopper et supprimer tous containers Docker + Supprimer toutes les docker images : docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q) && docker rmi $(docker images -a -q)

Monitoring basic des containers Docker

En ce connectant à la machine hôte qui fait fonctionner le daemon Docker, vous disposez de plusieurs solutions, pour monitorer simplement vos containers Docker :

Utilisation de docker stats

On peut afficher les statisques des containers actifs, un peu comme avec la commande “top” :

docker stats $(docker ps -q)

Utilisation des cgroup

Pour tout ce qui touche à la gestion, restriction, informations sur les ressources, Docker s’appuie sur les cgroup du kernel Linux. Dans le script qui suit, j’affiche la mémoire utilisée par chaque containers actifs :

for line in `docker ps | awk '{print $1}' | grep -v CONTAINER`; do docker ps | grep $line | awk '{printf $NF" "}' && echo $(( `cat /sys/fs/cgroup/memory/docker/$line*/memory.usage_in_bytes` / 1024 / 1024 ))MB ; done

Pour un container en particulier en Mo avec l’utilisation de jq (voir plus bas):

echo $( cat /sys/fs/cgroup/memory/docker/$(docker ps -q --no-trunc=true --filter "name=bind")/memory.usage_in_bytes ) | jq "./1024/1024" | jq "floor"

Utilisation de l’API Docker

Docker quand il démarre, ouvre un socket Unix qui se trouve dans /var/run/docker.sock, on peut lui envoyer des commandes http, pour réaliser une multitude d’actions. Je vous conseille de lire la documentation Docker API.

Ici je récupère l’ensemble des informations concernant les images gérés par ce daemon Docker :

echo -e "GET /images/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock |  tail -n +5  | python -m json.tool | less

Dans l’exemple ci-dessous, je demande le flux des statistiques du container ayant pour ID: 3e33d469abac

echo -e "GET /containers/3e33d469abac/stats HTTP/1.0\r\n" | nc -U /var/run/docker.sock

On peut le rendre plus facile à utiliser pour les humains en faisant la même requête à partir du nom du container :

echo -e "GET /containers/"$(docker ps -q --filter "name=bind")"/stats HTTP/1.0\r\n" | nc -U /var/run/docker.sock

En utilisant jq, on peut filter le stream JSON pour avoir un champ particulier, ici par exemple la mémoire utilisée :

echo -e "GET /containers/"$(docker ps -q --filter "name=bind")"/stats HTTP/1.0\r\n" | nc -U /var/run/docker.sock | tail -n +5 | jq -r '.memory_stats.usage'

Facilité la création de Dockerfile avec Vim

Comme je suis un inconditionnel de Vim (en fait NeoVim), je me suis créé un petit template pour ne rien oublier dans mes Dockerfiles. Dans mon fichier de configuration .vimrc, j’ai ajouté la commande suivante, qui insère automatiquement le template lorsque j'édite un fichier Dockerfile vide :

au BufNewFile Dockerfile r ~/mysetup/templates/Dockerfile.txt

Mon fichier de template est le suivant :

#┌───────────────────┐
#│ Pull base image   │
#└───────────────────┘
FROM resin/rpi-raspbian:wheezy
MAINTAINER Vincent RABAH <vincent.rabah@gmail.com>

#┌─────────────────────┐
#│   Install + CLeanup │
#└─────────────────────┘
RUN \
   apt-get update && \
   apt-get -y dist-upgrade && \
   
   apt-get install -y XXX  && \
   
   apt-get clean -y && \
   apt-get autoclean -y && \
   apt-get autoremove -y && \
   rm -rf /tmp/*
   rm -rf /var/lib/{apt,dpkg,cache,log,tmp}/*

#┌────────────────────────────┐
#│   Define working directory │
#└────────────────────────────┘
WORKDIR /data

#┌─────────────────────────────┐
#│   Expose some tcp/udp ports │
#└─────────────────────────────┘
EXPOSE 53
EXPOSE 53/udp


#┌──────────────────────────┐
#│   Define default command │
#└──────────────────────────┘
CMD ["bash"]

Conclusion sur les commandes Docker

Voilà, pour ce nouveau tutorial Docker sur l’utilisation et la simplification de l’exploitation au quotidien de Docker. N’hésitez pas à laisser des commentaires pour partager vos snippets avec les autres lecteurs et moi-même ! Merci.