我开始使用 Docker。我正在使用 WordPress 基础镜像和 docker-compose。
我正在尝试 ssh 进入其中一个容器以检查在初始构建期间创建的文件/目录。我尝试运行 docker-compose run containername ls -la
,但没有任何效果。即使是这样,我也宁愿有一个可以遍历目录结构的控制台,而不是运行单个命令。使用 Docker 执行此操作的正确方法是什么?
sudo docker run -it --entrypoint /bin/bash <container_name>
让您以交互方式进入容器。然后可以使用 cd <path>
检查容器中的文件系统
docker ps -a
; 2. sudo docker start <container_name>
如果您已经有一个容器正在运行。有关更多参数,请参阅 container start。 3.然后使用exec命令。
docker attach
可让您连接到 Docker 容器,但这与 ssh
并不完全相同。例如,如果您的容器正在运行网络服务器,docker attach
可能会将您连接到网络服务器进程的 stdout。它不一定会给你一个外壳。
docker exec
命令可能是您正在寻找的;这将允许您在现有容器内运行任意命令。例如:
docker exec -it <mycontainer> bash
当然,您运行的任何命令都必须存在于容器文件系统中。
在上述命令中,<mycontainer>
是目标容器的名称或 ID。是否使用 docker compose
无关紧要;只需运行 docker ps
并使用 ID(显示在第一列中的十六进制字符串)或名称(显示在最后一列中)。例如,给定:
$ docker ps
d2d4a89aaee9 larsks/mini-httpd "mini_httpd -d /cont 7 days ago Up 7 days web
我可以跑:
$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:3/64 scope link
valid_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
$
要 bash 进入正在运行的容器,请输入:
docker exec -t -i container_name /bin/bash
或者
docker exec -ti container_name /bin/bash
或者
docker exec -ti container_name sh
docker exec -it
而不是 docker exec -t -i
历史记录:在我写这个答案时,问题的标题是:“如何 ssh 进入 docker 容器?”
正如其他答案所表明的那样,在本地可访问的运行容器中执行预安装的命令(包括 shell)并与之交互是很常见的,而不是 SSH:
docker exec -it (container) (command)
注意:以下答案基于 Ubuntu(2016 年)。非 Debian 容器需要对安装过程进行一些翻译。
比方说,出于您自己的原因,您确实想使用 SSH。这需要几个步骤,但可以完成。以下是您将在容器内运行以进行设置的命令...
apt-get update
apt-get install openssh-server
mkdir /var/run/sshd
chmod 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@IPADDRESS
xeyes ## run an X11 demo app in the client
以下是一些相关资源:
openssh-server 未在 Docker 容器中启动
如何在后台模式下将 bash 或 ssh 放入正在运行的容器中?
你可以在 Linux Docker 容器中运行 GUI 应用程序吗?
通过搜索找到的其他有用的图形访问方法:Docker X11
如果你在 Docker 容器中运行 SSHD,那你就错了!
如果您像我一样在这里寻找特定于 Docker Compose 的答案,它提供了一种简单的方法,无需查找生成的容器 ID。
docker-compose exec
根据您的 docker-compose.yml
文件采用服务名称。
因此,要为您的“网络”服务获取 Bash shell,您可以执行以下操作:
$ docker-compose exec web bash
docker-compose run
也可以使用。
如果容器已经退出(可能是由于一些错误),你可以这样做
$ 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
创建一个新容器并将外壳放入其中。由于您指定了 --rm,因此当您退出 shell 时,容器将被删除。
注意:此答案推广了我编写的工具。
我创建了一个容器化的 SSH 服务器,您可以将它“粘”到任何正在运行的容器上。通过这种方式,您可以使用每个容器创建合成。唯一的要求是容器具有 Bash。
以下示例将启动连接到名为“my-container”的容器的 SSH 服务器。
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 客户端)时,将在名为“my-container”的容器中启动一个 Bash 会话。
有关更多指针和文档,请参阅:https://github.com/jeroenpeeters/docker-ssh
less
每次运行时都会显示警告等。到目前为止,使用 Jeroen 的容器给了我更好的体验。只需确保查看文档。响应中的示例命令似乎不再有效。
使用以下命令启动到 Docker 容器的会话:
sudo docker exec -i -t (container ID) bash
sudo docker exec -it <container ID> bash
如果您在 Windows 上使用 Docker 并希望获得对容器的 shell 访问权限,请使用以下命令:
winpty docker exec -it <container_id> sh
您很可能已经安装了 Git Bash。 如果不安装,请务必安装它。
在某些情况下,您的图像可以是基于 Alpine 的。在这种情况下,它会抛出:
OCI 运行时执行失败:执行失败:container_linux.go:348:启动容器进程导致“exec:\”bash\“:$PATH 中找不到可执行文件”:未知
因为 /bin/bash
不存在。而不是这个,你应该使用:
docker exec -it 9f7d99aa6625 ash
或者
docker exec -it 9f7d99aa6625 sh
要连接到 Windows 容器中的 cmd,请使用
docker exec -it d8c25fde2769 cmd
其中 d8c25fde2769 是容器 ID。
要检查文件,请运行 docker run -it <image> /bin/sh
以获取交互式终端。图像列表可以通过docker images
获得。与 docker exec
相反,此解决方案也适用于图像未启动(或运行后立即退出)的情况。
GOINSIDE解决方案
安装 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
它还解决了长期存在的 problem about fixed Docker container terminal sizes。如果你面对它,这是非常烦人的。
此外,如果您遵循 the link,您的 docker 容器名称也将完成命令。
很简单!
列出所有 Docker 镜像:
sudo docker images
在我的系统上,它显示以下输出:
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
bash latest 922b9cc3ea5e 9 hours ago
14.03 MB
ubuntu latest 7feff7652c69 5 weeks ago 81.15 MB
我的电脑上有两个 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 [container_id] /bin/bash
你会写:
dbash [container_id]
将以下内容放入您的 ~/.bash_profile (或任何其他适合您的),然后打开一个新的终端窗口并享受快捷方式:
#usage: dbash [container_id]
dbash() {
docker exec -it "$1" /bin/bash
}
docker exec -it <container_id or name> bash
或者
docker exec -it <container_id or name> /bin/bash
$ docker exec -it <Container-Id> /bin/bash
或者根据外壳,它可以是
$ docker exec -it <Container-Id> /bin/sh
您可以通过 docker ps
命令获取 container-Id
-i
= 交互式
-t
= 分配一个伪 TTY
您可以通过传递选项 -ti 与 docker 容器中的终端进行交互
docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu
-t 代表终端 -i 代表交互
根据目标,至少有 2 个选项。
选项 1:创建一个新的 bash 进程并加入它(更容易)
示例开始: docker exec -it
退出:输入退出
Pro:适用于所有容器(不取决于 CMD/Entrypoint)
Contra:使用自己的会话和自己的环境变量创建一个新进程
选项 2:附加到已经运行的 bash(更好)
示例开始: docker attach --detach-keys ctrl-d
退出:使用键 ctrl 和 d
Pro:加入容器中完全相同的正在运行的 bash。您具有相同的会话和相同的环境变量。
相反:仅当 CMD/Entrypoint 是交互式 bash 时有效,例如 CMD ["/bin/bash"] 或 CMD ["/bin/bash", "--init-file", "myfile.sh"] 并且容器具有开始使用交互式选项,例如 docker run -itd
我们发现选项 2 更有用。例如,我们将 apache2-foreground
更改为普通背景 apache2
并在此之后启动 bash
。
docker exec
肯定是一个解决方案。解决您提出的问题的一种简单方法是将 Docker 内的目录挂载到本地系统的目录。
这样您就可以立即查看本地路径的变化。
docker run -v /Users/<path>:/<container path>
利用:
docker attach <container name/id here>
另一种方法,虽然有危险,但是使用 attach
,但是如果你 Ctrl + C 退出会话,你也会停止容器.如果您只想查看发生了什么,请使用 docker logs -f
。
:~$ docker attach --help
Usage: 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)
使用这个命令:
docker exec -it containerid /bin/bash
要执行到名为 test
的正在运行的容器,以下是以下命令
如果容器有 bash
shell
docker exec -it test /bin/bash
如果容器有 bourne
shell 并且大多数情况下它都存在
docker run -it test /bin/sh
2022解决方案
考虑另一种选择
你为什么需要它?
有许多基于 distroless 基本图像的现代 docker-images(它们也没有 /bin/bash
/bin/sh
),因此无法docker exec -it {container-name} bash
进入它们。
如何在任何容器中装壳
使用 opener:
需要在您的环境开启者 wordpress 中添加别名
可在任何地方使用 docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock artemkaxboy/opener wordpress
您可以使用要连接的任何容器的名称或 ID 或图像名称来代替 wordpress
这个怎么运作
Opener 是一组封装到 docker 映像的 python 脚本。它通过任何唯一属性(名称、id、端口、图像)找到目标容器,并尝试使用 bash
连接到目标。如果未找到 bash
,opener 会尝试使用 sh
进行连接。最后,如果未找到 sh
,则打开器将 busybox
安装到目标容器中并使用busybox shell 连接到目标,打开器在断开连接期间删除 busybox
。
如果您使用 Kitematic
安装了 Docker,则可以使用 GUI。从 Docker 图标打开 Kitematic
,在 Kitematic
窗口中选择您的容器,然后单击 exec
图标。
您也可以在此 GUI 中查看容器日志和大量容器信息(在设置选项卡中)。
https://i.stack.imgur.com/CIUnq.jpg
https://i.stack.imgur.com/GDdTz.jpg
就我而言,出于某种原因,我需要检查每个容器中涉及的所有网络信息。所以以下命令必须在容器中有效......
ip
route
netstat
ps
...
我检查了所有这些答案,没有一个对我有帮助。我在其他网站上搜索过信息。我不会在这里添加超级链接,因为它不是用英文写的。因此,我只是为与我有相同要求的人提供了一个摘要解决方案。
假设您有一个名为 light-test 的正在运行的容器。请按照以下步骤操作。
docker 检查轻测试 -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
。
有两个选项我们可以使用这些方法 shell
和 bash
直接连接到 docker 终端,但通常不支持 bash 并且默认支持 sh 终端要 sh 进入正在运行的容器,请输入:
docker exec -it container_name/container_ID sh
要 bash 进入正在运行的容器,请输入:
docker exec -it container_name/container_ID bash
并且您只想使用 bash 终端,而不是像 RUN apt install bash -y
一样在 Dockerfile
中安装 bash 终端
另一种选择是使用 nsenter。
PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
nsenter
存在许多问题。首先是它要求您对 docker 主机具有物理访问权限,这不是给定的(您可能正在使用远程 docker API)。此外,在 nsenter
下运行可以免除 Docker 实施的一些安全和资源限制(根据您的环境,这可能是有利的,也可能是不利的)。
docker exec
。
如果您使用的是 Docker Compose,那么这将带您进入 Docker 容器。
docker-compose run container_name /bin/bash
在容器内部,它将带您到 Dockerfile 中定义的 WORKDIR。您可以通过以下方式更改工作目录
WORKDIR directory_path # E.g /usr/src -> container's path
对于 docker-compose up (Docker4Drupal)
docker-compose exec php bash
我在 Linux 笔记本电脑上使用 Docker for Drupal。运行容器后,我使用“docker-compose exec php bash
”连接容器,这样我就可以运行 drush commandos。这对我来说可以。
docker exec
仅适用于正在运行的容器(否则使用docker run -it --entrypoint /bin/bash
或类似的)。-it
是-i
和-t
的组合,分别是--interactive
(“即使未连接也保持 STDIN 打开”)--tty
(“分配伪 TTY”)。docker run -it --entrypoint /bin/bash <imageid> --any --more --args
,只是为了向人们澄清--any --more --args
将被输入图像定义为其CMD
而不是 Docker 的任何内容(或者如果您的图像只定义了一个ENTRYPOINT
而没有CMD
,那么这些选项将按照您在此处指定的方式输入到/bin/bash
中)。因此,例如任何其他docker run
选项(例如--net "host"
)都需要放在<imageid>
之前。