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?
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écuterdocker 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 deexec
.
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 LXClxc-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.
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.
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 quedocker 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.
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.