2017-05-27 35 views
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 

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

的Dockerfile对CDT的测试看起来像:

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. 如何获取为非守护程序容器创建的容器的容器标识(不使用$(docker ps))。

如果我做了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的测试是有的,即使它不是一个守护进程。

所以我们尝试检查它,像这样:

docker exec cdt-tests /bin/bash 

,但我们得到一个错误:

Error response from daemon: Container 08740a432d1c8f014bc138c82706de1e9682a052c088531d60b33c6acbbd5559 is not running 

怎么办?

回答

1

How can I inspect the filesystem of a non-daemon container after it has completed running?

使用docker cp。见docs

The docker cp utility copies the contents of SRC_PATH to the DEST_PATH. You can copy from the container’s file system to the local machine or the reverse, from the local filesystem to the container. (...) The CONTAINER can be a running or stopped container. The SRC_PATH or DEST_PATH can be a file or directory.

另一种选择是在它的容器物化到一个新的图像和运行bash下

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

How can I get the container id for the container that's created for a non-daemon container (without using $(docker ps)).

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

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

2)这将显示您停止试验容器:

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

而这种投入的最后一个变种停止试验容器:

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 
+0

嘿,罗伯特,非deamon容器我的意思是一个容器,不运行-d标志...但让我尝试docker cp的想法.. 。我不确定码头的CP会工作,因为我可能会收到一条消息,说:“CDT测试容器不运行”(因为它已完成)。我想要做的是将容器的内容从容器复制到主机。我认为其他答案是更好的地方,他们建议使用-v dir:/ dir –

+0

你必须查看其他答案的评论,你会明白我的意思。 –

+0

请注意,正如我所说,cp的工作原理如下:* CONTAINER可以是正在运行或已停止的容器。* – Robert

1

我不知道问题2. 但对于问题1,一个可能的解决方案是捕获退出信号 - 虽然这将在容器内部执行。但是,我猜如果目标是检查容器中的文件系统,则可以将结果传输到安装的目录。

例如使用-v选项时 对于安装日志目录/文件复制到主机,使用-v选项,

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

注意,:在run-tests.sh脚本中添加

exiting() { 
    # do file system inspection here 
} 

# trap the exit signal 
trap exiting SIGINT SIGTERM EXIT 

编辑,确保你没有安装到容器的工作目录 - docker会用主机内容覆盖它。

docker cp命令的其他答案也应该起作用。我主要使用-v,因为让日志活在主机上意味着我有可能在程序运行时使用tail -f来检查或观察它。这取决于用例。另外要记住的是,如果程序运行正常,容器将无错误地退出,并且它将不可用于复制。容器只有在出错时才会停留。

+0

好的,谢谢,所以当我运行詹金斯这个测试脚本,我不要(或者说是一个CI/CD管道的一部分,一些远程服务器上)我们不想停止整个过程。但是我确实想给自己一个机会,在出现问题时调试。不知道该怎么办。 –

+0

我不知道我是否理解正确,如果你指的是run-tests.sh脚本中的部分步骤,我应该可以在脚本中检查程序的退出代码并记录下来......类似[[[ $? != 0]]; echo“Error here” - 再次加载到安装目录中的日志文件,以便以后检查。 – micebrain

+0

@ run-test.sh脚本将写入容器中的某些日志文件......目前它尚未设置为向容器外的日志文件写入......尽管这似乎是我现在最好的选择......你有链接显示如何挂载共享目录或其他? –