Подтвердить что ты не робот

Почему "прикрепление докеров" зависает?

Я могу успешно запустить контейнер ubuntu:

# 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

Но выполнение docker attach зависает:

# docker attach 3aef6e642327

Пока я не нажимаю какую-либо клавишу, например Enter:

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

Почему docker attach зависает?

Обновить:

Прочитав комментарии, я думаю, что получаю ответы:

предпосылка:

"docker attach" повторное использование одного и того же tty, а не открытие нового tty.

(1) Выполнение docker run без режима демона:

# docker run -it ubuntu
[email protected]:/# 

Все в порядке, затем запустите команду ls:

[email protected]:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[email protected]:/#

(2) Запустите docker run в режиме демона:

# docker run -it -d ubuntu
91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc

На самом деле, в стандартный вывод из работающего контейнера должно выводиться следующее:

[email protected]:/#

Так что выполнение docker attach похоже на зависание, но на самом деле оно ждет вашего ввода:

# docker attach 91262536f7c9
ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[email protected]:/#
4b9b3361

Ответ 1

На самом деле это не висит. Как вы можете видеть в комментарии ниже (вы запускаете команду "/bin/bash" ), похоже, это будет ожидаемое поведение при подключении.

Насколько я понимаю, вы прикрепляетесь к рабочей оболочке, а только stdin/stdout/stderr - в зависимости от параметров, которые вы передаете вместе с командой run, - просто покажет вам, что входит в/из с этого момента. (Кто-то с немного более глубокими знаниями надежно может объяснить это на более высоком уровне).

Как я писал в своем комментарии к вашему вопросу, есть несколько человек, которые открыли проблему в репозитории docker github, описывая подобное поведение:

Поскольку вы упоминаете оболочку, я предполагаю, что у вас уже запущена оболочка. attach не запускает новый процесс, так каково ожидаемое поведение подключения к потокам in/out/err текущего процесса?   Я об этом не думал. Конечно, это ожидаемое поведение присоединения к рабочей оболочке, но желательно ли это?

Было бы возможно сбросить stdout/stderr на докере-присоединение, тем самым вынудив приглашение оболочки распечатать или это немного сложнее? Это то, что я лично "ожидал" при подключении к уже запущенной оболочке.

Не стесняйтесь закрыть эту проблему, если это необходимо, я просто почувствовал необходимость документировать это и получить некоторую обратную связь.

  • Взято из comment в этом проблема github. Вы можете найти больше информации в комментариях к этой проблеме.

Если вместо enter вы начнете вводить команду, вы не увидите лишнюю пустую строку подсказки. Если вы запустите

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

где <container-ID-or-name> - это идентификатор или имя контейнера после запуска docker run -it -d ubuntu (так что 3aef6e642327 или condescending_sammet в вашем вопросе), он будет запускать новую команду, поэтому не будет иметь эту проблему "stdout" для присоединения к существующему один.

Пример

Если у вас есть Dockerfile в каталоге, содержащем:

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

И иметь простой bash script script.sh в том же каталоге, который содержит:

#!/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

Затем создайте (в этом примере в том же каталоге, что и файл Dockerfile и script.sh), и запустите его с помощью

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

Наконец attach

$ docker attach time-test

В конечном итоге вы будете прикреплены к контейнеру, распечатывая время каждую секунду. (CTRL-C, чтобы выйти)

Пример 2

Или, если у вас есть Dockerfile, содержащий, например, следующее:

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

Затем запустите в том же каталоге:

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

Затем запустите его:

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

И наконец

$ docker attach irssi-test

Вы попадете в текущее irssi окно без этого конкретного поведения. Конечно, вы можете заменить irrsi на другую программу.

Ответ 2

Я столкнулся с этой проблемой и при попытке подключиться к контейнеру, который был разработан кем-то еще и уже запущен демон. (В этом случае это было изображение LinuxServer transmission docker).

Проблема:

То, что произошло, оказалось, что терминал оказался "висеть", где печатать что-то не помогло и не появлялось. Только Ctrl-C ударит меня назад.

docker run, docker start, docker attach все не удалось, оказалось, что мне нужна команда (после того, как контейнер был запущен с run или start), чтобы выполнить bash, так как шансы вы вытаскиваете из контейнера, у которого уже нет bash.

Решение:

docker exec -it <container-id> bash

(вы можете найти container-id для запуска docker ps -a).

Это приведет вас к экземпляру с функциональным bash как root (если не будет никакой другой явной настройки, сделанной вытащившим изображение).

Я знаю, что принятый ответ зафиксировал это также, но решил опубликовать еще один, немного более краткий и очевидный, поскольку решение не выскакивало для меня, когда я читал его.

Ответ 3

Это произошло со мной по следующей причине:

Может быть, команда bash внутри контейнера выполняет команду "cat".

Итак, когда вы прикрепляетесь к контейнеру (команда bash), вы действительно находитесь внутри команды cat, которая ожидает ввода. (текст и/или ctrl-d для записи файла)

Ответ 4

Если вы не можете получить доступ к командной строке, просто убедитесь, что вы запускаете свой контейнер с флагом -i при запуске.

Ответ 5

Когда я запускаю docker attach container-name, тогда ничего не выводится, даже Ctrl-c недействительно. Итак, сначала попробуйте

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

а затем ctrl-c может остановить его. Почему это ничего не выводило? просто потому, что контейнер не выводит. На самом деле мне нужно ввести мой контейнер и запустить некоторую команду оболочки. Поэтому правильная команда

docker exec -ti container-name bash