Я прочитал некоторые документы докеров, и я не понимаю, что это может означать для
- присоединить tty
- attach std-in и std-out
для этих целей я вижу, что используются флаги -i
и -t
.
Что означает этот процесс?
Я прочитал некоторые документы докеров, и я не понимаю, что это может означать для
для этих целей я вижу, что используются флаги -i
и -t
.
Что означает этот процесс?
stdin, stdout, and ttys
- связанные понятия. stdin
и stdout
являются входными и выходными потоками процесса. Псевдотерминал (также известный как tty
или pts
) соединяет пользовательский "терминал" с потоком stdin
и stdout
, обычно (но не обязательно) через оболочку, такую как bash
. Я использую кавычки вокруг "терминала", так как сегодня мы действительно не используем терминал в том же смысле.
В случае с докером вы часто будете использовать -t
и -i
вместе, когда будете запускать процессы в интерактивном режиме, например, при запуске оболочки bash
. В случае с оболочкой вы хотите иметь возможность выдавать команды и читать вывод.
Докер кода, используемый для прикрепления stdout/stdin
содержит все грязные детали.
Мы можем видеть, что происходит под капотом, используя команду 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
Это означает, что вы можете войти в свой контейнер, используя TTY, т.е. терминал. Как будто у вас есть машина Linux перед вами, и вы заходите в нее. Если у вас есть контейнер, в котором не работает SSH-сервер или telnet, это единственный способ войти в приглашение командной строки.
Что касается того, почему -i
и -t
- разные аргументы, я не уверен, я не могу представить сценарий, в котором вы хотите подключиться с помощью TTY, и не хотите, чтобы параметр stdin/stdout или наоборот.
Проще говоря, это позволяет нам прикрепить и отсоединить контейнер от терминала. Чтобы присоединить, мы используем команду присоединения docker, а для ветки мы используем команду CTRL + P & CTRL + Q.