我开始和Docker合作了。我正在使用WordPress的基本图像和docker合成。

我正在尝试ssh到其中一个容器中,以检查在初始构建期间创建的文件/目录。我试着运行docker compose运行containername ls-la,但没有任何效果。即使是这样,我也希望有一个控制台,在那里我可以遍历目录结构,而不是运行一个命令。使用Docker的正确方法是什么?


当前回答

我创建了一个终端功能,以便更方便地访问容器的终端。也许这对你们也有用:

结果是,不用键入:

docker exec -it [container_id] /bin/bash

你会写:

dbash [container_id]

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

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

其他回答

docker-attach将允许您连接到docker容器,但这实际上与ssh不同。例如,如果您的容器正在运行web服务器,docker附件可能会将您连接到web服务器进程的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
$

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

sudo docker运行-it--entrypoint/bin/bash<container_name>

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

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

or

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

or

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

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

另一种选择是使用nsenter。

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

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

ip
route
netstat
ps
...

我检查了所有这些答案,没有一个对我有用。我在其他网站上搜索过信息。我不会在这里添加超级链接,因为它不是用英语编写的。因此,我只是为与我有相同要求的人发布了一个总结解决方案。

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

docker inspect light test-f{{.NetworkSettings.SandboxKey}}。此命令将得到类似/var/run/docker/netns/xxxx的回复。然后是ln-s/var/run/docker/netns/xxxxx/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。