web-dev-qa-db-fra.com

Pourquoi "docker attach" est-il bloqué?

Je peux exécuter un conteneur ubuntu avec succès: 

# docker run -it -d ubuntu
3aef6e642327ce7d19c7381eb145f3ad10291f1f2393af16a6327ee78d7c60bb
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3aef6e642327        ubuntu              "/bin/bash"         3 seconds ago       Up 2 seconds                            condescending_sammet

Mais l'exécution de docker attach se bloque: 

# docker attach 3aef6e642327

Jusqu'à ce que j'appuie sur une touche, telle que Enter

# docker attach 3aef6e642327
root@3aef6e642327:/#
root@3aef6e642327:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

Pourquoi docker attach se bloque-t-il?

Mettre à jour

Après avoir lu les commentaires, je pense avoir les réponses: 

prérequis: 

"docker attach" réutilise le même tty, n'ouvre pas le nouveau tty.  

(1) Exécution du mode docker run sans démon: 

# docker run -it ubuntu
root@eb3c9d86d7a2:/# 

Tout va bien, lancez la commande ls

root@eb3c9d86d7a2:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@eb3c9d86d7a2:/#

(2) Exécutez docker run en mode démon: 

# docker run -it -d ubuntu
91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc

En fait, les éléments suivants auraient dû être sortis du répertoire en cours sur stdout:  

root@91262536f7c9:/#

Donc, exécuter docker attach semble être bloqué, mais en réalité, il attend votre entrée:

# docker attach 91262536f7c9
ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@91262536f7c9:/#
44
Nan Xiao

Cela ne fait pas vraiment coup. Comme vous pouvez le voir dans le commentaire ci-dessous (vous exécutez "/bin/bash" en tant que commande), il semble que le comportement attendu lors de l'attachement. 

Autant que je sache, vous vous attachez au shell en cours d’exécution et uniquement à stdin/stdout/stderr - en fonction des options que vous transmettez à la commande run - vous montrera simplement ce qui se passe dans/hors à partir de ce moment-là. (Quelqu'un avec une connaissance un peu plus approfondie espère pouvoir l'expliquer à un niveau supérieur). 

Comme je l'ai écrit dans votre commentaire sur votre question, plusieurs personnes ont ouvert un problème dans le dépôt de docker github décrivant un comportement similaire:

Puisque vous parlez de Shell, je suppose que vous avez déjà un Shell en cours d'exécution. attach ne démarre pas un nouveau processus, quel est donc le comportement attendu de la connexion aux flux in/out/err d'un processus en cours d'exécution? Je n'ai pas pensé à ça. Bien entendu, c’est le comportement attendu de la liaison à un shell en cours d’exécution, mais est-il souhaitable?

Serait-il possible de vider stdout/stderr sur l'attache de docker, forçant ainsi l'invite Shell à être imprimée ou est-ce un peu plus complexe que cela? C'est ce à quoi je m'attendrais personnellement lorsque je m'attache à un Shell en cours d'exécution.

Ne hésitez pas à fermer cette question si nécessaire, j'ai juste ressenti le besoin de documenter cela et obtenir des commentaires.

  • Tiré d'un commentaire sur ce problème de github . Vous pouvez trouver plus d'informations dans les commentaires de ce numéro.

Si, au lieu de enter, vous commenciez à taper une commande, la ligne d'invite extra vide ne s'afficherait pas. Si tu devais courir

$ docker exec -it ubuntu <container-ID-or-name> bash 

<container-ID-or-name> est l'ID ou le nom du conteneur après l'exécution de docker run -it -d ubuntu (donc 3aef6e642327 ou condescending_sammet dans votre question), il exécuterait une commande nouveau, sans avoir ce "problème stdout" d'attachement à un existant .

Exemple

Si vous aviez une Dockerfile dans un répertoire contenant:

FROM ubuntu:latest
ADD ./script.sh /timescript.sh 
RUN chmod +x /timescript.sh
CMD ["/timescript.sh"]

Et avoir un simple script bash script.sh dans le même répertoire contenant:

#!/bin/bash

#trap ctrl-c and exit, couldn't get out
#of the docker container once attached
trap ctrl_c INT
function ctrl_c() {
    exit
}

