difference between docker attach and docker exec

2019-01-13 05:38发布

问题:

Both will be able to execute commands in container. Both could detach the container.

So what is the real difference between docker exec and docker attach?

回答1:

There was a commit PR which added to the doc:

Note: This command (attach) is not for running a new process in a container. See: docker exec.

The answer to "Docker. How to get bash\ssh inside runned container (run -d)?" illustrates the difference:

(docker >= 1.3) If we use docker attach, we can use only one instance of shell.
So if we want open new terminal with new instance of container's shell, we just need run docker exec

if the docker container was started using /bin/bash command, you can access it using attach, if not then you need to execute the command to create a bash instance inside the container using exec.

As mentioned in this issue:

  • Attach isn't for running an extra thing in a container, it's for attaching to the running process.
  • "docker exec" is specifically for running new things in a already started container, be it a shell or some other process.

The same issue adds:

While attach is not well named, particularly because of the LXC command lxc-attach (which is more akin docker exec <container> /bin/sh, but LXC specific), it does have a specific purpose of literally attaching you to the process Docker started.
Depending on what the process is the behavior may be different, for instance attaching to /bin/bash will give you a shell, but attaching to redis-server will be like you'd just started redis directly without daemonizing.



回答2:

When a container is started using /bin/bash then it becomes the containers PID 1 and docker attach is used to get inside PID 1 of a container. So docker attach < container-id > will take you inside the bash terminal as it's PID 1 as we mentioned while starting the container. Exiting out from the container will stop the container.

Whereas in docker exec command you can specify which shell you want to enter into. It will not take you to PID 1 of the container. It will create a new process for bash. docker exec -it < container-id > bash. Exiting out from the container will not stop the container.

You can also use nsenter to enter inside containers. nsenter -m -u -n -p -i -t < pid of container > You can find PID of container using: docker inspect < container-id > | grep PID

Note: If you have started your container with -d flag then exiting out of container will not stop the container,whether you use attach or exec to get inside.



回答3:

Docker exec executes a new command / create a new process in the container’s environment, while docker attach just connects the standard input/output/error of the main process(with PID 1) inside the container to corresponding standard input/output/error of current terminal(the terminal you are using to run the command).

A container is an isolated environment, with some processes running in the environment. Specifically, a container has its own file system space and PID space that are isolated from host and other containers. When the container is started using “docker run –it …”, the main process will have a pseudo-tty and STDIN kept open. When attached in the tty mode, you can detach from the container (and leave it running) using a configurable key sequence. The default sequence is CTRL-p CTRL-q. You configure the key sequence using the --detach-keys option or a configuration file. You can reattach to a detached container with docker attach.

Docker exec just starts a new process, inside the container’s environment, that is, belongs to the PID space of the container.

For example, if you start your container using “docker run –dit XXX /bin/bash”,you can attach to the container(‘s main process) using two different terminals. While you are inputting in one terminal, you can see it appears in the other terminal, for both terminal are connected to same tty. Be careful that you are now in the main process of the container, if you type “exit”, you will exit the container(so be careful, using detach-keys to detach), and you will see both terminals exited. But if you run “docker exec –it XXX /bin/bash” in two terminals, you have started two new processes inside the container, and they are not related to each other and to the main process, and you can safely exit from them.