web-dev-qa-db-fra.com

différence entre le docker attach et le docker exec

Les deux pourront exécuter des commandes dans le conteneur. Les deux pourraient détacher le conteneur.

Alors, quelle est la vraie différence entre docker exec et docker attach?

57
MJL

Il y avait un commit PR qui a ajouté à la doc:

Remarque: Cette commande (attach) ne permet pas d'exécuter un nouveau processus dans un conteneur . Voir: docker exec

La réponse à " Docker. Comment obtenir bash\ssh dans un conteneur exécuté (run -d)? " illustre la différence:

(menu fixe> = 1.3) Si nous utilisons docker attach , , nous ne pouvons utiliser qu'une seule instance de Shell.
Donc, si nous voulons ouvrir un nouveau terminal avec une nouvelle instance du shell du conteneur, nous devons simplement exécuter docker exec

si le conteneur Docker a été démarré à l'aide de la commande /bin/bash, vous pouvez y accéder à l'aide de l'attachement. Sinon, vous devez alors exécuter la commande execute _ pour créer une instance bash dans le conteneur à l'aide de exec.

Comme mentionné dans ce numéro :

  • Attach ne sert pas à exécuter une tâche supplémentaire dans un conteneur, mais à attacher au processus en cours. 
  • "docker exec" est spécifiquement destiné à l'exécution de nouvelles choses dans un conteneur déjà démarré, que ce soit un shell ou un autre processus. 

Le même problème ajoute:

Bien que attach ne soit pas bien nommé, en particulier à cause de la commande LXC lxc-attach (qui ressemble plus à docker exec <container> /bin/sh, mais spécifique à LXC), son objectif spécifique est de vous lier littéralement au processus lancé par Docker.
Selon le processus, le comportement peut être différent, par exemple, attacher à /bin/bash vous donnera un shell, mais attacher à redis-server sera comme si vous veniez de démarrer redis directement sans démonisation.

66
VonC

Lorsqu'un conteneur est démarré avec/bin/bash, il devient alors le conteneur PID 1 et le docker attach est utilisé pour entrer à l'intérieur du PID 1 d'un conteneur. So docker attach <conteneur-id> vous mènera à l’intérieur du terminal bash car il s’agit du PID 1, comme nous l’avons mentionné lors du démarrage du conteneur. La sortie du conteneur arrêtera le conteneur.

Tandis que dans docker exec command, vous pouvez spécifier le shell dans lequel vous voulez entrer. Cela ne vous mènera pas au PID 1 du conteneur. Un nouveau processus sera créé pour bash . docker exec -it <id-conteneur> bash . La sortie du conteneur n’arrête pas le conteneur.

Vous pouvez également utiliser nsenter pour entrer dans les conteneurs . nsenter -m -u -n -p -i -t <pid du conteneur> Vous pouvez trouver le PID du conteneur en utilisant: docker inspecter <conteneur-id> | Grep PID

Remarque: Si vous avez démarré votre conteneur avec l'option -d, le fait de quitter le conteneur en dehors du conteneur n'arrêtera pas le conteneur, que vous utilisiez l'attachement ou l'exécutable pour y entrer.

10

Comme Michael Sun l'a déclaré dans sa réponse

docker exec exécute une nouvelle commande/crée un nouveau processus dans l'environnement du conteneur, tandis que docker attach ne fait que connecter l'entrée/sortie/erreur standard du processus principal (avec le PID 1) à l'intérieur du conteneur à l'entrée standard correspondante./output/error du terminal actuel (le terminal que vous utilisez pour exécuter la commande).

Ma réponse visera surtout à vous permettre de valider la déclaration ci-dessus et de la comprendre plus clairement.

Ouvrez une fenêtre de terminal et exécutez la commande docker run -itd --name busybox busybox /bin/sh. La commande va tirer l'image busybox si elle n'est pas déjà présente. Il créera ensuite un conteneur avec le nom busybox en utilisant cette image.

Vous pouvez vérifier l'état de votre conteneur en exécutant la commande docker ps -a | grep busybox.

