如何“ docker exec”从头开始构建的容器?

时间:2019-02-16 07:23:18

标签: docker containers

我正在尝试docker exec从头开始构建的容器(例如,NATS容器)。看起来很简单,但是由于它是从头开始构建的,因此我无法访问/bin/bash/bin/sh以及几乎任何此类命令。

我收到错误消息:oci runtime error(找不到命令,找不到文件等,取决于我输入的命令)。

我尝试了一些命令,例如:

docker exec -it <container name> /bin/bash
docker exec -it <container name> /bin/sh
docker exec -it <container name> ls

我的问题是,如何docker exec一个从头开始构建且仅包含二进制文件的容器?通过执行docker exec,我希望了解文件是否已成功从主机复制到容器(COPY中有Dockerfile)。

4 个答案:

答案 0 :(得分:2)

如果临时容器正在运行,则可以将外壳程序(和其他所需的utils)复制到其文件系统中,然后执行它。该外壳将需要是静态二进制文件。这里的Busybox是一个不错的选择,因为它可以将其他二进制文件数量增加一倍。

完整示例:

# Assumes scratch container is last launched one, else replace with container ID of
# scratch image, e.g. from `docker ps`, for example:
# scratch_container_id=401b31621b36
scratch_container_id=$(docker ps -ql)

docker run -d busybox:latest sleep 100
busybox_container_id=$(docker ps -ql)
docker cp "$busybox_container_id":/bin/busybox .

# The busybox binary will become whatever you name it (or the first arg you pass to it), for more info run:
# docker run busybox:latest /bin/busybox
# The `busybox --install` command copies the binary with different names into a directory.

docker cp ./busybox "$scratch_container_id":/busybox

docker exec -it "$scratch_container_id" /busybox sh -c '
export PATH="/busybin:$PATH"
/busybox mkdir /busybin
/busybox --install /busybin
sh'

对于Kubernetes,我认为Ephemeral Containers提供或将提供同等功能。

参考: distroless java docker image error https://github.com/GoogleContainerTools/distroless/issues/168#issuecomment-371077961

答案 1 :(得分:1)

有几种选择。

  1. 您可以执行docker container cp ${CONTAINER}:/path/to/file/on/container /path/to/temp/dir/on/host。这会将文件复制到您的主机,您可以在其中使用主机工具检查内容。
  2. 您可以将适当的VOLUME添加到Dockerfile中。然后,您可以docker container inspect ${CONTAINER}。这将在文件应显示的位置显示卷名。然后,您可以检查另一个容器中的容器(基于具有所需所有工具的图像)。
  3. 您可以在运行时将容器绑定到适当位置的卷或主机目录。
  4. 您可以将所需的二进制文件添加到图像中。如果您需要/bin/ls/bin/sh,则可以添加它们。
  5. 您可以将必需的二进制文件绑定安装到容器上-因此容器具有用于验证目的的二进制文件,但是映像不会因它们而膨胀。

答案 2 :(得分:0)

您只能使用scratch来运行容器中实际存在的命令。如果这些命令不存在,则无法运行它们。正如您已经指出的,COPY基本映像不包含任何内容-没有外壳,没有库,没有系统文件,不包含任何内容。

如果您要检查的只是Dockerfile FROM busybox命令是否确实复制了您说过的文件,我通常会假设该工具可以正常工作,而只是在我的应用程序中引用复制的文件。

由于听起来像您控制了Dockerfile,一种解决方法是将基本映像更改为轻量但非空的内容,例如{{1}}。这将为您提供最少的工具集,您可以使用它们而不会过度放大图像大小。

答案 3 :(得分:0)

我正在尝试根据我的需要进行相同的文件检查。我最终用 docker cp 从容器中复制了这个文件。就我而言,我使用的是 nats 容器,但您可以使用任何其他运行基于暂存映像的容器

sudo docker cp nats_nats_1:/nats-server.conf ./nats-server.conf