Правильний спосіб від'єднання від контейнера, не зупиняючи його


313

У Docker 1.1.2 (остання версія), який правильний спосіб від'єднати від контейнера, не зупиняючи його?

Наприклад, якщо я спробую:

  • docker run -i -t foo /bin/bash або
  • docker attach foo (для вже запущеного контейнера)

обидва з них потрапляють до терміналу в контейнері, як я можу вийти з терміналу контейнера, не зупиняючи його?

exitі CTR+Cобидва зупиняють контейнер.


"Контейнер" - це лише набір обмежених просторів імен (простір імен процесів, простір імен файлової системи тощо), в яких можуть запускатися процеси. Якщо у вас немає процесу всередині простору імен, чи існує ця область імен насправді? Це не схоже на віртуальну машину, де є переривання годинника на відповідь ядра & c. незалежно.
Чарльз Даффі

Відповіді:


166

Оновлення: Як зазначено у відповідях нижче, відповіді Ctrl+ p, Ctrl+ qтепер перетворить інтерактивний режим у режим демон.


Ну Ctrl+ C(або Ctrl+ \) повинен відірвати вас від контейнера, але це вб'є контейнер, оскільки ваш основний процес - це бешкет.

Маленький урок про докера. Контейнер не є справжньою повнофункціональною ОС. Коли ви запускаєте контейнер, процес, який ви запускаєте, приймає PID 1 і беремо на себе init power. Отже, коли цей процес припиняється, демон зупиняє контейнер до запуску нового процесу (через запуск докера) (Більше пояснення з цього питання http://phusion.github.io/baseimage-docker/#intro )

Якщо ви хочете, щоб контейнер постійно працював у відокремленому режимі, я пропоную вам скористатися

docker run -d foo

З сервером ssh на контейнері. (найпростіший спосіб - дотримуватися підручника з докеризацією відкриття https://docs.docker.com/engine/examples/running_ssh_service/ )

Або ви можете просто перезапустити контейнер через

docker start foo

(вона буде відключена за замовчуванням)


3
+1 для базового зображення. Приємно знати, що є шаблон із порадами про важкі частини Докера.
mtmacdonald

Зауважте, що ssh не є суворо необхідним: blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker
Адріан Муат

1
Запуск міститься в режимі -d був дуже корисним. Також посилання на початок ssh через Dockerfile полегшило мені життя.
Раві

56
Від'єднайте за допомогою Ctrl-p, Ctrl-q. Поради цієї відповіді вб'ють контейнер.
таранакі

4
Це працювало для мене (взято з відповіді нижче): Почніть з -ti -d, потім додайте docker attach, потім від'єднайте спочатку ctrl + p, а потім ctrl + q. Я думав, я можу використовувати лише один із комбінацій клавіш.
CGFoX

526

Введіть Ctrl+, pа потім Ctrl+ q. Це допоможе вам перетворити інтерактивний режим в режим демон.

Дивіться https://docs.docker.com/v1.7/articles/basics/#running-an-interactive-shell .

# To detach the tty without exiting the shell,
# use the escape sequence Ctrl-p + Ctrl-q
# note: This will continue to exist in a stopped state once exited (see "docker ps -a")

4
Здається, це не спрацьовує (намагається вийти з доданого контейнера Wekan).
небезпека89

7
Я неодноразово відвідував цю сторінку, тому що не міг точно запам’ятати цю комбінацію клавіш! :-D
Thamme Gowda

10
@ небезпека89 ctrl-p, ctrl-q працюватиме лише тоді, коли ви запустили контейнер в інтерактивному режимі (-it). Якщо ви запустили його в режимі deamon (-d) і приєднали до нього, ви можете просто вийти з нього, і він все ще буде працювати у фоновому режимі.
Riscie

1
@SlimShady натисніть Ctrl + P, потім Ctrl + Q, щоб вийти, не один із них, але обидва в тому порядку.
Мохяддін Алаоддін

160

Я розібрався в цьому, і всі відповіді, наведені вище, частково вірні. Все залежить від способу запуску контейнера. Він зводиться до наступного, коли контейнер запускався:

  • було виділено TTY ( -t)
  • залишився відкритим ( -i)

^P^Q працює, але лише тоді, коли -tі -iвикористовується для запуску контейнера:

[berto@g6]$ docker run -ti -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518

[berto@g6]$ docker attach test
# here I typed ^P^Q
read escape sequence

# i'm back to my prompt
[berto@g6]$ docker kill test; docker rm -v test
test
test

ctrl+c працює, АЛЕ лише тоді, коли -t( без -i ) використовується для запуску контейнера:

[berto@g6]$ docker run -t -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
018a228c96d6bf2e73cccaefcf656b02753905b9a859f32e60bdf343bcbe834d

[berto@g6]$ docker attach test
^C

[berto@g6]$    

Третій спосіб від'єднання

Існує спосіб від'єднати, не вбиваючи контейнер; вам потрібна інша оболонка. Підсумовуючи це, запустивши це в іншій відокремленій оболонці та залишивши контейнер працює pkill -9 -f 'docker.*attach':

[berto@g6]$ docker run -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518

[berto@g6]$ docker attach test
# here I typed ^P^Q and doesn't work
^P
# ctrl+c doesn't work either
^C
# can't background either
^Z

# go to another shell and run the `pkill` command above

# i'm back to my prompt
[berto@g6]$

Чому? Тому що ви вбиваєте процес, який з'єднав вас із контейнером, а не сам контейнер.


2
Третій спосіб працює для мене. Дякую. якщо ви приєднуєтесь до декількох екземплярів і хочете лише відірватися від одного. Може вбити конкретний процес: ps -ef | grep attach -> отримати pid. Потім: убий -9 <pid>
phanhuy152

pkill - це єдине, що працювало для мене після вкладення
докера

Для чого нам потрібні -9. Я помітив, якщо ми не використовуємо -9, він закриває контейнер.
Анжело

Інші сигнали - це, сигнали. Вони повідомляють процесу, який тип сигналу, і дають йому можливість діяти і щось робити. kill -9Сигнал не робить. Процес припиняється і не застосовується. Я здогадуюсь, що інші сигнали дають контейнерові можливість вимкнутись, тоді як -9ні.
Берто

1
Це було дуже корисно. Дякую!
Еван Замір

40

Якщо ви "docker attach" id id контейнера, ви потрапляєте в контейнер. Щоб вийти з контейнера, не зупиняючи контейнер, вам потрібно ввести Ctrl+ P+Q


6
краще до Ctrl + P і Ctrl + Q
sib10

4
Ctrl + P, Q (досі тримає Ctrl);)
dimpiax

це повертає мене:Error response from daemon: Container f560a0ad6806150b2775d0b6e6d5f7065a03775bae858fb4fb7df05a277976db is not running
Веб-жінка

31

Я вважаю відповідь Ешвіна найправильнішою, моя стара відповідь нижче.


Я хотів би додати тут ще один варіант, який полягає у запуску контейнера наступним чином

docker run -dti foo bash

Потім ви можете ввести контейнер і запустити bash

docker exec -ti ID_of_foo bash

Не потрібно встановлювати sshd :)