Si vous exécutez docker top busybox, vous devriez voir une sortie ressemblant à ceci.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh

Bien entendu, les valeurs PID, PPID et les autres seront différentes dans votre cas. Vous pouvez également utiliser d'autres outils et utilitaires tels que pstree, top, htop pour afficher la liste des PID et PPID.

Les variables PID et PPID désignent l'identifiant du processus et l'identifiant du processus parent. Le processus a démarré lorsque nous avons créé et démarré notre conteneur avec la commande /bin/sh. Maintenant, exécutez la commande docker attach busybox. Cela attachera le flux d'entrée/sortie/erreur standard du conteneur à votre terminal.

Après avoir associé le conteneur, créez une session Shell en exécutant la commande sh. Appuyez sur la séquence CTRL-p CTRL-q. Cela détachera le terminal du conteneur et le maintiendra en fonctionnement. Si vous exécutez maintenant docker top busybox, vous devriez voir deux processus dans la liste.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh

Mais la PPID des deux processus sera différente. En fait, la PPID du deuxième processus sera la même que PID du premier. Le premier processus agit en tant que processus parent pour la session Shell que nous venons de créer.

Maintenant, lancez docker exec -it busybox sh. Une fois dans le conteneur, vérifiez la liste des processus en cours pour le conteneur busybox dans une autre fenêtre de terminal en exécutant la commande docker top busybox. Vous devriez voir quelque chose comme ça

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh
root                7880                7451                0                   11:45               pts/1               00:00:00            sh

Le PPID du premier et du troisième processus sera le même, ce qui confirme que docker exec crée un nouveau processus dans l'environnement du conteneur, tandis que docker attach ne connecte que l'entrée/sortie/erreur standard du processus principal à l'intérieur du conteneur à l'entrée/sortie standard correspondante/erreur du terminal actuel.

1
Kartik Chauhan

Docker exec exécute une nouvelle commande/crée un nouveau processus dans l'environnement du conteneur, tandis que docker attach connecte simplement l'entrée/sortie standard/l'erreur du processus principal (avec le PID 1) à l'intérieur du conteneur à l'entrée/sortie/erreur standard correspondante du courant. terminal (le terminal que vous utilisez pour exécuter la commande).

Un conteneur est un environnement isolé, avec certains processus s'exécutant dans l'environnement. Plus précisément, un conteneur possède son propre espace de système de fichiers et son propre espace PID isolés de l'hôte et d'autres conteneurs. Lorsque le conteneur est démarré à l'aide de «docker run –it…», le processus principal aura un pseudo-tty et STDIN maintenu ouvert. Une fois connecté en mode tty, vous pouvez vous détacher du conteneur (et le laisser fonctionner) à l'aide d'une séquence de touches configurable. La séquence par défaut est CTRL-p CTRL-q. Vous configurez la séquence de touches à l'aide de l'option --detach-keys ou d'un fichier de configuration. Vous pouvez vous rattacher à un conteneur détaché avec une fixation de menu fixe.

Docker exec commence juste un nouveau processus, dans l’environnement du conteneur, c’est-à-dire qu’il appartient à l’espace PID du conteneur.

Par exemple, si vous démarrez votre conteneur avec "docker run –dit XXX/bin/bash", vous pouvez vous connecter au conteneur (processus principal) à l'aide de deux terminaux différents. Pendant que vous entrez dans un terminal, vous pouvez voir qu'il apparaît dans l'autre terminal, car les deux terminaux sont connectés au même terminal. Faites attention que vous êtes maintenant dans le processus principal du conteneur, si vous tapez "exit", vous quitterez le conteneur ( soyez donc prudent, en utilisant des clés de détachement pour vous détacher ), et vous verrez les deux terminaux sont sortis. Mais si vous exécutez “docker exec –it XXX/bin/bash” dans deux terminaux, vous avez démarré deux nouveaux processus à l'intérieur du conteneur, et ils ne sont pas liés l'un à l'autre et au processus principal, et vous pouvez en toute sécurité. sortir d'eux.

0
Michael.Sun