我已经为一个应用程序创建了一个docker镜像,我正在为这个图像复制文件夹,如下所示:
COPY extra-addons/ /mnt/extra-addons/pos_item_price/
但是当我使用kubernetes使用该图像并转到/ mnt / extra-addons文件夹时
$ kubectl --insecure-skip-tls-verify --namespace my-app exec -it my-app-55d464dd78-7h7x7 -- /bin/bash
root@my-app-55d464dd78-7h7x7:/# cd /mnt/extra-addons/
root@my-app-55d464dd78-7h7x7:/mnt/extra-addons# ls
root@my-app-55d464dd78-7h7x7:/mnt/extra-addons#
我什么也没看到
但我确实看到在构建图像时正在复制数据
Step 19/26 : COPY extra-addons/ /mnt/extra-addons/pos_item_price/
---> 47fda7baba98
Step 20/26 : RUN ls -la /mnt/extra-addons/*
---> Running in ab93cf423db5
total 12
drwxr-xr-x. 3 odoo root 4096 Apr 21 11:13 .
drwxr-xr-x. 3 odoo root 4096 Apr 21 11:13 ..
drwxrwxrwx. 7 root root 4096 Apr 21 11:13 pos_item_price
Removing intermediate container ab93cf423db5
---> 645bc64741e0
Step 21/26 : RUN ls -la /mnt/extra-addons/pos_item_price/*
---> Running in f6ad09d6d83c
total 44
drwxrwxrwx. 7 root root 4096 Apr 21 11:13 .
drwxr-xr-x. 3 odoo root 4096 Apr 21 11:13 ..
-rw-rw-rw-. 1 root root 77 Apr 21 11:10 .git
-rw-rw-rw-. 1 root root 579 Apr 21 11:10 .gitignore
-rw-rw-rw-. 1 root root 45 Apr 21 11:10 __init__.py
-rw-rw-rw-. 1 root root 571 Apr 21 11:10 __manifest__.py
drwxrwxrwx. 2 root root 4096 Apr 21 11:13 data
drwxrwxrwx. 2 root root 4096 Apr 21 11:13 models
drwxrwxrwx. 2 root root 4096 Apr 21 11:13 security
drwxrwxrwx. 3 root root 4096 Apr 21 11:13 static
drwxrwxrwx. 2 root root 4096 Apr 21 11:13 views
Removing intermediate container f6ad09d6d83c
---> dc35af25b2a8
我想知道为什么当我将它复制到图像中时它不是持久的,我本来期望数据出现在kubernetes pod中?
完整的Dockerfile
FROM debian:stretch
# Generate locale C.UTF-8 for postgres and general locale data
ENV LANG C.UTF-8
# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf
RUN set -x; \
apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
dirmngr \
fonts-noto-cjk \
gnupg \
libssl1.0-dev \
node-less \
python3-pip \
python3-pyldap \
python3-qrcode \
python3-renderpm \
python3-setuptools \
python3-vobject \
python3-watchdog \
xz-utils \
&& curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb \
&& echo '7e35a63f9db14f93ec7feeb0fce76b30c08f2057 wkhtmltox.deb' | sha1sum -c - \
&& dpkg --force-depends -i wkhtmltox.deb\
&& apt-get -y install -f --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* wkhtmltox.deb
# install latest postgresql-client
RUN set -x; \
echo 'deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main' > etc/apt/sources.list.d/pgdg.list \
&& export GNUPGHOME="$(mktemp -d)" \
&& repokey='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' \
&& gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \
&& gpg --armor --export "${repokey}" | apt-key add - \
&& gpgconf --kill all \
&& rm -rf "$GNUPGHOME" \
&& apt-get update \
&& apt-get install -y postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# Install rtlcss (on Debian stretch)
RUN set -x;\
echo "deb http://deb.nodesource.com/node_8.x stretch main" > /etc/apt/sources.list.d/nodesource.list \
&& export GNUPGHOME="$(mktemp -d)" \
&& repokey='9FD3B784BC1C6FC31A8A0A1C1655A0AB68576280' \
&& gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \
&& gpg --armor --export "${repokey}" | apt-key add - \
&& gpgconf --kill all \
&& rm -rf "$GNUPGHOME" \
&& apt-get update \
&& apt-get install -y nodejs \
&& npm install -g rtlcss \
&& rm -rf /var/lib/apt/lists/*
# Install Odoo
ENV ODOO_VERSION 12.0
ARG ODOO_RELEASE=20190128
ARG ODOO_SHA=9e34aaed2eb1e7697aaf36767247dbf335e9fe7a
RUN set -x; \
curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/odoo_${ODOO_VERSION}.${ODOO_RELEASE}_all.deb \
&& echo "${ODOO_SHA} odoo.deb" | sha1sum -c - \
&& dpkg --force-depends -i odoo.deb \
&& apt-get update \
&& apt-get -y install -f --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* odoo.deb
# Copy entrypoint script and Odoo configuration file
RUN pip3 install num2words xlwt
COPY ./entrypoint.sh /
COPY ./odoo.conf /etc/odoo/
RUN chown odoo /etc/odoo/odoo.conf
# Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons
RUN mkdir -p /mnt/extra-addons/pos_item_price \
&& chown -R odoo /mnt/extra-addons
VOLUME ["/var/lib/odoo", "/mnt/extra-addons"]
RUN ls -la /mnt/extra-addons/*
RUN echo "-------- Before LS END -----"
COPY extra-addons/ /mnt/extra-addons/pos_item_price/
RUN ls -la /mnt/extra-addons/*
RUN ls -la /mnt/extra-addons/pos_item_price/*
# Expose Odoo services
EXPOSE 8069 8071
# Set the default config file
ENV ODOO_RC /etc/odoo/odoo.conf
# Set default user when running the container
USER odoo
ENTRYPOINT ["/entrypoint.sh"]
CMD ["odoo"]
我相信您面临的问题与您的卷有关,但与Dockerfile中定义的卷不相关(即使我个人不喜欢Dockerfile中定义的任何卷,因为它们会导致问题)。
要解释Dockerfile中VOLUME产生的问题,您可以看到以下示例来测试COPY,ADD和RUN:
$ cat df.vol
FROM busybox:latest
VOLUME ["/data"]
CMD find /data
COPY sample-data/file.txt /data/file.txt
COPY sample-data/dir /data/dir
ADD sample-data/tar-file.tgz /data/tar-dir
RUN echo "hello world" >/data/run.txt \
&& find /data \
&& sleep 5m
这是用于COPY和ADD命令的sample-data目录:
$ ls -al sample-data/
total 32
drwxr-xr-x 3 bmitch bmitch 4096 Jan 22 2017 .
drwxr-xr-x 34 bmitch bmitch 12288 Apr 17 15:16 ..
drwxr-xr-x 2 bmitch bmitch 4096 Jan 22 2017 dir
-rw-r--r-- 1 bmitch bmitch 14 Jan 22 2017 file2.txt
-rw-r--r-- 1 bmitch bmitch 12 Jan 22 2017 file.txt
-rw-r--r-- 1 bmitch bmitch 214 Jan 22 2017 tar-file.tgz
让我们运行一个构建(没有BUILDKIT,因为我们希望能够调试它):
$ DOCKER_BUILDKIT=0 docker build -f df.vol -t test-vol .
Sending build context to Docker daemon 23.04kB
Step 1/7 : FROM busybox:latest
---> 59788edf1f3e
Step 2/7 : VOLUME ["/data"]
---> Using cache
---> 14b4f1130806
Step 3/7 : CMD find /data
---> Running in 75673363d1e3
Removing intermediate container 75673363d1e3
---> 262714d065fc
Step 4/7 : COPY sample-data/file.txt /data/file.txt
---> d781519c584e
Step 5/7 : COPY sample-data/dir /data/dir
---> 34b5b4a83b1e
Step 6/7 : ADD sample-data/tar-file.tgz /data/tar-dir
---> 3fc45f2e62a4
Step 7/7 : RUN echo "hello world" >/data/run.txt && find /data && sleep 5m
---> Running in d75794387274
/data
/data/dir
/data/dir/file1.txt
/data/dir/file2.txt
/data/run.txt
/data/tar-dir
/data/tar-dir/dir
/data/tar-dir/dir/file1.txt
/data/tar-dir/dir/file2.txt
/data/tar-dir/file.txt
/data/file.txt
Removing intermediate container d75794387274
---> 5af322be539a
Successfully built 5af322be539a
Successfully tagged test-vol:latest
请注意上面的run.txt
文件。我们还会看到COPY和ADD命令中的文件。但是,如果我们运行另一个RUN命令,或者我们使用生成的图像,我们会看到:
$ docker run -it --rm test-vol:latest
/data
/data/dir
/data/dir/file1.txt
/data/dir/file2.txt
/data/tar-dir
/data/tar-dir/dir
/data/tar-dir/dir/file1.txt
/data/tar-dir/dir/file2.txt
/data/tar-dir/file.txt
/data/file.txt
只有来自COPY和ADD的文件。如果我们查看docker用于RUN步骤的临时容器(这就是为什么我在构建期间有sleep 5m
),原因就更容易看到了。这是5分钟睡眠期间另一个窗口的输出:
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d75794387274 3fc45f2e62a4 "/bin/sh -c 'echo \"h…" 1 second ago Created brave_dubinsky
$ docker diff d75
$ docker inspect d75
[
{
"Id": "d75794387274cc222391065c14581a29ff9fcc898ef367db64b9f145bd9325c7",
"Created": "2019-04-21T18:19:19.449392301Z",
"Path": "/bin/sh",
"Args": [
"-c",
"echo \"hello world\" >/data/run.txt && find /data && sleep 5m"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 31620,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-04-21T18:19:22.699031557Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
...
"Mounts": [
{
"Type": "volume",
"Name": "07b9d30dfdfcae91b820dc6fa249030fd8d7a4ad9c50ee928aaab104c07c8a9d",
"Source": "/home/var-docker/volumes/07b9d30dfdfcae91b820dc6fa249030fd8d7a4ad9c50ee928aaab104c07c8a9d/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...
您在上面的命令中看到的是docker使用临时容器和匿名卷运行构建。 diff
输出显示对该容器的更改,该更改将由构建作为Dockerfile中的层捕获。在这种情况下,没有。
对卷进行更改不会修改容器文件系统,因此您永远不会看到更改,但ADD和COPY命令直接针对图像层运行,因此您可以看到这些更改。
从Dockerfile中删除VOLUME会解决这个问题吗?可能不会(除非您运行图像的方法是创建并重用图像中的匿名卷)。我还建议你去掉VOLUME吗?是的,稍后在运行容器时不需要指定卷,您可以为任何目录定义卷,然后在Dockerfile中中断尝试以非直观的方式使用RUN命令扩展映像。
因此,如果不是VOLUME命令与COPY交互,为什么还会看到您的更改丢失?最可能的原因是在运行容器时定义卷。我们需要确定您的yml规范。该卷(如果它是指定的卷)将使用图像的内容进行初始化,但只会初始化一次。之后,无论您在图像中更改了什么内容,卷都将保持不变,并显示上次使用该卷时卷中的文件。
如果要根据映像更改来更新卷,则需要在映像中配置入口点,以将文件从映像中保存的位置复制到容器中的卷位置。我在docker-base图像中有这样做的例子。在那里查看save-volume
和load-volume
脚本。