Как войти в контейнер Docker, который уже запущен, с новым TTY

У меня есть контейнер, в котором на переднем плане запущена служба Apache. Я хотел бы иметь возможность получить доступ к контейнеру из другой оболочки, чтобы «ковыряться» внутри него и исследовать файлы. В настоящий момент, если я присоединяюсь к контейнеру, я смотрю на демон Apache и не могу выполнять никакие команды.

Можно ли подключить еще один tty к работающему контейнеру? Возможно, я смогу воспользоваться тем фактом, что Docker на самом деле просто оборачивается вокруг контейнеров LXC? Я пробовал sudo lxc-console -n [container-id] -t [1-4], но оказалось, что доступен только один tty, на котором запущен демон apache. Возможно, есть способ включить несколько консолей lxc во время сборки?

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


person Programster    schedule 05.01.2014    source источник
comment
Вы пробовали docker attach [conainer-id]?   -  person shabbychef    schedule 01.04.2014
comment
@shabbychef, если docker attach не изменилось, команда attach подключается к работающему tty, а не к новому, поэтому заголовок вопроса ... с новым TTY. Вот почему в приведенном ниже ответе не используется команда подключения.   -  person Programster    schedule 01.04.2014
comment
Начиная с версии 1.3 существует более простой способ, описанный в этом ответе   -  person Thomasleveil    schedule 23.10.2014


Ответы (10)


В docker 1.3 появилась новая команда docker exec. Это позволяет вам войти в работающий контейнер:

docker exec -it [container-id] bash

Примечание. Предполагается, что в вашем контейнере установлен bash. Вы можете запустить sh или любую другую интерактивную оболочку, установленную в контейнере.

person Michael_Scharf    schedule 21.10.2014
comment
Я изменил это на правильный ответ (из моего собственного), потому что этот новый метод, которого не было во время вопроса, является лучшим текущим методом IMO. - person Programster; 29.10.2014
comment
Однако обратите внимание, что exec не работает как обычный терминал. Например, вы не можете сменить пользователя один раз внутри контейнера. - person Pithikos; 29.10.2014
comment
Для docker 1.2 используйте nsenter. В OS X и Windows вы можете следовать инструкциям nsenter. - person Michael_Scharf; 06.02.2015
comment
@Pithikos: Я могу использовать exec для запуска оболочки, а затем su someuser для смены пользователя. Запуск Docker 1.4.1 - person lsh; 02.03.2015
comment
Примечание для всех, кто читает это обсуждение. Я уверен, что docker exec -it в конечном итоге предоставит полнофункциональный псевдотерминал, но на данный момент (версия Docker 1.9.1) есть некоторые недостатки: github.com/docker/docker/issues/8755 - person blong; 05.01.2016
comment
если вы получаете сообщение об ошибке «exec: bash: исполняемый файл не найден в $ PATH», вы можете попробовать следующее: docker exec -it [container-id] / bin / sh - person Dai Kaixian; 12.09.2016
comment
При условии, что в некоторых случаях bash недостаточно, нам нужно установить PID1 как / bin / bash docker exec -it [container-id] / bin / bash - person Alok Adhao; 05.04.2017
comment
Здесь, в Alpine, если для контейнера определено имя: docker exec -it NAME /bin/sh - person Junior Mayhé; 17.05.2017
comment
Имя контейнера также будет делать то же самое. - person Arefe; 15.03.2019
comment
Это не сработает, если контейнер работает роем. Я еще не нашел способа сделать это ... но был бы признателен, если бы кто-нибудь знал. Есть предложения, @Michael_Scharf? Он всегда говорит Error: No such container: <container-id>, даже если на том же / единственном узле, где существует и работает служба. - person code_dredd; 16.01.2020
comment
-it = --interactive + --tty? - person Andrey Kurnikovs; 19.06.2021

Вы должны использовать инструмент Жерома Петаццони под названием 'nsenter' для входа в контейнер без использования SSH. См .: https://github.com/jpetazzo/nsenter

Установить, просто запустив: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Затем используйте команду docker-enter <container-id>, чтобы войти в контейнер.