while true; do
    time=$(date +%N)
    echo $time;
    sleep  1;
done

Puis construisez (dans cet exemple, dans le même répertoire que Dockerfile et script.sh) et exécutez-le avec

$ docker build -t nan-xiao/time-test .
..stuff happening...
$ docker run -itd --name time-test nan-xiao/time-test

Enfin attach

$ docker attach time-test

Vous allez vous retrouver attaché à un conteneur imprimant le temps à chaque seconde. (CTRL-C pour sortir)

Exemple 2

Ou si vous avez une Dockerfile contenant par exemple ce qui suit:

FROM ubuntu:latest
RUN apt-get -y install irssi
ENTRYPOINT ["irssi"]

Puis lancez dans le même répertoire:

$ docker build -t nan-xiao/irssi-test .

Puis lancez-le:

$ docker run -itd --name irssi-test nan-xiao/irssi-test

Et enfin

$ docker attach irssi-test

Vous vous retrouveriez dans une fenêtre irssi en cours d'exécution sans ce comportement particulier. Bien sûr, vous pouvez remplacer irrsi par un autre programme.

27

J'ai rencontré ce problème également lors de la tentative de liaison à un conteneur développé par quelqu'un d'autre et exécutant déjà un démon. (Dans ce cas, il s’agissait de l’image transmission du menu fixe de LinuxServer). 

Problème:

Ce qui s’est passé, c’est que le terminal a semblé «se bloquer», où taper quoi que ce soit n’aide en rien et ne se présente pas. Seul Ctrl-C me renverrait. 

docker run, docker start, docker attach tout a échoué, la commande dont j'avais besoin (une fois le conteneur démarré avec run ou start) était destinée à exécuter bash, car il est fort probable que le conteneur extrait n'a pas déjà démarré bash. 

Solution:

docker exec -it <container-id> bash 

(vous pouvez trouver le container-id à partir de docker ps -a).

Cela vous entraînera dans l'instance avec un bash fonctionnel comme root (en supposant qu'il n'y a pas eu d'autre configuration explicite faite par l'image que vous avez extraite).

Je sais que la réponse acceptée a également capturé cela, mais a décidé d'en publier une autre un peu plus concise et plus évidente, car la solution ne m'est pas apparue lorsque je l'ai lue.

12
matrixanomaly

Quand je lance docker attach container-name, alors rien ne sort, même Ctrl-c n'est pas valide. Alors, essayez d'abord

docker attach container-name --sig-proxy=false

et alors ctrl-c peut l'arrêter. Pourquoi n'a-t-il rien généré? ... simplement parce que le conteneur ne l'a pas généré. En fait, je dois entrer dans mon conteneur et exécuter une commande Shell. Donc, la commande correcte est 

docker exec -ti container-name bash
1
Billy Yang

Cela m'est arrivé une fois pour la raison suivante:

Il se peut que la commande bash à l'intérieur du conteneur exécute une commande "cat".

Ainsi, lorsque vous attachez le conteneur (la commande bash), vous vous trouvez réellement dans la commande cat qui attend une entrée. (texte et/ou ctrl-d pour écrire le fichier)

1
HerbalMart

Je viens d'avoir un problème similaire aujourd'hui et j'ai pu le résoudre:

Voici ce qui se passait pour moi:

docker-compose logs -f nginx
Attaching to laradock_nginx_1

Ensuite, ça resterait là jusqu'à ce que je quitte via CTRL-C: ^CERROR: Aborting.

docker ps -a a montré que ce qui aurait dû s'appeler laradock_nginx n'existait pas avec ce nom d'image.

docker stop cce0c32f7556
docker rm cce0c32f7556
docker-compose up -d laradock_nginx

Malheureusement: ERROR: No such service: laradock_nginx

J'ai donc fait un Sudo reboot puis un docker ps -a, mais laradock_nginx n'y était toujours pas.

Heureusement, docker-compose up -d nginx a ensuite fonctionné et docker-compose logs -f nginx fonctionne maintenant.

0
Ryan

Si vous ne pouvez pas accéder à la ligne de commande, assurez-vous d’exécuter votre conteneur avec le drapeau -i au début.

0
Ali Motameni