将tty / std-in-out附加到docker或lxc是什么意思?

我读了一些docker文件,我不明白这可能是什么意思

  • 附上一个tty
  • 附加std-in和std-out

为了这些目的,我看到-i-t标志是使用的。

这个过程是什么意思?

stdin, stdout, and ttys是相关的概念。 stdinstdout是一个进程的input和输出stream。 伪terminal (也称为ttypts )通常(但不一定)通过诸如bash的shell将用户的“terminal”与stdinstdoutstream连接起来。 我在“terminal”周围使用引号,因为我们今天真的不使用terminal。

在Docker的情况下,当您以交互模式运行进程时,例如启动bash shell时,经常会同时使用-t-i 。 在shell中,您希望能够发出命令并读取输出。

使用-t-i (Docker version 0.8.1)进行实验的一些示例:

 $ docker run -i ubuntu:12.04 echo hello # Attach stdin and stdout but no tty hello $ docker run -t ubuntu:12.04 echo hello # Try to attach a tty without stdin/stdout hello $ docker run -i -t ubuntu:12.04 echo hello # This process starts and exits with a tty, stdin and stdout attached hello 

代码泊坞窗用来附加stdout/stdin具有所有的脏细节。

通过使用lsof命令我们可以看到底下发生了什么。 对于演示,我们可以从运行睡眠的Debian镜像创build一个简单的docker容器:

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

这将在新容器中启动睡眠命令(请注意,我们没有使用-i-t )。

接下来,我们通过exec命令“login”到我们的容器中,并启动一个bash:

 docker exec -it tty-test /bin/bash 

一个普通的debian映像将不会安装lsof所以我们需要安装它:

 apt update && apt install -y lsof 

接下来我们运行lsof:

 lsof 

如果没有任何选项运行, lsof将打印所有正在运行的进程的打开文件。 你应该在其输出中看到三个进程(sleep,bash和lsof本身)。

这里是相关的行是那些显示文件描述符(FD列) 02

请注意,我们在没有-t选项的情况下启动的sleep过程如何为stdinstdoutstderr提供三个FIFOpipe道:

 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过程有一个实际的设备连接到stdinstdoutstderr

 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选项创build另一个容器:

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

再次安装lsof (见上面)后,我们从sleep过程的lsof获得了不同的输出:

 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 

请注意types列已更改为CHR ,名称列显示/15

最后,当我们从exec命令中忽略-t选项,并像这样:

 docker exec -it tty-test /bin/bash 

那么我们可以注意到两件事情。 首先,我们现在没有从bash获得shell提示,但是我们仍然可以键入命令并查看它们的输出。 当我们运行lsof我们看到bash进程现在也有pipe道,而不是tty连接到stdinstdoutstderr

 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(即terminal)login到您的容器。 就好像你有一台Linux机器在你面前,你正在login它。 如果你有一个没有运行SSH服务器或telnet的容器​​,这是进入命令行提示符的唯一模式。

至于为什么-i-t是我不确定的不同的参数,我无法想象你想要使用TTY连接的场景,而不想使用stdin / stdout选项,反之亦然。