如何在后台模式下将 bash 或 ssh 放入正在运行的容器中?

Tim*_*nov 969 ssh bash container docker

我想通过 ssh 或 bash 进入正在运行的 docker 容器。请看例子:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 
Run Code Online (Sandbox Code Playgroud)

现在我想得到这样的东西(进入正在运行的容器):

$ sudo docker run -t -i webserver(或者也许665b4a1e17b6相反)
$ root@665b4a1e17b6:/#

但是,当我运行上面的行时,我得到了新的 CONTAINER ID:

$ root@42f1e37bd0e5:/#
Run Code Online (Sandbox Code Playgroud)

我使用了 Vagrant,我想获得与vagrant ssh.

Tim*_*nov 1345

答案是Docker的attach命令。所以对于我上面的例子,解决方案是:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ sudo docker attach loving_heisenberg #by Name
$ root@665b4a1e17b6:/#
Run Code Online (Sandbox Code Playgroud)

对于 Docker 1.3 或更高版本:感谢用户WiR3D,他提出了另一种获取容器外壳的方法。如果我们使用,attach我们只能使用一个 shell 实例。因此,如果我们想使用容器外壳的新实例打开一个新终端,我们只需要运行以下命令:

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID
Run Code Online (Sandbox Code Playgroud)

或者

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Run Code Online (Sandbox Code Playgroud)

  • attach 命令对我不起作用,它会导致 docker 冻结.. 知道为什么会发生这种情况吗? (57认同)
  • 这是一个危险的答案,被选中并获得如此高的票数。例如,`docker attach` 到一个 MongoDB 实例会杀死该实例。正如 [this question](http://stackoverflow.com/questions/30172605/how-to-get-into-a-docker-container) 中更详细的解释,`attach` 和 `exec` 是不同的动物。 (50认同)
  • ```-i -t``` 等于 ```-it``` (18认同)
  • 给 boot2docker 用户的提醒:删除 sudo :) (10认同)
  • 或者,执行`sudo docker attach love_heisenberg` (5认同)

WiR*_*R3D 706

从 Docker 1.3 开始:

docker exec -it <containerIdOrName> bash
Run Code Online (Sandbox Code Playgroud)

基本上,如果 Docker 容器是使用/bin/bash命令启动的,您可以使用attach. 如果没有,那么您需要执行命令以使用exec.

还要退出 Bash 而不让 Bash 在流氓进程中运行:

exit
Run Code Online (Sandbox Code Playgroud)

是的,就是这么简单。

  • 使用 docker group 是不好的做法。docker 组中的任何用户本质上都具有 root 权限,无需使用 sudo。http://www.projectatomic.io/blog/2015/08/why-we-dont-let-non-root-users-run-docker-in-centos-fedora-or-rhel/ (10认同)
  • 我认为,从主机安全的角度来看,使用 `sudo` 还是使用 `docker` 组并没有太大区别。无论哪种方式,docker 都内置了一个安全漏洞,它可以从来宾提供主机文件系统中的完整权限——无论您是使用 docker 组还是 `sudo` 来启动容器。 (2认同)

Ada*_*nas 129

虽然问题的作者特别说他们对正在运行的容器感兴趣,但同样值得注意的是,如果容器没有运行,但你想运行它来戳你可以运行:

docker run -i -t --entrypoint /bin/bash <imageID>

  • 这给出了一个不同的容器,就像@kraxor 的答案一样。 (11认同)

kra*_*xor 29

尝试这个:

sudo docker run -i -t webserver /bin/bash
Run Code Online (Sandbox Code Playgroud)

来源:https : //docs.docker.com/engine/reference/commandline/run/

  • 它不合适,因为我得到了不同的 CONTAINER ID(``root@42f1e37bd0e5:/#`` 而不是 ``root@665b4a1e17b6:/#``) (16认同)

小智 20

根据@Timur 的回答,我创建了以下方便的脚本

设置

docker-ssh包含$PATH以下内容的文件放入您的文件中

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$CONTAINER" == "" ]]; then
  # if no id given simply just connect to the first running container
  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")
fi

# start an interactive bash inside the container
# note some containers don't have bash, then try: ash (alpine), or simply sh
# the -l at the end stands for login shell that reads profile files (read man)
docker exec -i -t $CONTAINER bash -l
Run Code Online (Sandbox Code Playgroud)

注意:有些容器不含有bash,但是ashsh等。在这些情况下,bash应在上面的脚本来代替。

用法

如果您只有一个正在运行的实例,只需运行

$> docker-ssh 
Run Code Online (Sandbox Code Playgroud)

否则,为它提供您从docker ps(第一列)获得的 docker id 参数

$> docker-ssh 50m3r4nd0m1d
Run Code Online (Sandbox Code Playgroud)


lak*_*tak 18

如果您的容器没有安装 bash,您可以尝试 sh:

docker exec -it CONTAINER /bin/sh
Run Code Online (Sandbox Code Playgroud)

或者先在 /bin 中寻找 shell:

docker export CONTAINER|tar -t|egrep ^bin/
Run Code Online (Sandbox Code Playgroud)


小智 9

我创建了一个容器化的 SSH 服务器,它为任何正在运行的容器提供 SSH 功能。您无需更改容器。唯一的要求是容器有 bash。

如果您有一个名为“web-server1”的容器。以下 docker run 命令将启动第二个容器,为第一个容器提供 SSH。

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \
jeroenpeeters/docker-ssh
Run Code Online (Sandbox Code Playgroud)

有关更多指示,查看https://github.com/jeroenpeeters/docker-ssh


小智 6

@jpetazzo 有一篇关于这个主题精彩帖子。简短的回答是使用nsenter

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
Run Code Online (Sandbox Code Playgroud)

PS:不要忘记查看帖子评论中的讨论...

干杯