person Hyperfocus    schedule 05.07.2014
comment
Это правильный путь. См. блог. - person Jesse Glick; 18.07.2014
comment
В docker 1.3 появилась новая команда docker exec. Это позволяет вам войти в работающий докер: docker exec -it <container-id> bash (см. Мой ответ ниже) - person Michael_Scharf; 24.10.2014
comment
docker-enter все еще существует? Это дает мне command not found. - person Snowcrash; 10.10.2016

Обновить

Начиная с docker 0.9, чтобы шаги, описанные ниже, теперь работали, теперь нужно обновить /etc/default/docker файл параметром '-e lxc' для параметра запуска демона докеров перед перезапуском демона (я сделал это, перезагрузив хост).

обновить файл / etc / default / docker

Это все потому что ...

... он [docker 0.9] содержит новую абстракцию «драйвер движка», чтобы сделать возможным использование API, отличного от LXC, для запуска контейнеров. Он также предоставляет новый драйвер движка на основе новой библиотеки API (libcontainer), которая может обрабатывать группы управления без использования инструментов LXC. Основная проблема заключается в том, что если вы полагаетесь на lxc-attach для выполнения действий с вашим контейнером, таких как запуск оболочки внутри контейнера, что безумно полезно для среды разработки ...

исходный код

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


Оказывается, решение другого вопроса также было решением этого вопроса:

... вы можете использовать docker ps -notrunc, чтобы получить полный идентификатор контейнера lxc, а затем использовать lxc-attach -n <container_id> run bash в этом контейнере от имени пользователя root.

Обновление. Скоро вам нужно будет использовать ps --no-trunc вместо ps -notrunc, который устарел.

введите описание изображения здесьНайдите полный идентификатор контейнера

введите описание изображения здесьВведите команду lxc attach.

введите описание изображения здесьВверху показан мой процесс apache, на котором запущен этот докер.

person Programster    schedule 05.01.2014
comment
Итак, с помощью Docker это невозможно сделать, не так ли? Я лично предпочитаю не смешивать LXC. - person qkrijger; 06.01.2014
comment
Есть ли способ запустить команду с lxc-attach вместо запуска bash? Спасибо!! - person joselo; 21.01.2014
comment
@qkrijger, насколько мне известно, это правильно. Зачем беспокоиться о смешивании LXC? Вы ведь понимаете, что докер построен на основе LXC? - person Programster; 21.01.2014
comment
@joselo Я не понимаю ваш вопрос, но я предлагаю вам создать новый пост с более подробной информацией? Есть много способов запустить процесс докера, например, с помощью bash или в качестве демона с -d и т. Д. - person Programster; 21.01.2014
comment
@programster да, я это понимаю :) Тем не менее, использование LXC напрямую в сочетании с Docker похоже на взлом. Удовольствие, но не совсем ремонтопригодное. В общем, код следует кодировать на уровне абстракции, на котором вы решили работать. Если вам действительно нужен сам LXC, возможно, пришло время для запроса на включение в Docker :) - person qkrijger; 22.01.2014
comment
@Programster Если я использую lxc-attach, он запускает новую консоль bash, но я хочу просто запустить команду напрямую, например lxc-attach -n xxxx - echo test - person joselo; 22.01.2014
comment
@joselo Я думаю, вы думаете о lxc-execute lxc.sourceforge.net/man/lxc- execute.html - person Programster; 22.01.2014
comment
Или вы можете оставить libcontainer и использовать nsinit :). go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit; cd /var/lib/docker/containers/<id>; nsinit exec <cmd> - person creack; 09.05.2014

А как насчет запуска tmux / GNU Screen внутри контейнера? Кажется, более простой способ получить доступ к любому количеству vty с помощью простого:

$ docker attach {container id}
person solr    schedule 10.07.2014
comment
Это нормальное решение, если вы знаете, что хотите получить доступ к контейнеру (например, для его отладки), но это не поможет OP, который заявляет, что они хотят осмотреть существующий контейнер. - person Luca Spiller; 01.08.2014
comment
Моя проблема с этим ответом заключается в том, что люди уже спрашивали об использовании docker attach, и я указал, что: ...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY" - person Programster; 06.08.2014
comment
Что ж, если контейнер уже работает, это решение вам не поможет, но если вы ранее позаботились о том, чтобы мультиплексор работал, вам не понадобятся дополнительные ttys ... Фактически, с тех пор, как я начал использовать tmux, я использую один tty и только один, чтобы делать все, что мне нужно, поскольку однажды в tmux я могу порождать столько vty, сколько захочу. - person solr; 07.08.2014

