为什么docker没有完全删除我的文件?
我正在尝试使用以下方法构建:为什么docker没有完全删除我的文件?,docker,centos,Docker,Centos,我正在尝试使用以下方法构建: FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS builder COPY pythonnet/src/ pythonnet/src WORKDIR /pythonnet/src/runtime RUN dotnet build -f netstandard2.0 -p:DefineConstants=\"MONO_LINUX\;XPLAT\;PYTHON3\;PYTHON37\;UCS4\;NETSTANDAR
FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS builder
COPY pythonnet/src/ pythonnet/src
WORKDIR /pythonnet/src/runtime
RUN dotnet build -f netstandard2.0 -p:DefineConstants=\"MONO_LINUX\;XPLAT\;PYTHON3\;PYTHON37\;UCS4\;NETSTANDARD\" Python.Runtime.15.csproj
# copy myApp csproj and restore
COPY src/myApp/*.csproj /src/myApp/
WORKDIR /src/myApp
RUN dotnet restore
# now copy everything else as separate docker step
# (copy to staging folder, remove csproj, and copy down - so we don't overwrite project above)
WORKDIR /
COPY src/myApp/ ./staging/src/myApp
RUN rm ./staging/src/myApp/*.csproj \
&& cp -r ./staging/* ./ \
&& rm -rf ./staging
这很好,在Windows 10中仍然可以,但在CentOS 7中我得到:
Step 10/40 : RUN rm ./staging/src/myApp/*.csproj && cp -r ./staging/* ./ && rm -rf ./staging
---> Running in 6b17ae0fae89
cp: cannot stat './staging/src/myApp/myApp.csproj': No such file or directory
使用ls
而不是cp
会引发类似的文件未找到错误,因此Docker似乎仍然知道myApp.csproj
,但无法看到它,因为它已被删除
有办法解决这个问题吗?我尝试过使用rsync,但也遇到了类似的问题。我不知道具体如何解决这个问题,因为文件系统中有很多上下文您没有(可能无法)与我们共享 我对战略的建议是:
docker exec-it[image]bash
跳入图像我的猜测是,不知何故,linux机器由于某种原因没有预期的文件,因此它根本没有被复制到映像中,这就是docker构建过程找不到它的原因。但是,如果不调试构建过程,就无法知道。每当源是符号链接且链接的目标不存在时,cp-r将停止并失败,并显示
cannot stat
消息。它不会将链接复制到不存在的文件
所以我猜在运行COPY src/myApp//staging/src/myApp
之后,您的文件/staging/src/myApp/myApp.csproj
是指向不存在文件的符号链接。为什么下面的RUN rm./staging/src/*.csproj
没有删除它并且对此保持沉默,我不知道答案
为了帮助演示我的理论,请参见下面显示的Centos 7上符号链接的cp故障
[547] $ docker run --rm -it centos:7
Unable to find image 'centos:7' locally
7: Pulling from library/centos
524b0c1e57f8: Pull complete
Digest: sha256:e9ce0b76f29f942502facd849f3e468232492b259b9d9f076f71b392293f1582
Status: Downloaded newer image for centos:7
[root@a47b77cf2800 /]# ln -s /tmp/foo /tmp/bar
[root@a47b77cf2800 /]# ls -l /tmp/foo
ls: cannot access /tmp/foo: No such file or directory
[root@a47b77cf2800 /]# ls -l /tmp/bar
lrwxrwxrwx 1 root root 8 Jul 6 05:44 /tmp/bar -> /tmp/foo
[root@a47b77cf2800 /]# cp /tmp/foo /tmp/1
cp: cannot stat '/tmp/foo': No such file or directory
[root@a47b77cf2800 /]# cp /tmp/bar /tmp/2
cp: cannot stat '/tmp/bar': No such file or directory
请注意,您是如何复制无法统计符号链接的源或目标的报告的。这正是你所看到的症状
如果您只是想克服这个问题,可以尝试使用tar
而不是cp
或rsync
而不是
cp -r ./staging/* ./
改用这个:
tar -C ./staging -cf - . | tar -xf -
tar很乐意复制不存在的符号链接。我只是通过添加
忽略了这个问题;在有问题的行上退出0
。不太好,但是做得很好
编辑:这对我很有效,因为我无法升级CemtOS的版本。如果可以,请查看Alexander Block的答案。您很可能遇到了一个内核错误,该错误很久以前就在最近的内核中修复了。到目前为止,CentOS 7基于Linux内核3.10,该内核已经很旧了,并且在存储后端(覆盖文件系统)方面没有良好的Docker支持 CentOS试图将所需的补丁和功能向后移植到3.10中,但在覆盖支持方面似乎没有完全成功。在互联网上搜索“CentOS 7 overlay driver”时,您会发现与此相关的多个问题(略有不同)。它们都有一个共同点,即从父覆盖中删除文件并不能按预期工作 对我来说,似乎
rm
对文件的调用返回成功,即使文件没有完全删除。目录列表(例如,通过ls
或shell扩展,如您的情况)仍会列出文件,而访问文件则会失败(无论是读取、写入还是删除文件)
我想你所看到的只是这些问题的另一个化身。您应该切换到CentOS 8或升级您的内核(据我所知,CentOS并不正式支持)。或者更激进的做法是,切换到与Docker结合使用频率更高的发行版,通常提供更新的内核,例如Debian或Ubuntu。我曾尝试降级Docker
sudo yum降级Docker ce-
。我对您的Docker文件感到困惑。您将csproj恢复到容器上的/src/myApp
,然后使用staging目录中的内容覆盖其中的所有内容(csproj文件除外)。我读错了吗?一个很长的镜头,是吗?@timur,是的。我把它设置为允许,同样的错误。除非您的意思是在docker容器中?我打算建议您完全禁用它-我认为permissive
意味着SELinux仍然按照正常方式运行和分析您的策略。唯一的区别是它不强制执行任何操作,只记录评估结果(这仍然会导致它在后台检查您的文件)。说到你的观点,你是否应该在容器中禁用它-我不这么认为,因为它以前工作过。谢谢迈克,但这就是我正在做的。谢谢。给出了tar:./src/myApp/myApp.csproj:在我们阅读之前已删除的文件
。上一个rm
似乎太慢了。我现在只是猜测,但这听起来像是缓存问题,甚至可能与shell扩展有关。rm
正在删除cp
(和tar
)已经读取的文件。当他们开始的时候,它已经消失了。作为一个实验,现在尝试拆分&&
链,并将RUN
命令拆分为3个独立的RUN
命令。docker会将每次运行提交到它自己的层(不是最有效的),但它可能会突出一些东西,并为youThanks提供一些线索。同样的问题。此解决方案不能解决根本问题,而且在应用到更关键的地方时,实际上会导致将来的问题。幸运的是,在这种情况下,您没有后续问题,因为.csproj
文件之后就不再需要了。正确的解决方案是升级内核,如中所述。Ple