2

我有一个创建的容器

# start
docker build -t cdt-tests .
docker run -it --name cdt-tests cdt-tests
# end => I want to inspect the container filesystem after it's done

因为它没有在分离模式下运行,我如何检查容器?我想要做的是防止容器“自动关闭”,以便在容器完成后检查容器的文件系统。

cdt-tests 的 Dockerfile 如下所示:

FROM node:6

RUN apt-get update && \
      apt-get -y install sudo

RUN sudo apt-get -y update
RUN sudo apt-get -y upgrade
RUN sudo apt-get install -y sqlite3 libsqlite3-dev

USER root

RUN mkdir -p /tmp/test-deps
RUN mkdir -p /usr/local/cdt-tests
WORKDIR /usr/local/cdt-tests

ENV SUMAN_POSTINSTALL_IS_DAEMON no

RUN rm -rf node_modules

RUN npm set progress=false
RUN npm config set loglevel=warn
RUN npm set loglevel=warn

COPY package.json .

RUN npm install --no-optional > /dev/null 2>&1
RUN npm install bower  > /dev/null 2>&1

COPY . .

RUN ./node_modules/.bin/bower install --config.interactive=false --allow-root  > /dev/null 2>&1

ENTRYPOINT ["/bin/bash", "/usr/local/cdt-tests/@run-tests.sh"]

我知道要使用的技巧,覆盖入口点并检查容器,如下所示:

docker run -it --entrypoint /bin/bash --name cdt-tests cdt-tests

但是,这不适用于我当前的用例,因为我想在@run-tests.sh 完成后检查容器!

所以我有两个问题:

  1. 如何在非守护程序容器完成运行后检查它的文件系统?
  2. 如何获取为非守护程序容器创建的容器的容器 ID(不使用 $(docker ps))。

如果我做 a docker ps -a,我会看到:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
08740a432d1c        cdt-tests           "/bin/bash /usr/lo..."   24 seconds ago      Exited (130) 7 seconds ago                       cdt-tests
f27a302b1d8f        cdt-server          "/bin/bash /usr/lo..."   38 seconds ago      Up 36 seconds                                    cdt-server
b854506e75df        cisco-selenium      "/opt/bin/entry_po..."   41 seconds ago      Up 39 seconds                4444/tcp            cdt-selenium
a37cab33b293        mongo               "docker-entrypoint..."   43 seconds ago      Up 41 seconds                27017/tcp           cdt-mongo

所以我们可以看到 cdt-tests 在那里,即使它不是一个守护进程。

所以我们尝试检查它,如下所示:

docker exec cdt-tests /bin/bash

但我们得到一个错误:

Error response from daemon: Container 08740a432d1c8f014bc138c82706de1e9682a052c088531d60b33c6acbbd5559 is not running

该怎么办?

4

2 回答 2

3

如何在非守护程序容器完成运行后检查它的文件系统?

使用docker cp. 查看文档

docker cp 实用程序将 SRC_PATH 的内容复制到 DEST_PATH。您可以从容器的文件系统复制到本地机器,或者反过来,从本地文件系统复制到容器。(...) CONTAINER 可以是正在运行或已停止的容器。SRC_PATH 或 DEST_PATH 可以是文件或目录。

另一种选择是将容器具体化为新图像并在其上运行 bash:

docker commit <stopped-container> new_image_name
docker run -it --entrypoint /bin/bash new_image_name

如何获取为非守护程序容器创建的容器的容器 ID(不使用 $(docker ps))。

1)当你做docker run -d的输出是已经创建的容器ID,所以你可以保存该信息:

container_id=$(docker run -d .......)

2)这将向您显示停止的测试容器:

docker ps -a --filter ancestor=cdt-tests

这将最后停止的测试容器放入 var 中:

container_id=$(docker ps -q -a --filter ancestor=cdt-tests | head -n1)

每种情况都有许多其他变体。


编辑。使用卷版本方法,您可以将单个文件绑定为卷:

docker run -v ./tests.log:/path/to/logs/file.log -it --name cdt-tests cdt-tests
于 2017-05-27T13:27:03.560 回答
1

我不知道问题 2。但对于问题 1,一个可能的解决方案是捕获退出信号 - 尽管这将在容器本身内执行。但我想如果目标是检查容器中的文件系统,您可以将结果通过管道传输到已安装的目录。

例如在 run-tests.sh 脚本中添加

exiting() {
  # do file system inspection here
}

# trap the exit signal
trap exiting SIGINT SIGTERM EXIT

编辑:要将日志目录/文件挂载到主机,请使用 -v 选项,

docker run -it -v $HOME/log:/var/log --name cdt-tests cdt-tests

请注意,使用 -v 选项时,请确保您没有挂载到容器的工作目录 - docker 将使用主机内容覆盖它。

docker cp 命令的另一个答案也应该有效。我主要使用 -v ,因为在主机上运行日志意味着我可以在程序运行时使用 tail -f 检查或观看它。这取决于用例。要记住的另一件事是,如果程序运行正常,容器将退出而不会出错,并且无法复制。容器仅在错误退出时才保留。

于 2017-05-27T06:30:48.873 回答