Как работают docker флаги stdin и tty под крышками в контейнерах? - PullRequest
3 голосов
/ 29 января 2020

Я часто использую эти параметры командной строки, -i и -t при работе с контейнерами, с которыми я хочу взаимодействовать.

  -i, --stdin=false: Pass stdin to the container
  -t, --tty=false: Stdin is a TTY

Как они работают для создания контейнеров интерактивными?

1 Ответ

2 голосов
/ 29 января 2020

Когда вы используете опцию -i, клиент (т. Е. Команда docker) присоединяется к стандартному вводу команды внутри контейнера. Если вы используете опцию -t, вы также присоединяете терминал к команде. Некоторые программы ведут себя по-разному при подключении к терминалу.


bash-3.2$ docker run -i ubuntu cat
Hey    <-- input from my stdin
Hey    --> output from cat
Hello  <-- input from my stdin
Hello  --> output from cat

cat Стандарт команды подключен к docker run Стандарт команды.


bash-3.2$ echo Hey | docker run -i ubuntu cat
Hey    --> output from cat

Здесь стандартный ввод команды cat подключен к стандартному вводу docker run, который подключен к стандартному выводу echo. docker run выходит, как только stdin отключен.


bash-3.2$ docker run -it ubuntu cat
Hey    <-- input from my stdin
Hey    --> output from cat

Stdin cat подключен к tty-входу. Этот tty подключен к стандартному вводу docker run. stdin из docker run также должен быть tty.

Не уверен, что cat ведет себя иначе, если это stdin tty, но многие другие программы делают. Пример: Некоторые команды могут скрывать ввод при получении пароля от tty.


bash-3.2$ echo Hey | docker run -it ubuntu cat
the input device is not a TTY

docker run Стандартом команды не является tty. Поэтому он не может быть подключен к tty, подключенному к cat стандартному значению команды.


bash-3.2$ docker run -t ubuntu cat
Hey    <-- input from my stdin. no output from cat

cat Стандартный командный элемент подключен к tty и все. Команда docker run stdin НЕ подключена к cat, поскольку опция -i не используется. Таким образом, даже если вы введете что-либо в свой стандартный ввод, оно не достигнет cat.


bash-3.2$ echo Hey | docker run -t ubuntu cat

cat Стандар команды подключен к tty и все. Выход echo не достигнет cat.


Как это работает для создания интерактивных контейнеров?

Клиент делает вызов API в /containers/{id}/attach в docker демон. Это HTTP-соединение затем захватывается для передачи stdin, stdout и stderr (в зависимости от параметров) через базовый сокет. Клиент и сервер используют этот сокет для двунаправленной потоковой передачи.

В зависимости от того, включен ли tty, формат потока может отличаться. Начиная с container_attach. go:

// If the container is using a TTY, there is only a single stream (stdout), and
// data is copied directly from the container output stream, no extra
// multiplexing or headers.
//
// If the container is *not* using a TTY, streams for stdout and stderr are
// multiplexed.
// The format of the multiplexed stream is as follows:
//
//    [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
//
// STREAM_TYPE can be 1 for stdout and 2 for stderr
//
// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
// This is the size of OUTPUT.

На стороне клиента данные из потока копируются в его стандартный вывод и это стандартный копируется на поток .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...