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

545

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

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

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

Programster
источник
7
Ты пробовал docker attach [conainer-id]?
Шаббычеф
13
@shabbychef, если docker attach не изменился, команда присоединения присоединяется к запущенному tty, а не к новому, поэтому заголовок вопроса "... с новым TTY". Вот почему ответ ниже не использует команду присоединения.
Programster
1
Начиная с
версии

Ответы:

1061

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

docker exec -it [container-id] bash
Michael_Scharf
источник
30
Я изменил это, чтобы быть правильным ответом (от моего собственного), потому что этот новый метод, которого не было во время вопроса, является лучшим текущим методом IMO.
Programster
3
Однако обратите внимание, что execэто не действует как обычный терминал. Например, вы не можете изменить пользователя один раз внутри контейнера.
Питикос
3
@Pithikos: я могу использовать exec для запуска оболочки, а затем su someuserдля смены пользователя. Запуск Docker 1.4.1
LSH
2
Примечание для тех, кто читает это обсуждение. Я уверен, docker exec -itчто в конечном итоге предоставит полнофункциональный псевдотерминал, но на данный момент (Docker версия 1.9.1) есть некоторые недостатки: github.com/docker/docker/issues/8755
blong
18
если вы получаете сообщение об ошибке 'exec: "bash": исполняемый файл не найден в $ PATH ", вы можете попробовать это: docker exec -it [container-id] / bin / sh
Dai Kaixian
42

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

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

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

Hyperfocus
источник
Это правильный путь. Смотрите блог .
Джесси Глик
5
В докере 1.3 появилась новая команда docker exec. Это позволяет вам войти в работающий докер: docker exec -it <container-id> bash(см. Мой ответ ниже)
Michael_Scharf
5
Все docker-enterеще существует? Это дает мне command not found.
Snowcrash
22

Обновить

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

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

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

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

источник

Обратите внимание, что это предотвратит « работу» дополнительной функции новой сети для хоста в Docker 0.11, и вы увидите только петлевой интерфейс. отчет об ошибке


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

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

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

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

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

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

Programster
источник
Таким образом, нет способа сделать это только с помощью Docker, верно? Я лично предпочитаю не смешивать в LXC сам.
qkrijger
Есть ли способ запустить команду с lxc-attach вместо запуска bash? Спасибо!!
Хосело
@ qkrijger, насколько я знаю, это правильно. Почему беспокоятся о «смешении» LXC? Вы понимаете, что докер построен поверх LXC, верно?
Программист
@joselo Я не понимаю ваш вопрос, но я предлагаю вам создать новый пост с более подробной информацией? Есть много способов запустить процесс докера, например, с помощью bash или как демон с -d и т. Д.
Programster
@programster да, я это понимаю :) Тем не менее, использование LXC напрямую в сочетании с Docker похоже на хакерство. Забавно, но не совсем в обслуживании. В общем, нужно кодировать на уровне абстракции, на котором вы решили работать. Если вам действительно нужен сам LXC, возможно, пришло время для запроса на извлечение Docker :)
qkrijger
7

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

docker ps

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

КОНТЕЙНЕР ID ИМИДЖ КОМАНДА СОЗДАННЫЕ СТАТУС ИМЕНА ПОРТОВ

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

patapouf_ai
источник
5

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

$ docker attach {container id}
cig0
источник
Это нормальное решение, если вы знаете, что хотите получить доступ к контейнеру (например, для его отладки), но это не поможет OP, который заявляет, что хочет просмотреть существующий контейнер.
Лука Спиллер
1
Моя проблема с этим ответом состоит в том, что люди уже спрашивали об использовании, docker attachи я указал, что:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
Programster
Хорошо, если контейнер уже запущен, это решение вам не поможет, но если вы ранее позаботились о том, чтобы мультиплексор оставался включенным, вам не понадобятся дополнительные ttys ... Фактически, так как я начал использовать tmux, я использую один tty. и только один, чтобы делать все, что мне нужно, так как, попав в tmux, я могу создавать столько vtys, сколько захочу.
cig0
4

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

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

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

./docker-enter [-u <user>] [-d <directory>] <container ID>
Pithikos
источник
Только что попробовал, очень круто! В Ubuntu пришлось запустить sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> Хорошо, что мне не нужно получать полный идентификатор, как с lxc-attach -n Codebase достаточно короток, чтобы можно было быстро отсканировать все, чтобы найти что-нибудь вредоносное.
Programster
Я сделал ebuild доступным на gentoo по адресу github.com/steveeJ/personal-portage-overlay как app-emulation / docker-enter.
stefanjunker
Я добавил учебник / скрипт для автоматического это для Ubuntu пользователей в programster.blogspot.co.uk/2014/01/...
Programster
2

Способ "nsinit" это:

установить nsinit

git clone git@github.com: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
Ивайло Бардаров
источник
2
docker exec -t -i container_name /bin/bash

Отведу вас к консоли контейнеров.

Danstan
источник
Я попал на этот вопрос, потому что у меня была та же проблема. Ответ, который кажется похожим, не работал для меня, пока я не изменил. Я могу удалить это хотя.
Данстан
2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh
Флавио
источник
1

Я запустил PowerShell на работающем Microsoft / IIS запустить как демон, используя

docker exec -it <nameOfContainer> powershell
Ахмед Самир
источник
Похоже, что вопрос был о контейнере на основе Linux. Этот ответ, вероятно, будет работать только в том случае, если у вас есть контейнер на базе Windows, или если у вас установлена ​​версия PowerShell .NET Core, например PowerShell 6 или более поздняя версия.
Манфред
0

На 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», вы получите сообщение об ошибке, похожее на «устройство ввода не TTY. Если вы используя mintty, попробуйте добавить префикс команды к winpty

Шаг 5: Запустите команду " $ winpty docker exec -it {идентификатор контейнера} sh "

вола !! Вы сейчас внутри терминала.

Dev 00721
источник