Первый шаг - получение идентификатора контейнера:

docker ps

Это покажет вам что-то вроде

КОНТЕЙНЕР ИДЕНТИФИКАЦИЯ ИЗОБРАЖЕНИЕ КОМАНДА СОЗДАНО СОСТОЯНИЕ НАЗВАНИЯ ПОРТОВ

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" 26 секунд назад вверх на 25 секунд 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 - это идентификатор контейнера в данном случае.

Во-вторых, войдите в докер:

docker exec -it [container_id] bash

поэтому в приведенном выше случае: docker exec -it 1170fe9e9460 bash

person patapouf_ai    schedule 24.01.2018

nsenter делает это. Однако мне также нужно было ввести контейнер простым способом, и nsenter не подходил для моих нужд. В некоторых случаях он был ошибочным (черный экран плюс флаг -wd не работал). Кроме того, я хотел войти в систему как конкретный пользователь и в определенном каталоге.

В итоге я создал свой собственный инструмент для входа в контейнеры. Вы можете найти его по адресу: https://github.com/Pithikos/docker-enter.

Его использование так же просто, как

./docker-enter [-u <user>] [-d <directory>] <container ID>
person Pithikos    schedule 30.07.2014
comment
Только что попробовал, очень круто! На ubuntu пришлось запустить sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter ‹short-container-id› Приятно, что мне не нужно получать полный идентификатор, как с lxc-attach -n Кодовая база достаточно короткая, чтобы можно было быстро сканировать все, чтобы найти что-нибудь вредоносное. - person Programster; 02.09.2014
comment
Я сделал ebuild доступным на gentoo по адресу github.com/steveeJ/personal-portage-overlay как приложение-эмуляция / докер-ввод. - person stefanjunker; 03.09.2014
comment
Я добавил учебник / сценарий для автоматического выполнения этого для пользователей ubuntu по адресу programster.blogspot.co.uk/2014/01/ - person Programster; 01.10.2014

docker exec -t -i container_name /bin/bash

Перенесет вас в консоль контейнеров.

person Danstan    schedule 20.11.2017
comment
Я остановился на этом вопросе, потому что у меня была такая же проблема. Ответ, который кажется похожим, не работал у меня, пока я не изменил его. Но я могу это удалить. - person Danstan; 26.06.2018

Способ "nsinit":

установить nsinit

git clone [email protected]:dotcloud/docker.git
cd docker
make shell

изнутри контейнера:

go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit

снаружи:

docker cp id_docker_container:/go/bin/nsinit /root/

используй это

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash
person Ivailo Bardarov    schedule 04.06.2014

Я запустил powershell на запущенном Microsoft / iis, запущенном как демон, используя

docker exec -it <nameOfContainer> powershell
person Ahmed Samir    schedule 17.10.2017
comment
Похоже, вопрос был о контейнере на базе linux. Этот ответ, вероятно, будет работать только в том случае, если у вас есть контейнер на основе Windows - или - если у вас установлена ​​версия PowerShell .NET Core, например PowerShell 6 или новее. - person Manfred; 03.11.2019

В Windows 10 у меня установлен докер. Я запускаю Jnekins в контейнере и обнаружил то же сообщение об ошибке. Вот пошаговое руководство по решению этой проблемы:

Шаг 1. Откройте gitbash и запустите docker run -p 8080: 8080 -p 50000: 50000 jenkins.

Шаг 2. Откройте новый терминал.

Шаг 3: Выполните docker ps, чтобы получить список запущенных контейнеров. Скопируйте идентификатор контейнера.

Шаг 4. Теперь, если вы выполните команду «docker exec -it {container id} sh» или «docker exec -it {container id} bash», вы получите сообщение об ошибке, подобное тому, что «устройство ввода не телетайп. Если вы используете mintty, попробуйте поставить перед командой префикс "winpty" "

Шаг 5: Выполните команду "$ winpty docker exec -it {container id} sh".

вола !! Теперь вы внутри терминала.

person Dev 00721    schedule 16.09.2019