18
0
Fork 0
wiki/HowtoDocker.md

28 KiB
Raw Blame History

title categories
Howto Docker docker

Docker est une solution qui permet de créer, déployer et gérer des conteneurs Linux.

Documentation : https://docs.docker.com/

Écosystème

Le démon docker et son client

Docker est une application en mode client-serveur. dockerd est un démon qui fournit une API REST afin d'interagir avec les conteneurs. docker est un client qui permet d'interagir avec le démon en ligne de commande. Il peut interagir avec un démon en local (sur la même machine) ou avec un démon sur une machine distante.

Les objets dockers

Image

Une image est un template contenant des instructions pour créer un conteneur docker. Ces instructions sont listées dans un fichier nommé Dockerfile. La plupart du temps, une image se base sur une autre image ce qui crée un système de couches. Lorsqu'on modifie une image, seules les couches qui sont modifiées sont reconstruites.

Une fois qu'une image est créée on peut la publier dans un registry (docker push).

Conteneur

Un conteneur est une instance exécutable d'une image.

Stack, service et task

Lorsque Docker fonctionne en swarm mode (en cluster), les notions de stack, service et task sont introduites, en plus des précédentes.

Un service est un objet qui contient des informations comme l'image Docker à instancier, des contraintes de placement ou de limitation de ressources, des objets à lier au conteneur qui sera lancé (volumes, réseau, etc…), le nombre de réplicas à démarrer, etc…

Les services se manipulent avec la commande docker service, mais généralement on les définit dans un fichier YAML. On peut définir plusieurs services dans un fichier YAML ainsi que d'autres objets dont les services font référence (volume, network, secret, config, etc…). Cet ensemble représente alors une stack, que l'on peut manipuler avec la commande docker stack.

Un service démarre donc un ou plusieurs réplicas. Ces réplicas sont appelés des tasks. Chaque task lance un et un seul conteneur. Les conteneurs étant des processus Docker indépendant, l'ordonnanceur de Docker Swarm introduit la notion de task afin de manipuler les conteneurs. Concrètement, une task représente un conteneur et un état dans lequel il est (running, failed, stopped et des états transitoires). Sur le même principe qu'une unité systemd, monit ou supervisord peut surveiller ses processus et les redémarrer en cas de besoin, une task Docker se comporte de la même manière avec son conteneur.

Voir : https://docs.docker.com/engine/swarm/how-swarm-mode-works/services/#services-tasks-and-containers

docker registry

Un registry sert à héberger des images docker. Il existe des registres publics tels que docker hub ou docker cloud mais il est possible d'héberger son propre registry.

Docker Engine

Installation

Il est conseillé d'utiliser le paquet docker-ce des dépôts du projet Docker :

# apt install apt-transport-https
# echo "deb http://download.docker.com/linux/debian buster stable" > /etc/apt/sources.list.d/docker.list
# wget https://download.docker.com/linux/debian/gpg -O /etc/apt/trusted.gpg.d/docker.asc
# chmod 644 /etc/apt/trusted.gpg.d/docker.asc
# apt update
# apt install docker-ce

Note : Pour Debian 9 :

# apt install apt-transport-https
# echo "deb http://download.docker.com/linux/debian stretch stable" > /etc/apt/sources.list.d/docker.list
# wget https://download.docker.com/linux/debian/gpg -O /etc/apt/trusted.gpg.d/docker.asc
# apt update
# apt install docker-ce

Sur sa machine de travail, il est utile d'ajouter son utilisateur dans le groupe docker pour pouvoir interagir avec le démon dockerd sans passer root à chaque fois :

# adduser $USER docker

Configuration

Changer le chemin de stockage

Créer le fichier /etc/docker/daemon.json et y mettre :

{
    "graph": "<VOTRE_CHEMIN>",
    "storage-driver": "overlay"
}

Ansible

Le rôle docker-host permet d'installer le docker-engine sur un hôte distant et de l'exposer à l'externe ou non.

La documentation concernant l'utilisation du rôle est située dans son répertoire.

TLS

Lorsque le docker-engine est exposé, il est important de le sécuriser avec TLS.

Au moment de l'installation, une version altérée de shellpki est copiée dans le répertoire docker/tls. Ensuite, les certificats et la clé sont créés pour le serveur. (shellpki init)

Pour autoriser des hôtes à se connecter à l'engine, il faut leur créer une clé et un certificat. Pour ce faire, il suffit de lancer le script:

