Як увійти в контейнер Docker, який вже працює з новим TTY


545

У мене на передньому плані є контейнер, на якому працює служба Apache. Я хотів би мати можливість отримати доступ до контейнера з іншої оболонки, щоб "обколоти" всередині нього і вивчити файли. На даний момент, якщо я приєднаюся до контейнера, я переглядаю демон Apache і не можу виконувати жодних команд.

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

Я б краще не конфігурував і не створював контейнер із службою opensh, якщо можливо.


7
Ви пробували docker attach [conainer-id]?
shabbychef

13
@shabbychef, якщо докерне вкладення не змінилося, команда attach приєднується до запущеного tty, а не до нового, отже, назва питання "... з новим TTY". Ось чому відповідь нижче не використовує команду attach.
Programster

1
З 1.3 є простіший спосіб, як описано у цій відповіді
Thomasleveil

Відповіді:


1061

З докер 1.3 є нова команда docker exec. Це дозволяє ввести запущений докер:

docker exec -it [container-id] bash

30
Я змінив це на правильну відповідь (з моєї власної), оскільки цей новий метод, якого не було на момент запитання, є найкращим сучасним методом ІМО.
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 [контейнер-ідентифікатор] / bin / sh
Dai Kaixian

42

Ви повинні використовувати інструмент Jérôme Petazzoni під назвою "nsenter" для введення контейнера без використання SSH. Дивіться: https://github.com/jpetazzo/nsenter

Встановіть просто: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Потім за допомогою команди docker-enter <container-id>введіть контейнер.


Це правильний шлях. Дивіться блог .
Джессі Глік

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, щоб виконувати дії над вашим контейнером, як, наприклад, запустити оболонку всередині контейнера, що шалено корисно для середовища розробки ...

джерело

Зауважте, що це не дозволить новій додатковій функції докера 0.11 функціонувати лише для хостів, щоб вона не працювала, і ви побачите лише інтерфейс зворотного зв'язку. повідомлення про помилку


Виявляється, що вирішення іншого питання також було вирішенням цього:

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

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

введіть тут опис зображення Знайдіть повний ідентифікатор контейнера

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

введіть тут опис зображення Вгорі відображається мій процес apache із запуском цього докера.


Отже, немає ніякого способу зробити це просто з Докером, правда? Я особисто вважаю за краще не змішувати себе в LXC.
qkrijger

Чи є спосіб запустити команду з lxc-attach замість цього, щоб запустити bash? Дякую!!
joselo

@qkrijger, наскільки я знаю, що це правильно. Чому турбуєтесь про "змішування" LXC? Ви розумієте, що докер побудований на вершині LXC?
Programster

@joselo Я не розумію вашого питання, але я пропоную вам створити нову публікацію з більш детальною інформацією? Є багато способів , щоб почати процес докер, наприклад, з Баш або як демон з -d і т.д.
Programster

@programster так, я розумію, що :) Все-таки використання LXC безпосередньо в поєднанні з Docker відчуває себе як хакерство. Весело, але насправді не піддається ремонту. Взагалі, слід ввести код у шарі абстракції, над яким вирішили працювати. Якщо вам дійсно потрібен сам LXC, можливо, настав час для запиту на
виклик

7

Перший крок - отримати ідентифікатор контейнера:

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


5

Що щодо запуску екрана tmux / GNU в контейнері? Здається, більш простий спосіб отримати доступ до стільки, скільки вам потрібно, за допомогою простого:

$ docker attach {container id}

Це нормальне рішення, якщо ви знаєте, що ви хочете отримати доступ до контейнера (наприклад, налагодити його), але це не допоможе ОП, який заявляє, що вони хочуть оглянути існуючий контейнер.
Лука Спіллер

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>

Просто спробував, дуже круто! У ubuntu довелося запускати sudo apt-get build-basic - gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> Приємно, що я не повинен отримувати повний ідентифікатор, як у lxc-attach -n Codebase є досить коротким, що можна швидко сканувати цілісність, щоб знайти щось шкідливе.
Programster

Я зробив доступну електронну збірку на gentoo на сайті github.com/steveeJ/personal-portage-overlay як емуляція програми / докер-введення.
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

Відведе вас до консолі контейнерів.


Я приземлився на це питання, тому що в мене була така ж проблема. Відповідь, яка здається подібною, не працювала для мене, поки я не змінив. Я можу видалити це.
Данстан


1

Я запустив powerhell на запущеному мікрософт / iis, який працює як демон

docker exec -it <nameOfContainer> powershell

Схоже, питання стосується контейнера на базі linux. Ця відповідь, ймовірно, спрацює лише у тому випадку, якщо у вас є контейнер на базі Windows-або- якщо у вас встановлена ​​версія .NET Core PowerShell, наприклад PowerShell 6 або новішої версії.
Манфред

0

У Windows 10 у мене встановлений докер. Я запускаю Jnekins на контейнер, і я зіткнувся з тим же повідомленням про помилку. Ось покрокове керівництво для вирішення цієї проблеми:

Крок 1: Відкрийте gitbash та запустіть докер-біг -p 8080: 8080 -p 50000: 50000 джинкінів.

Крок 2: Відкрийте новий термінал.

Крок 3: Зробіть "docker ps", щоб отримати список запущеного контейнера. Скопіюйте ідентифікатор контейнера

Крок 4: Тепер, якщо ви зробите "docker exec -it {container id} sh" або "docker exec -it {container id} bash", ви отримаєте повідомлення про помилку, подібне до "пристрій введення не TTY. Якщо ви використовуючи м'ятний, спробуйте префікс команди "winpty" "

Крок 5: Виконайте команду " $ winpty docker exec -it {контейнер ідентифікатор} sh "

вола !! Ви зараз всередині терміналу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.