Что значит присоединить tty/std-in-out к докерам или lxc?
Я прочитал некоторые документы докеров, и я не понимаю, что это может означать для
- присоединить tty
- attach std-in и std-out
для этих целей я вижу, что используются флаги -i
и -t
.
Что означает этот процесс?
Ответы
Ответ 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.