/home/docker/tls$ ./shellpki create

Les fichiers seront créés, par défaut, dans le répertoire /home/docker/tls/files/$CN

Utilisation de base

Une image Docker contient un système minimal avec un ou plusieurs services. Un conteneur quant à lui est une instance (créée à partir d'une image) en cours d'exécution.

Gérer les conteneurs

Lister les conteneurs

$ docker ps

Options utiles :

-a : lister tous les conteneurs
-l : lister les conteneurs récemment lancés
-q : lister uniquement les ID des conteneurs

Instancier un nouveau conteneur

$ docker run <image> [commande]

Options utiles :

--name="nom"                : donner un nom au conteneur
-p port_hôte:port_conteneur : rendre un port accessible depuis l'hôte
-d                          : lancer le conteneur en mode 'détaché'
-it                         : lancer le conteneur en mode intéractif avec tty

Démarrer un conteneur existant

Un conteneur existant est un conteneur précédemment instancié avec docker run.

$ docker start <ID ou nom du conteneur>

Éteindre ou tuer un conteneur

$ docker stop|kill <ID ou nom du conteneur>

Lorsque le conteneur n'est plus en fonction, il existe toujours et peut être listé à l'aide de la commande docker ps -a

Autostart d'un conteneur

Pour s'assurer qu'un conteneur démarre ou non au démarrage du démon Docker, il existe un paramètre RestartPolicy :

$ docker inspect -f "{{ .HostConfig.RestartPolicy.Name }}" monconteneur

Les valeurs possibles sont :

no  Ne redémarre pas automatiquement le conteneur. (défaut)
on-failure  Redémarre le conteneur s'il crash suite à une erreur (code de sortie non nul)
always  Toujours redémarrer le conteneur sil sarrête. S'il est arrêté manuellement, il est redémarré uniquement lorsque le démon Docker redémarre ou que le conteneur lui-même est redémarré manuellement.
unless-stopped  Semblable à always, sauf que lorsque le conteneur est arrêté (manuellement ou autrement), il n'est pas redémarré même après le redémarrage du démon Docker.

Pour mettre à jour la politique :

$ docker update --restart=always monconteneur

Supprimer un conteneur

$ docker rm <ID ou nom du conteneur>

Exécuter des commandes dans un conteneur en fonctionnement

$ docker exec <ID ou nom du conteneur> <commande>

Options utiles :

-t : alloue un TTY
-i : attache stdin (mode interactif)

On utilise habituellement la commande suivante pour obtenir un shell dans un conteneur en fonctionnement :

$ docker exec -ti <ID ou nom du conteneur> bash

Visionner les journaux d'un conteneur

Il s'agit en fait de la sortie standard et la sortie d'erreur du processus lancé à l'intérieur du conteneur :

$ docker logs <ID ou nom du conteneur>

Options utiles :

-f : suivre les logs en direct
-t : afficher un timestamp devant chaque ligne

Afficher les informations d'un conteneur

$ docker inspect <ID ou nom du conteneur>

Cette commande s'applique généralement à n'importe quel objet Docker (conteneur, image, service, réseau…) et donne une liste exhaustive des attributs de l'objet, formaté en JSON.

Il est aussi possible de récupérer une sous partie en utilisant l'argument --format

# Récupérer les IP du container d05daab5c59e
$ docker inspect d05daab5c59e --format "{{range .NetworkSettings.Networks }}{{ .IPAddress  }}{{ end }}" 
# Récupérer l'IP du container f4bae02ef1407adc92f1aa2cc32c8e9fae75dac87126e2bf4964db265e9ad55d sur l'interface docker_gwbridge
$ docker inspect docker_gwbridge --format "{{ .Containers.f4bae02ef1407adc92f1aa2cc32c8e9fae75dac87126e2bf4964db265e9ad55d.IPv4Address }}"

Note : De notre expérience, l'option --format peut se montrer capricieuse, notamment s'il y a en jeu des identifiant de containers. Une alternative est de parser du json manuellement avec jq

Gérer les images

Lister les images locales

$ docker image ls

Construire une image

Pour construire ou mettre à jour une image :

$ docker build <repertoire>

Le répertoire doit contenir un fichier Dockerfile décrivant l'image à construire.

Option utiles :

-t : ajoute un tag à l'image

Ajouter un tag à une image existante

$ docker tag <tag actuel> <nouveau tag>

Pousser une image sur un dépôt distant

$ docker push <image>

Avant de pousser une image, il est nécessaire de lui attribuer le bon tag qui doit contenir l'adresse du dépôt distant.

Par exemple pour pousser l'image foo-image sur le dépôt Docker registry.example.net:5000 :

$ docker tag foo-image registry.example.net:5000/foo-image
$ docker push registry.example.net:5000/foo-image

Récupérer une image d'un dépôt distant

$ docker pull <image>

Copier des fichiers dans/depuis un conteneur

$ docker cp <fichier> <conteneur>:<chemin>

On peut aussi le faire de conteneur à conteneur :

$ docker cp <conteneurA>:<fichier> <conteneurB>:<chemin>

Astuces

Éteindre/Tuer/Supprimer tous les conteneurs :

$ docker ps -aq |xargs -r docker stop|kill|rm

Supprimer toutes les images :

$ docker images -q |xargs -r docker image rm

Démarrer un conteneur existant avec un shell bash (pour des fins de debug par exemple) :

$ docker run -it IMAGE bash

Dockerfile

Les fichiers Dockerfile décrivent les étapes de construction d'une image. Ils permettent de reconstruire à l'identique votre image et de connaitre exactement ce qui a été fait. Ainsi au lieu de distribuer une image potentiellement volumineuse, on distribue uniquement la procédure de construction (Dockerfile) et les quelques fichiers annexes.

Référence pour la syntaxe des fichiers Dockerfile : https://docs.docker.com/engine/reference/builder/

Procédure de création d'une nouvelle image

Exemple avec une image exécutant rsyslog :

  • depuis un répertoire vierge, création d'un fichier Dockerfile :
~/docker-images/rsyslog $ $EDITOR Dockerfile

# Image sur laquelle notre image se base
FROM debian:stretch

# Champs optionnels
LABEL maintainer="John Doe <jdoe@example.com>"

# Installation des paquets voulus
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
        && apt-get install -y --no-install-recommends rsyslog procps \
        && rm -rf /var/lib/apt/lists/*

# Configuration de rsyslog. On peut modifier la configuration directement ou
# bien copier des fichiers de notre machine
RUN sed -i 's/^#\(module(load="imudp")\)/\1/; s/^#\(input(type="imudp" port="514")\)/\1/' /etc/rsyslog.conf
COPY custom.conf /etc/rsyslog.d/

# /var/log/ est un volume qui doit être monté depuis l'extérieur lors de
# l'exécution du conteneur
VOLUME /var/log/

# Le port 514/udp est rendu public à l'extérieur du conteneur à son exécution
EXPOSE 514/udp

# La commande suivante est exécutée lorsque le conteneur est exécuté
CMD /usr/sbin/rsyslogd -n

Dans la mesure du possible, voici quelques bonnes pratiques à respecter :

  • la commande spécifiée par CMD doit s'exécuter en avant plan et ne pas forker. Si la commande rend la main, le conteneur sera alors arrêté ;
  • la commande doit envoyer ses logs sur stdout et/ou stderr. Cela permet de les consulter directement à l'aide de docker logs.

Un exemple à ne pas écrire :

CMD /usr/bin/foo -d; tail -f /var/log/foo.log

Dans le cas où /usr/bin/foo -d lance le démon foo en arrière plan, le conteneur s'exécutera correctement mais Docker va monitorer le processus tail et non plus foo. Si foo crash, le conteneur ne passera pas en failed et ne pourra pas être redémarré automatiquement.

À supposer que foo ne puisse pas envoyer ses logs sur stdout, le bon example serait :

CMD touch /var/log/foo.log && tail -f /var/log/foo.log & /usr/bin/foo

À noter que seulement une seule directive CMD est acceptée dans un Dockerfile.

On peut ensuite construire notre image, en lui donnant ici le tag rsyslog :

~/docker-images/rsyslog $ ls
Dockerfile      custom.conf
~/docker-images/rsyslog $ docker build -t rsyslog .
~/docker-images/rsyslog $ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
rsyslog             latest              4bea99cda08c        8 minutes ago       470MB
debian              stretch             5b712ae16dd7        3 days ago          100MB

Utilisation avancée

Docker registry

Un docker registry permet d'héberger des images Docker.

On peut le déployer avec la stack suivante :

version: "3.6"

services:

  registry:
    image: registry:2
    deploy:
      replicas: 1
      restart_policy:
          condition: on-failure
    environment:
      REGISTRY_HTTP_TLS_CERTIFICATE: /run/secrets/certificate
      REGISTRY_HTTP_TLS_KEY: /run/secrets/certificate
      REGISTRY_HTTP_ADDR: 0.0.0.0:5000
    volumes:
      - registry:/var/lib/registry
    secrets:
      - certificate
    ports:
      - :5000:5000

volumes:
  registry:

secrets:
  certificate:
    file: certificate.pem

Attention, le certificat doit absolument être valide et le Common Name doit correspondre avec le nom utilisé pour y accéder.

Lors d'un déploiement d'une stack existante, en cas d'erreur :

image registrydocker.example.com:5000/XXX could not be accessed on a registry to record
its digest. Each node will access registrydocker.example.com:5000/XXX independently,
possibly leading to different nodes running different
versions of the image.

Il peut s'agir de différents problèmes (réseau, SSL, etc…), Docker n'est pas très bavard sur la cause de l'échec. Un bon moyen de déboguer la situation est avec :

$ curl https://registrydocker.example.com:5000/v2/_catalog

La requête devrait retourner la liste des images hébergées au format json.

Swarm

Swarm permet de mettre en communication plusieurs hôtes Docker afin d'en former un cluster. On pourra ainsi déployer des applications multi-conteneurs sur plusieurs machines.

Initialiser le cluster

docker0# docker swarm init

Joindre les autres machines au cluster créé (il vous suffit généralement de copier-coller la commande retournée par docker swarm init :

docker1# docker swarm join --token <token> <IP du premier node>

Par défaut la machine sur laquelle le cluster a été initialisée a le rôle de manager, et les suivantes ont le rôle de worker. On ne peut déployer de nouveaux services que depuis les managers. Les workers se contentent de recevoir les services à rouler.

Pour ajouter des machines plus tard, il suffit de générer un nouveau token :

docker0# docker swarm join-token <manager|worker>

Lister les machines du cluster

# docker node ls

Ajouter des labels à une machine

# docker node update --label-add <clé>=<valeur> <machine>

Les labels servent notamment à définir des contraintes de placement des services lors de l'utilisation de docker stack.

Compose/stack (docker stack)

Docker permet de déployer des infrastructures multi-conteneurs (stacks) simplement à l'aide de docker stack (anciennement Docker Compose, logiciel tier). Il est très utile dans le cadre de déploiement sur un cluster Swarm.

L'infra est à décrire dans un fichier YAML.

Déployer (ou mettre à jour à chaud) une nouvelle stack :

# docker stack deploy -c <stack_name.yml> <stack name>

Lister les stacks :

# docker stack ls

Lister les services, toutes stacks confondues ou pour une stack donnée :

# docker service ls
# docker stack services <stack name>

Lister les tasks (replicas) d'une stack ou d'un service donné :

# docker stack ps <stack name>
# docker service ps <service name>

Supprimer une stack :

# docker stack rm <stack name>

Réseaux (docker network)

Docker permet de gérer différentes topologies de réseaux pour connecter les conteneurs entre eux à l'aide de docker network.

drivers réseau supportés :

  • bridge : utilise les bridges Linux ;
  • overlay : utilisé dans le cas d'un cluster Swarm, permet d'avoir un réseau unique partagé entre tous les hôtes Docker et permet de faire du load-balancing entre les conteneurs (replicas) d'un service ;
  • macvlan : permet d'assigner directement des adresses IP publiques aux conteneurs, donc aucun NAT n'est fait contrairement aux précédents.

Créer un réseau :

# docker create -d <driver> […] <network name>

Lister les réseaux créés :

# docker network ls

Informations détaillées sur un réseau :

# docker network inspect <network name>

Volumes (docker volume)

Les volumes Docker sont des répertoires ou fichiers présents sur l'hôte qui peuvent être montés à l'intérieur des conteneurs. L'intérêt est de pouvoir écrire des données persistantes depuis les conteneurs, qui seront alors conservés après arrêt et suppression du conteneur et accessible depuis l'hôte. Les volumes sont indépendants des conteneurs.

Ils sont généralement utilisés pour stocker des fichiers de logs, des répertoires de bases de données ou des configuration.

Sauf si un chemin est spécifié, Docker mets ses volumes dans /var/lib/docker/volumes/, et les données sont accessibles dans /var/lib/docker/volumes/"nom du volume"/_data/.

On peut gérer les volumes avec la commande docker volume :

# docker volume create vol1
vol1
# docker volume ls
DRIVER              VOLUME NAME
local               vol1
# docker volume rm vol1
vol1

Dans le cas d'un cluster Docker Swarm, les volumes ne sont pas répliqués entre les membres du cluster. Si un conteneur monte un volume, il faut bien penser à restreindre son placement à un Docker node spécifique, ou bien mettre en place un système de réplication de fichiers tier.

Fichiers de configuration (docker config)

Les config sont des objets permettant de stocker un unique fichier, généralement un fichier de configuration d'un service.

À la différence des volumes, les config sont répliqués au sein d'un cluster Swarm, ce qui permet de ne pas avoir à copier le fichier de configuration sur chaque serveur. Lors de la création de l'objet config, il sera rendu accessible à tous les membres du cluster qui en auront besoin.

À l'intérieur des conteneurs, les objets config sont montés en lecture seule. Un processus qui a besoin de réécritre lui-même sa configuration durant son exécution ne marchera donc pas, et il faudra préférer l'utilisation d'un volume.

Les config ne peuvent pas non plus être mis à jour lors d'un redéploiement de stack :

failed to update config foo: Error response from daemon: rpc error: code = InvalidArgument desc = only updates to Labels are allowed

Il faut obligatoirement soit supprimer l'objet config et donc les objets qui en dépendent (conteneurs), soit créer un nouveau config (avec un nouveau nom donc) et l'ajouter au conteneur en question (non testé). On perd donc la souplesse des volumes dans ce cas là.

Les config se gèrent avec la commande docker config. Le serveur doit avoir le rôle manager dans le cluster Swarm pour pouvoir créer un objet config, puisque cela impacte l'ensemble du cluster :

# docker config create vim-config .vimrc
07kaw58mhvtkqem46ipkd97i1
# docker config ls
ID                          NAME                                   DRIVER              CREATED                  UPDATED
07kaw58mhvtkqem46ipkd97i1   vim-config                                                 Less than a second ago   Less than a second ago
# docker config rm vim-config
vim-config

Fichiers sensibles (docker secrets)

Ce sont des objets permettant de stocker des fichiers, au même titre que les configs, mais dédiés aux fichiers sensibles comme les clés privée ou fichiers contenant des mots de passe.

Ils sont rendus accessibles dans /run/secrets/ dans les conteneurs.

Les secret héritent des mêmes caractéristiques que les config (voir ci-dessus), à savoir qu'ils sont accessibles partout dans un cluster Swarm mais ne peuvent ni être modifiés depuis un conteneur ni depuis l'hôte, ils doivent être recréés en cas de modification.

Les config se gèrent avec la commande docker secret.

Fichier YAML de description de stack (anciennement docker-compose.yml)

Les stacks Docker se décrivent à l'aide d'un fichier YAML. Anciennement le déploiement d'une stack se faisait à l'aide de Docker-compose et le fichier s'appelait couramment docker-compose.yml. Docker stack ne définit pas de nom par défaut donc il peut porter n'importe quel nom.

Le fichier contient une description de tous les objets Docker à créer pour déployer une stack de zéro.

Tout ce que l'on peut faire avec le fichier YAML peut être fait avec les commandes docker équivalentes (docker service, docker volume, docker config, etc…). Le nom des commandes et options sont exactement les mêmes. Le format YAML permet simplement de rendre plus simple la description d'une stack qu'une série de commandes.

Référence sur le format du fichier : https://docs.docker.com/compose/compose-file/

Voici un aperçu :

$ cat ma-stack.yml
version: "3.6"

services:

  web:
    image: my-website:latest
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
      - "443:443"
    environment:
      - MYSQL_DB=foo_dev
      - MYSQL_USER=foo_dev
      - MYSQL_PASS=deb2Ozpifut?
    secrets:
      - ssl_cert
    configs:
      - source: nginx
        target: /etc/nginx/nginx.conf

  mysql:
    image: mariadb:latest
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.labels.role == sql
    volumes:
      - mysql-datadir:/var/lib/mysql

volumes:
  mysql-datadir:

configs:
  nginx:
    file: nginx.conf

secrets:
  ssl_cert:
    file: example.com.pem

On lance ici 2 services, web et mysql. On spécifie que web doit avoir 2 réplicas, il y aura donc 2 tasks (et donc 2 conteneurs) qui seront démarrés, peu importe où sur le cluster.

Pour le service mysql par contre, on spécifie une contrainte de placement de la task, elle doit être démarré sur une machine du cluster ayant le label role == sql. La raison est que comme on lui a associé un volume pour son datadir, il doit toujours être exécuter sur la même machine (les volumes ne sont pas répliqués entre les machines d'un cluster).

On ne spécifie pas de chemin pour le volume mysql_datadir, donc Docker le créera par défaut dans _/var/lib/docker/volumes/ma-stack_mysql-datadir/ sur la machine hôte.

Le service web à besoin d'une config appelée nginx et d'un secret appelé ssl_cert que l'on déclare tout en bas et qui contiennent respectivement le fichier nginx.conf et example.com.pem dans notre répertoire courant, à côté du ma-stack.yml. Lorsque Docker crée une config ou un secret (au déploiement de la stack), il les rend disponible à tous les membres du cluster, ce qui fait qu'on n'a pas besoin de spécifier de contrainte de placement pour web.

Ensuite on peut déployer notre stack :

$ ls
ma-stack.yml        nginx.conf      example.com.pem
$ docker stack deploy -c ma-stack.yml ma-stack

Surcharge de paramètre

On peut surcharger certains paramètres définit dans le premier en créant un second fichier contenant seulement les paramètres à surcharger. Les 2 fichiers devront être passer en paramètre de docker stack deploy et ils seront alors fusionnés. Cela permet de réutiliser un fichier de stack pour différents environnement (preprod, prod…) en changeant uniquement des variables d'environement, mots de passe, etc…

$ cat ma-stack.dev.yml
version: "3.6"
services:
  web:
    environment:
      - DEBUG=1
      - MYSQL_DB=foo_dev
      - MYSQL_USER=foo_dev
      - MYSQL_PASS=deb2Ozpifut?

On peut ensuite déployer ainsi :

$ docker stack deploy -c ma-stack.yml -c ma-stack.dev.yml ma-stack

FAQ

Les conteneurs ont des problèmes de connectivités entre eux/vers l'extérieur

C'est très probablement lié à un outil manipulant les règles netfilter qui a effacé les règles spécifiques à Docker, notamment dans la table nat.

Pour restaurer les règles netfilter de Docker, il n'y a pas d'autre moyen que de redémarrer le démon :

# /etc/init.d/docker restart

Espace insuffisant lors du build d'une image

Solutions:

  • Vérifier que le "build context" n'est pas trop grand.
  • Modifier la variable d'environnement DOCKER_TMPDIR .
  • Créer un fichier .dockerignore pour exclure des fichiers et répertoires du "build context"

Build context: Tout ce qui se trouve à la racine du Dockerfile.

Lors d'un redéploiement d'une stack Docker (docker stack deploy), les services ne sont pas redémarrer avec la nouvelle image

Vérifier que le tag latest est bien précisé dans le nom de l'image dans le docker-stack.yml :

      image: registrydocker.example.com:5000/foo:latest

Est-il possible de ne faire écouter un service d'une stack que sur une interface précise de la machine hôte (par exemple sur un LAN privé) ?

Non, Docker ne supporte pas ça. Il faut bloquer le port en question dans le pare-feu, dans la chaîne iptables DOCKER-USER.

Pour bloquer l'accès au registry Docker depuis l'extérieur par exemple :

# iptables -A DOCKER-USER -i eth0 -p tcp -m tcp --dport 5000 -j DROP

Au sein des conteneurs, un getent <service> ou getent tasks.<service> ne retourne pas l'adresse IP du service alors que celui-ci est bien lancé.

Stopper le conteneur du service avec un docker stop <conteneur du service>. Docker stack devrait le relancer automatiquement.

Comment obtenir l'adresse IP des tasks d'un service (dans le cadre de l'utilisation de Docker stack) au sein de conteneur (à des fins de debug) ?

L'adresse IP virtuelle qui redirige aléatoirement sur chacune des tasks (si le réseau utilise le driver overlay, cas par défaut) :

$ getent hosts <nom du service>

L'adresse IP des différentes tasks d'un service :

$ getent hosts tasks.<nom du service>

Comment trouver le PID d'un processus roulant dans un conteneur?

Docker et autres technologies de conteneurs, utilisent des namespace linux pour isoler les processus. Lutilité pgrep(1) est capable de filtrer les processus par namespace sur la base dun autre processus.

$ pgrep --ns $dockerPID $query

Ce concept provient du système Plan9

Accéder aux ports locaux (docker-proxy) avec minifirewall

Vous devez autoriser l'interface docker0

# Autorisation Docker
/sbin/iptables -A INPUT -i docker0 -j ACCEPT