【问题标题】:How does docker stdin and tty flags work under the covers in containers?docker stdin 和 tty 标志如何在容器的幕后工作?
【发布时间】:2020-01-29 14:06:06
【问题描述】:

在处理我想与之交互的容器时,我经常使用这些命令行选项-i-t

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

这些如何使容器具有交互性?

【问题讨论】:

  • 我通常通过对容器进行网络调用来与容器交互,所以我不需要这些选项。您在寻找什么样的答案;指向 Docker 源代码的指针?
  • 一个指向一个好的教程,一个高级准确的解释。如果它补充了高级解释,指向 docker 源代码的指针也应该没问题。
  • 这能回答你的问题吗? what is docker run -it flag?

标签: docker containers stdin tty


【解决方案1】:

当您使用-i 选项时,客户端(即docker 命令)会将自己附加到容器内命令的标准输入。如果您使用-t 选项,您也是attaching a terminal 的命令。当连接到终端时,某些程序的行为会有所不同。


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 在标准输入断开后立即退出。


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

cat 的标准输入连接到 tty 输入。此 tty 连接到 docker run 的标准输入。 docker run 的标准输入也必须是 tty。

不确定如果 cat 的 stdin 是 tty,它的行为是否会有所不同,但许多其他程序会这样做。示例:Some commands might hide the input when taking password input from a tty.


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

docker run 命令的标准输入不是 tty。所以它不能连接到连接到cat命令的stdin的tty。


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

cat 命令的标准输入连接到 tty 就是这样。 docker run 命令的标准输入未连接到 cat,因为未使用 -i 选项。因此,即使您在标准输入中输入任何内容,它也不会到达 cat


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

cat 命令的标准输入连接到 tty 就是这样。 echo 的输出不会达到 cat


这些如何使容器具有交互性?

客户端在/containers/{id}/attach 处向 docker 守护进程生成一个API call。然后这个 HTTP 连接是 hijacked 以通过底层套接字传输 stdinstdoutstderr(取决于选项)。客户端和服务器使用此套接字进行双向流式传输。

根据是否启用 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.

在客户端,来自流的数据是copied onto it's stdoutit's stdin is copied onto the stream

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2022-07-07
    • 2022-09-28
    相关资源
    最近更新 更多