如何'docker exec'从头开始构建容器?

问题描述 投票:1回答:2

我正在尝试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)。

docker containers
2个回答
2
投票

有几种选择。

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

2
投票

如果您的临时容器正在运行,您可以将shell(以及其他所需的utils)复制到其文件系统中,然后执行它。 shell需要是一个静态二进制文件。 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
投票

您只能使用docker exec来运行实际存在于容器中的命令。如果这些命令不存在,则无法运行它们。正如您所指出的那样,scratch基本图像不包含任何内容 - 没有shell,没有库,没有系统文件,没有任何内容。

如果您要检查的是Dockerfile COPY命令是否实际上复制了您所说的文件,我通常会假设工具正常工作,并且只是在我的应用程序中引用复制的文件。

因为它听起来像你控制Dockerfile,一个解决方法可能是将基本图像更改为轻量级但非空的,如FROM busybox。这将为您提供一组最小的工具,您可以使用它们而不会过多地夸大图像大小。

© www.soinside.com 2019 - 2024. All rights reserved.