首页 > 解决方案 > Docker 卷对不同图像的行为不同

问题描述

我是 docker 新手,需要了解 docker 卷行为

我用 nginx 和 jenkins 得到了不同的结果

场景一:使用“nginx”镜像

# docker volume create testvol
testvol
# cd /var/lib/docker/volumes/testvol/_data/
# touch newfile1 newfile2
# ls
newfile1  newfile2

# docker run -it -v testvol:/usr/share/nginx/html nginx bash
# cd usr/share/nginx/html/
# ls
newfile1  newfile2

在这里,/usr/share/nginx/html/ 下的容器内部文件是从卷(newfile1,newfile2)复制的,但默认的 nginx 文件已删除(50x.html index.html)

场景 2:使用 jenkins 图像

使用相同体积的 testvol

# docker run -it -v testvol:/var/jenkins_home jenkins/jenkins bash
# cd /var/jenkins_home
# ls
copy_reference_file.log  newfile1  newfile2

在这里,在容器内,原始文件保存在詹金斯容器(copy_reference_file.log)中,文件从卷(newfile1,newfile2)中复制

为什么会有这种差异,或者我理解错了?

标签: dockerdocker-volume

解决方案


Jenkins Docker 镜像的源代码在GitHub 上。如果你查看它的Dockerfile,它的最后一行

ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/jenkins.sh"]

当你那时

docker run ... jenkinsci/jenkinsci bash

成为bash图像的命令,作为附加参数传递给入口点,Docker 运行该组合命令。jenkins.sh脚本依次

: "${JENKINS_HOME:="/var/jenkins_home"}"
: "${COPY_REFERENCE_FILE_LOG:="${JENKINS_HOME}/copy_reference_file.log"}"
touch "${COPY_REFERENCE_FILE_LOG}"

这就是为什么在您的第二个示例中该文件copy_reference_file.log存在的原因。

创建容器时:

  • 如果 Dockerfile 声明了 aVOLUME并且该目录上没有挂载任何其他内容,则 Docker 会创建一个新的空匿名卷。
  • 如果将命名或匿名卷(但不是绑定挂载)挂载到容器中,并且该卷为空,则将映像的内容复制到卷中。
  • 卷从这里开始替换容器文件系统的相应部分;对该目录的读取和写入转到卷(或绑定安装的主机目录)。

不是图像的“传递”;只有在第一次使用空卷时,才会将内容复制到卷中。如果您以您的示例并重新运行nginx具有相同卷的容器,您将看到卷中copy_reference_file.log仍然存在。


推荐阅读