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

Что значит присоединить tty/std-in-out к докерам или lxc?

Я прочитал некоторые документы докеров, и я не понимаю, что это может означать для

  • присоединить tty
  • attach std-in и std-out

для этих целей я вижу, что используются флаги -i и -t.

Что означает этот процесс?

4b9b3361

Ответ 1

stdin, stdout, and ttys - связанные понятия. stdin и stdout являются входными и выходными потоками процесса. Псевдотерминал (также известный как tty или pts) соединяет пользовательский "терминал" с потоком stdin и stdout, обычно (но не обязательно) через оболочку, такую как bash. Я использую кавычки вокруг "терминала", так как сегодня мы действительно не используем терминал в том же смысле.

В случае с докером вы часто будете использовать -t и -i вместе, когда будете запускать процессы в интерактивном режиме, например, при запуске оболочки bash. В случае с оболочкой вы хотите иметь возможность выдавать команды и читать вывод.

Докер кода, используемый для прикрепления stdout/stdin содержит все грязные детали.

Ответ 2

Мы можем видеть, что происходит под капотом, используя команду lsof. Для демонстрации мы можем создать простой контейнер докеров из образа Debian, который просто запускает сон:

docker run -d --name tty-test debian /bin/bash -c "sleep 1000"

Это запустит команду sleep в новом контейнере (обратите внимание, что мы не использовали -i или -t).

Далее мы "входим" в наш контейнер, хотя команда exec и запустим bash:

docker exec -it tty-test /bin/bash

У простого изображения debian не будет установлен lsof, поэтому нам нужно его установить:

apt update && apt install -y lsof

Затем мы запустим lsof:

lsof

Если вы запускаете без каких-либо параметров, lsof будет печатать открытые файлы для всех запущенных процессов. Вы должны увидеть три процесса в своем выходе (sleep, bash и lsof).

Вот соответствующие строки - это те, которые показывают дескрипторы файла (столбец FD) 0 до 2.

Обратите внимание, как процесс sleep, который мы начали без опции -t, имеет три канала FIFO для stdin, stdout и stderr:

sleep     1 root    0r  FIFO   0,10      0t0 8226490 pipe
sleep     1 root    1w  FIFO   0,10      0t0 8226491 pipe
sleep     1 root    2w  FIFO   0,10      0t0 8226492 pipe

В то время как процесс bash имеет фактическое устройство, подключенное к stdin, stdout и stderr:

bash      7 root    0u   CHR 136,15      0t0      18 /dev/pts/15
bash      7 root    1u   CHR 136,15      0t0      18 /dev/pts/15
bash      7 root    2u   CHR 136,15      0t0      18 /dev/pts/15

Позволяет создать другой контейнер с опцией -t:

docker run -d -t --name tty-test2 debian /bin/bash -c "sleep 1000"

После установки lsof снова (см. выше) мы получим отличный результат от lsof для процесса sleep:

sleep     1 root    0u   CHR 136,15      0t0      18 /15
sleep     1 root    1u   CHR 136,15      0t0      18 /15
sleep     1 root    2u   CHR 136,15      0t0      18 /15

Обратите внимание, что столбец типа изменился на CHR, а в столбце name отображается /15.

Наконец, когда мы опускаем опцию -t из команды exec и вот так:

docker exec -it tty-test /bin/bash

то мы можем заметить две вещи. Во-первых, мы не получаем приглашение оболочки из bash, но мы все еще можем вводить команды и видеть их вывод. Когда мы запускаем lsof, мы видим, что процесс bash теперь также имеет каналы, а не tty, привязанные к stdin, stdout и stderr

bash    379 root    0r  FIFO   0,10      0t0 8263037 pipe
bash    379 root    1w  FIFO   0,10      0t0 8263038 pipe
bash    379 root    2w  FIFO   0,10      0t0 8263039 pipe

Ответ 3

Это означает, что вы можете войти в свой контейнер, используя TTY, т.е. терминал. Как будто у вас есть машина Linux перед вами, и вы заходите в нее. Если у вас есть контейнер, в котором не работает SSH-сервер или telnet, это единственный способ войти в приглашение командной строки.

Что касается того, почему -i и -t - разные аргументы, я не уверен, я не могу представить сценарий, в котором вы хотите подключиться с помощью TTY, и не хотите, чтобы параметр stdin/stdout или наоборот.

Ответ 4

Проще говоря, это позволяет нам прикрепить и отсоединить контейнер от терминала. Чтобы присоединить, мы используем команду присоединения docker, а для ветки мы используем команду CTRL + P & CTRL + Q.