PseudoTerminal(PTY): Behind “attach” and “exec” command for Docker and Kubernetes

sonu kushwaha
5 min readSep 5, 2021

when some normal program is started by the user ie in the console then all the standard input, standard output and standard error (a.k.a stdin,stdout,stderr respectively) streams get attached to the controlling terminal for that particular session .Apart from that, the controlling terminal is also responsible for signal handling. So in a nutshell everything passed by the user on the console goes to the standard input stream and output for the same is reflected back / echoed back on the console .

FACT:-once the ctrl+c is pressed it actually goes to the background rather than forground , and breaks out the input bytes section and instead of that it sends SIGINT(default action is to terminate the process here pesudoterminal PTY)

Daemon process are the process running in the back ground and can never be attached to the controlling terminal, hence what if user want to create the daemon process so let me some example how docker does it/impliments it .

Even though we started a container completely detached from the console, we managed to connect to it later and even delivered a SIGINT by pressing Ctrl-C. Under the hood of this trick lies

source

A pseudoterminal (sometimes abbreviated “pty”) is a pair of virtual character devices that provide a bidirectional communication channel. One end of the channel is called the master; the other end is called the slave. The slave end of the pseudoterminal provides an interface that behaves exactly like a classical terminal. A process that expects to be connected to a terminal, can open the slave end of a pseudoterminal and then be driven by a program that has opened the master end. Anything that is written on the master end is provided to the process on the slave end as though it was input typed on a terminal. For example, writing the interrupt character (usually control-C) to the master device would cause an interrupt signal (SIGINT) to be generated for the foreground process group that is connected to the slave. Conversely, anything that is written to the slave end of the pseudoterminal can be read by the process that is connected to the master end. source

When docker launches bash process in the example above, it allocates a PseudoTerminal pair and sets the slave end as a controlling terminal for bash. When a user attach-es to the running container, docker just binds his stdin & stdout to the master .

Difference between “attach” and “exec”

Talking about the diffrence , there is no as such difference wrt implementation perspective of exec and attach command ,but when it comes to the pseudo terminal and stdin/out part then there lies the difference as the command themselves are different .

Attach Command

suppose we have the container running in d-foreground,so we create our container (ie an isolated box with the help of the cgroups and namespaces) and one want to connect/reconnect to the containers main process(as discussed in this that docker itslef is a kind of restricted process). But then you figure out that you need to have the access to the i/o , and docker achives it with docker attach <container name>. In a nutshell attach command simply reconnects to the container main process

below is the proof that the command docker attach reconnects to the docker container main process, so what i have done is created a container in detached mode (backgroung ie with out connecting it to the controlling terminal )and then tried to attach the container, so after connection is established then i have tried to exit from the PTY of the container but remember the pseudoTerminal is running with attach command so once we exit , the container will exit as well.

$ docker run -dit — name sonu centos
Unable to find image ‘centos:latest’ locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c
Status: Downloaded newer image for centos:latest
a02ae6e50512b18ab6e5fa6de3621e1fb5c7cc4291a021ada6d68cde85a99870
$
$
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a02ae6e50512 centos “/bin/bash” 7 seconds ago Up 6 seconds sonu
$
$
$ docker attach sonu
[root@a02ae6e50512 /]#
[root@a02ae6e50512 /]# exit
exit
$
$
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Exec Command

this command helps to provide the access to the i/o to pseudoterminal, but in a different fashion ie docker exec command runs or create totally new process inside the existing container to achieve i/o permission

proof that the exec command creates the new process of pseudo terminal ie PTY inside the container (box) and once we exit out of PTY then we exit of PTY only as completely new process was/is running for PTY

$ docker run -dit — name sonu centos
Unable to find image ‘centos:latest’ locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
6a07a68e799b8fbd6a871803a8cfb517e040c991d70974d296ce4dfddc309676
$
$
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a07a68e799b centos “/bin/bash” 5 seconds ago Up 4 seconds sonu
$
$
$ docker exec -it sonu bash
[root@6a07a68e799b /]# exit
exit
$
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a07a68e799b centos “/bin/bash” 29 seconds ago Up 29 seconds sonu
$

conclusion of difference

docker run -dit is equivalent to (docker create +docker start)

docke run -it is equivalent to (docker create+ docker start +docker attach)

--

--