如何进入Docker容器的shell?

我正在开始使用Docker。我正在使用WordPress基础映像和docker-compose。

我正在尝试ssh进入其中一个容器以检查在初始构建期间创建的文件/目录。我尝试运行docker-compose run containername ls -la,但没有任何作用。即使有,我宁愿有一个可以遍历目录结构的控制台,而不是运行单个命令。使用Docker执行此操作的正确方法是什么?

1806066 次浏览

docker attach将允许您连接到Docker容器,但这与ssh并不完全相同。例如,如果您的容器运行的是Web服务器,docker attach可能会将您连接到Web服务器进程的标准输出。它不一定会给你一个shell。

docker exec命令可能就是您要查找的;这将允许您在现有容器中运行任意命令。例如:

docker exec -it <mycontainer> bash

当然,您正在运行的任何命令都必须存在于容器文件系统中。

在上面的命令<mycontainer>中是目标容器的名称或ID。无论您是否使用docker compose;只需运行docker ps并使用ID(显示在第一列中的十六进制字符串)或名称(显示在最后一列中)。例如,给定:

$ docker psd2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web

我可以跑:

$ docker exec -it web ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWNlink/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UPlink/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ffinet 172.17.0.3/16 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::42:acff:fe11:3/64 scope linkvalid_lft forever preferred_lft forever

我可以通过运行来完成同样的事情:

$ docker exec -it d2d4a89aaee9 ip addr

类似地,我可以在容器中启动一个shell;

$ docker exec -it web sh/ # echo This is inside the container.This is inside the container./ # exit$

另一种选择是使用nsenter

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

docker exec肯定是一个解决方案。处理你问的问题的一个简单方法是将Docker中的目录挂载到本地系统的目录

这样你就可以立即查看本地路径的变化。

docker run -v /Users/<path>:/<container path>

公告:这个答案推广了我写的一个工具。

我创建了一个容器化的SSH服务器,您可以“坚持”任何正在运行的容器。这样您就可以使用每个容器创建组合。唯一的要求是容器具有Bash。

下面的示例将启动一个SSH服务器,该服务器连接到名为“my-容器”的容器。

docker run -d -p 2222:22 \-v /var/run/docker.sock:/var/run/docker.sock \-e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \jeroenpeeters/docker-ssh
ssh localhost -p 2222

当您连接到这个SSH服务(使用您选择的SSH客户端)时,一个Bash会话将在名为“my-容器”的容器中启动。

更多指针和留档见:https://github.com/jeroenpeeters/docker-ssh

要猛击正在运行的容器,请键入:

docker exec -t -i container_name /bin/bash

docker exec -ti container_name /bin/bash

docker exec -ti container_name sh

使用以下命令在Docker容器中启动会话:

sudo docker exec -i -t (container ID) bash

历史笔记:在我写这个答案的时候,这个问题的标题是:“如何ssh到docker容器中?”

正如其他答案所示,使用docker exec而不是SSH在本地可访问的运行容器中执行预装命令(包括shell)并与之交互是很常见的:

docker exec -it (container) (command)

注意:以下答案基于Ubuntu(2016年)。非Debian容器需要对安装过程进行一些翻译。

比方说,由于您自己的原因,您确实想要使用SSH。这需要几个步骤,但可以完成。以下是您将在容器内运行以设置它的命令…

apt-get updateapt-get install openssh-server
mkdir /var/run/sshdchmod 0755 /var/run/sshd/usr/sbin/sshd
useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'passwd username ## Enter a password
apt-get install x11-apps ## X11 demo applications (optional)ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

现在,您甚至可以使用X11转发到SSH客户端来运行图形应用程序(如果它们安装在容器中):

ssh -X username@IPADDRESSxeyes ## run an X11 demo app in the client

以下是一些相关资源:

用途:

docker attach <container name/id here>

另一种方法,尽管有危险,是使用attach,但如果您Ctrl+C退出会话,您也将停止容器。如果您只是想看看发生了什么,请使用docker logs -f

:~$ docker attach --helpUsage:  docker attach [OPTIONS] CONTAINER
Attach to a running container
Options:--detach-keys string   Override the key sequence for detaching a container--help                 Print usage--no-stdin             Do not attach STDIN--sig-proxy            Proxy all received signals to the process (default true)

