为什么 docker 图像内容与从中创建的容器不同?

Why does docker image content differ from the container created from it?

以下是镜像的 Dockerfile,

FROM jenkins/jenkins:lts-jdk11
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean:1.25.2 http_request" && ls -la /var/jenkins_home

当使用 docker build -t ireshmm/jenkins:lts-jdk11 . 构建时,以下是输出,

Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM jenkins/jenkins:lts-jdk11
 ---> 9aee0d53624f
Step 2/3 : USER jenkins
 ---> Using cache
 ---> 49d657d24299
Step 3/3 : RUN jenkins-plugin-cli --plugins "blueocean:1.25.2 http_request" && ls -la /var/jenkins_home
 ---> Running in b459c4c48e3e
Done
total 20
drwxr-xr-x 3 jenkins jenkins 4096 Jan 22 16:49 .
drwxr-xr-x 1 root    root    4096 Jan 12 15:46 ..
drwxr-xr-x 3 jenkins jenkins 4096 Jan 22 16:49 .cache
-rw-rw-r-- 1 jenkins root    7152 Jan 12 15:42 tini_pub.gpg
Removing intermediate container b459c4c48e3e
 ---> 5fd5ba428f1a
Successfully built 5fd5ba428f1a
Successfully tagged ireshmm/jenkins:lts-jdk11

创建容器和列表文件时 docker run -it --rm ireshmm/jenkins:lts-jdk11 ls -la /var/jenkins_home,输出如下:

total 40
drwxr-xr-x 3 jenkins jenkins  4096 Jan 22 16:51 .
drwxr-xr-x 1 root    root     4096 Jan 12 15:46 ..
-rw-r--r-- 1 jenkins jenkins  4683 Jan 22 16:51 copy_reference_file.log
drwxr-xr-x 2 jenkins jenkins 16384 Jan 22 16:51 plugins
-rw-rw-r-- 1 jenkins root     7152 Jan 12 15:42 tini_pub.gpg

问题:为什么 /var/jenkins_home 的内容在构建图像时和从它创建的容器内部不同,因为没有命令是 运行在构建图像时列出文件之后?怎么会这样?

jenkins/jenkins:lts-jdk11 有一个运行 /usr/local/bin/jenkins.shENTRYPOINT,它创建了 copy_reference_file.log 文件:

$ grep -i copy_reference /usr/local/bin/jenkins.sh
: "${COPY_REFERENCE_FILE_LOG:="${JENKINS_HOME}/copy_reference_file.log"}"
touch "${COPY_REFERENCE_FILE_LOG}" || { echo "Can not write to ${COPY_REFERENCE_FILE_LOG}. Wrong volume permissions?"; exit 1; }
echo "--- Copying files at $(date)" >> "$COPY_REFERENCE_FILE_LOG"
find "${REF}" \( -type f -o -type l \) -exec bash -c '. /usr/local/bin/jenkins-support; for arg; do copy_reference_file "$arg"; done' _ {} +

每当您从该映像启动容器时(在您在命令行中提供的任何命令之前),ENTRYPOINT 脚本都会运行。