Я думаю, що у другій команді вам потрібно замінити foo на ідентифікатор контейнера foo
Nehal J Wani

У цьому контексті, я думаю, docker attachбуло б більш стандартним шляхом повторного приєднання до першого запуску bash. docker execтакож працює тут, однак він створює новий процес bash на додаток до першого. Звичайно, процес створюється в одному контексті / середовищі / контейнері першого, однак це інший (аналогія - це відкрити нову вкладку терміналу у вашому улюбленому емуляторі терміналу).
thiagowfx

20

Типовим способом від'єднання від інтерактивного контейнера є Ctrl+ P Ctrl+ Q, але ви можете його замінити під час запуску нового контейнера або приєднання до існуючого контейнера, використовуючи прапор --detach-keys .


16

Якщо ви приєдналися через docker attach, ви можете від'єднатись, вбивши процес прикріплення докер. Кращий спосіб - використовувати параметр sig-proxy, щоб уникнути передачі Ctrl + C у ваш контейнер:

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

Той самий варіант доступний для docker runкоманди.


6
Хоча --sig-proxy = false є надзвичайно корисним, він не працює для вже доданих контейнерів, для яких він не був вказаний. Проблема полягає в тому, що після приєднання, здається, немає способу від'єднання, не вбиваючи процес, включаючи "вбивство процесу приєднання докер". Cp, Cq не працює з доданими контейнерами, а лише інтерактивними (наприклад, питання використовується).
таранакі

1
Це має бути прийнята відповідь, включаючи коментар @taranaki, Ctrl + P, Q не працює дляphp:7.3-apache
MKaama

10

Якщо ви просто хочете побачити результат процесу, який працює з контейнера, ви можете зробити просте docker container logs -f <container id>.

-fПрапор робить це так , що вихід з контейнера followedі оновлюється в режимі реального часу. Дуже корисно для налагодження чи моніторингу.


8

Ви можете використовувати цю --detach-keysопцію під час запуску, docker attachщоб замінити послідовність CTRL+ P, CTRL+ за замовчуванням Q(що не завжди працює).

Наприклад, коли ви запустите docker attach --detach-keys="ctrl-a" testі натиснете CTRL+, Aви вийдете з контейнера, не вбиваючи його.

Інші приклади:

  • docker attach --detach-keys="ctrl-a,x" test- натисніть, CTRL+Aа потім Xвийти
  • docker attach --detach-keys="a,b,c" test- натисніть A, потім B, Cщоб вийти

Витяг з офіційної документації:

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

Щоб замінити послідовність для окремого контейнера, використовуйте --detach-keys="<sequence>"прапор із командою приєднати докер. Формат <sequence>листа є або буквою [a-Z], або ctrl-комбінованим із будь-яким із наведених нижче:

  • az (один алфавіт з малих літер)
  • @ (на знак)
  • [(ліва дужка)
  • \ (дві відстані назад)
  • _ (підкреслення)
  • ^ (карета)

Ці a, ctrl-a, Xабо ctrl-\\значення є прикладами дійсних послідовностей ключовими. Щоб налаштувати іншу послідовність клавіш конфігурації для всіх контейнерів, див розділ Конфігураційний файл.

Примітка. Це працює з версії докера 1.10+ (на момент отримання відповіді, поточна версія - 18.03)


0

Стара публікація, але просто вийдіть, а потім запустіть її знову ... проблема в тому, якщо ви знаходитесь на машині Windows, Ctrl p або Ctrl P прив'язані до друку ... Вихід із стартового контейнера нічого не зашкодить

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