如果您在Windows上使用Docker并希望获得对容器的shell访问权限,请使用以下命令:

winpty docker exec -it <container_id> sh

很可能,您已经安装了gitbash如果没有,请确保安装它。

要连接到Windows容器中的cmd,请使用

docker exec -it d8c25fde2769 cmd

其中d 8 c 25 fde 2769是容器ID。

对于docker编写(Docker4Drupal)

docker-compose exec php bash

我在Linux笔记本电脑上使用Drupal的Docker。运行容器后,我使用docker-compose exec php bash连接容器,这样我就可以运行drush突击队了。它对我来说很好。

要检查文件,请运行docker run -it <image> /bin/sh以获取交互式终端。图像列表可以通过docker images获得。与docker exec相反,此解决方案也适用于图像未启动(或运行后立即退出)的情况。

如果您像我一样在这里寻找特定于Docker Compose-的答案,它提供了一种简单的方法,而无需查找生成的容器ID。

docker-compose exec根据您的docker-compose.yml文件获取服务的名称。

因此,要为您的“Web”服务获取Bash shell,您可以执行以下操作:

$ docker-compose exec web bash

如果您使用的是Docker Compose,那么这将带您进入Docker容器。

docker-compose run container_name /bin/bash

在容器内,它将带您到Dockerfile中定义的WORKDIR。您可以通过

WORKDIR directory_path # E.g  /usr/src -> container's path

内侧解决方案

安装goinside命令行工具:

sudo npm install -g goinside

并进入具有适当终端大小的docker容器:

goinside docker_container_name

旧的答案

我们把这个片段放在~/.profile中:

goinside(){docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";}export -f goinside

这不仅使每个人都能够进入正在运行的容器:

goinside containername

它还解决了一个长寿的固定Docker容器终端大小的问题。如果你面对它,这是非常烦人的。

此外,如果您遵循的链接,您的docker容器名称也将完成命令。

在某些情况下,您的图像可以是基于高山的。在这种情况下,它会抛出:

OCI运行时执行失败:执行失败:container_linux.go:348:启动容器进程导致“exec:\”bash\”:在$PATH":未知

因为/bin/bash不存在。你应该使用:

docker exec -it 9f7d99aa6625 ash

docker exec -it 9f7d99aa6625 sh

如果您安装了带有Kitematic的Docker,则可以使用GUI。从Docker图标打开Kitematic,在Kitematic窗口中选择您的容器,然后单击exec图标。

您也可以在此GUI中看到容器日志和大量容器信息(在设置选项卡中)。

从菜单中选择图形

点击exec

这很简单

列出你所有的Docker镜像:

sudo docker images

在我的系统上,它显示了以下输出:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZEbash                latest              922b9cc3ea5e        9 hours ago14.03 MBubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

我的PC上有两个Docker映像。假设我想运行第一个。

sudo docker run -i -t ubuntu:latest /bin/bash

这将使您可以对容器进行终端控制。现在您可以在容器内执行所有类型的shell操作。就像做ls一样,将输出文件系统根目录中的所有文件夹。

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

使用此命令:

docker exec -it containerid /bin/bash

在我的情况下,出于某种原因,我需要检查每个容器中的所有网络相关信息。因此,以下命令必须在容器中有效…

iproutenetstatps...

我检查了所有这些答案,没有一个对我有帮助。我在其他网站搜索过信息。我不会在这里添加超级链接,因为它不是用英文写的。所以我只是把这篇文章和一个总结的解决方案放在一起,供和我有同样要求的人使用。

假设您有一个名为light-test的正在运行的容器。按照以下步骤操作。

  • docker inspect light-test -f \{\{.NetworkSettings.SandboxKey}}。此命令将得到类似于/var/run/docker/netns/xxxx的回复。
  • 然后ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx。目录可能不存在,先做mkdir /var/run/netns
  • 现在您可以执行ip netns exec xxxx ip addr show来探索容器中的网络世界。

PS。xxxx始终与从第一个命令接收到的值相同。当然,任何其他命令都是有效的,即ip netns exec xxxx netstat -antp|grep 8080

如果容器已经退出(可能是由于某些错误),您可以这样做

$ docker run --rm -it --entrypoint /bin/ash image_name

$ docker run --rm -it --entrypoint /bin/sh image_name

$ docker run --rm -it --entrypoint /bin/bash image_name

创建一个新容器并将shell放入其中。由于您指定了--rm,因此当您退出shell时,容器将被删除。

$ docker exec -it <Container-Id> /bin/bash

或者根据外壳,它可以是

$ docker exec -it <Container-Id> /bin/sh

您可以通过docker ps命令获取容器类型

-i=交互式

-t=分配一个psuedo-TTY

您可以通过传递选项-ti与docker容器中的终端交互

docker run --rm -ti <image-name>eg: docker run --rm -ti ubuntu

-t代表终端

交互式

我创建了一个终端函数,以便更轻松地访问容器的终端。也许它对你们也很有用:

所以结果是,而不是键入:

docker exec -it [container_id] /bin/bash

你会写:

dbash [container_id]

将以下内容放入您的~/.bash_profile(或其他适合您的内容),然后打开一个新的终端窗口并享受快捷方式:

#usage: dbash [container_id]dbash() {docker exec -it "$1" /bin/bash}

要执行到名为test的正在运行的容器中,下面是以下命令

如果容器有bash shell

docker exec -it test /bin/bash

如果容器有bourne shell并且大多数情况下它都存在

docker run -it test /bin/sh

根据目标,至少有两种选择。

备选案文1:创建一个新的bash进程并加入它(更容易)

  • 示例开始:docker exec -it <containername> /bin/bash
  • 退出:类型exit
  • 优点:适用于所有容器(不依赖于CMD/Entrypoint)
  • 魂斗罗:创建一个拥有自己会话和环境变量的新进程

备选案文2:附加到已经运行的bash(更好)

  • 示例开始:docker attach --detach-keys ctrl-d <containername>
  • 退出:使用键ctrld
  • 优点:加入容器中完全相同的运行bash。您有相同的会话和相同的环境变量。
  • 魂斗罗:只有当CMD/Entrypoint是一个交互式bash,如CMD ["/bin/bash"]CMD ["/bin/bash", "--init-file", "myfile.sh"],如果容器已经启动了交互式选项,如docker run -itd <image>(-i=交互式,-t=tty和-d=deamon[opt])

我们发现选项2更有用。例如,我们将apache2-foreground更改为正常背景apache2,然后开始bash

有两个选项,我们可以使用这些方法shellbash直接连接到docker终端,但通常不支持bash,支持defualt sh终端要sh到正在运行的容器中,请键入:

docker exec-itcontainer_name/container_IDsh

要猛击正在运行的容器,请键入:

docker exec-itcontainer_name/container_IDbash

你想只使用bash终端,而不是像RUN apt install bash -y一样在你的Dockerfile中安装bash终端

docker exec -it <container_id or name> bash

docker exec -it <container_id or name> /bin/bash

2022解决方案

考虑另一种选择

你为什么需要它?

有一堆基于无发行基本图像(他们也没有#0#1)的现代docker映像,因此不可能docker exec -it {container-name} bash进入它们。

如何在任何容器中使用shell

使用开瓶器

  • 需要添加别名在您的环境中opener wordpress
  • 在任何地方工作docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock artemkaxboy/opener wordpress

而不是wordpress,您可以使用要连接的任何容器的名称或ID或图像名称


它是如何运作的

开场白是一组包装成docker映像的python脚本。它通过任何唯一属性(名称、id、端口、图像)找到目标容器,尝试使用bash连接到目标容器。如果找不到bash,打开器尝试使用sh连接。最后,如果找不到sh,打开器将busybox安装到目标容器中,并使用busybox shell连接到目标容器,打开器在断开连接时删除busybox

简单

docker exec -it <container_id> bash

在上面-it表示交互终端。

这对我来说是最好的,因为如果使用它,我真的不必在我的docker构建中添加切入点。

sudo docker run -it --entrypoint /bin/bash <container_name>