为什么容器外的目录层次结构的 docker cp 失败且权限被拒绝?

问题描述 投票:0回答:3

背景:

这个 docker cp out from 容器失败的行为有点古怪,所以我认为应该记录下来。我找不到匹配的问题或 docker 问题,但我可以看到聊天/评论,我认为这表明人们正在遇到这个问题。

我有一个 docker 映像,在创建映像时我会打包映像中的一些目录。当容器第一次启动时,目录将从容器中复制出来并用于初始化目录,然后将该目录安装为容器的 docker 卷。

问题:

我所看到的是,根据图像的构建方式,有时在执行目录的部分副本后,目录外的 docker cp 会失败,并显示 “open

/ 权限被拒绝”

我发现当开发人员在本地构建图像时,它工作正常。我看到当从已发布的模块构建图像时它失败了。

以 root 身份在目录外执行 docker cp 工作正常。

以普通用户身份在目录外执行 docker cp 不起作用。该目录已创建,但为空。

目录权限(奇怪的是源目录)是问题的原因

这有点明显,但也不明显;顶层目录可以正常创建,因此无论源目录的权限是什么,您都会期望完整目录层次结构的递归副本能够工作。

在源代码管理目录所有权内设置了写权限。当模块被释放时,写入权限被删除。因此,解决方案是在使用已发布的模块进行构建时,必须重新添加写入权限。

drwxr-xr-x dev/dev         buildarea/.../jenkins/
drwxr-xr-x dev/dev         buildarea/.../jenkins/email-templates/

dr-xr-xr-x root/root         /releasearea/.../jenkins/
dr-xr-xr-x root/root         /releasearea/.../jenkins/email-templates/

我在 2017 年 7 月的容器中使用 docker 17.03.1 centos cp 看到了这一点。

答案:

因为,有点奇怪,source目录(即在容器中)不可写。

说明:

简单地说:

docker cp
在复制不可写目录时保留权限。因此,当它尝试将第一个文件复制到目标目录时会失败。

如果您使用

docker cp
以非 root 用户身份复制目录,并且未在层次结构中的目录(包含文件)上设置写权限,那么它将失败。
docker cp
命令将复制目录和文件,直到创建一个不可写的目录。当它尝试将第一个文件复制到该不可写目录时,它会失败并显示类似以下消息:

Copying unlinkat <dir-which-is-not-writable>/<file>: permission denied
.

解决方案:

在需要使用

docker cp
(作为非 root 用户)从容器中复制的 docker 映像中创建目录时,请确保在每个(非空)目录上设置顶级可写权限。

例如,在

Dockerfile
中,您可以添加
RUN find -type d -exec chmod u+w {} +
。对于现有容器,您可以简单地从容器内运行相同的
find
命令。

相关问题:https://github.com/moby/moby/issues/3986#issuecomment-316966200

正如已经提到的,目录权限是首先要检查的事情。特别是,如果正在访问的文件夹设置了正确的权限是不够的 - 其父文件夹(直到您的主目录)至少需要具有“列出目录”权限。另请参阅我的回答这里 但是,什么解决了

的问题

cp:无法打开“/directory/./file”:权限被拒绝

在我的例子中是
Windows EFS(加密文件系统)

。确保源中的文件或文件夹没有基于文件系统进行加密。 Docker 尝试从 Linux 访问文件系统,并且与 Windows 不同,在读取时不会透明地解密文件。 可以通过右键单击文件/文件夹,然后

属性

> 常规选项卡 > 高级按钮 > 加密内容以保护数据来切换加密。

处理此问题的一种巧妙方法是提升本地计算机上的文件权限,然后将其复制到容器中。

chmod 777 source_file.txt # <-- this is unsafe (change to a better set of permissions) docker cp source_file.txt <container>:/path/to/file.txt

您的容器现在可以以 root 或非 root 用户身份运行该文件。

docker permissions
3个回答
7
投票

答案:

因为,有点奇怪,source目录(即在容器中)不可写。

说明:

简单地说:

docker cp
在复制不可写目录时保留权限。因此,当它尝试将第一个文件复制到目标目录时会失败。

如果您使用

docker cp
以非 root 用户身份复制目录,并且未在层次结构中的目录(包含文件)上设置写权限,那么它将失败。
docker cp
命令将复制目录和文件,直到创建一个不可写的目录。当它尝试将第一个文件复制到该不可写目录时,它会失败并显示类似以下消息:

Copying unlinkat <dir-which-is-not-writable>/<file>: permission denied
.

解决方案:

在需要使用

docker cp
(作为非 root 用户)从容器中复制的 docker 映像中创建目录时,请确保在每个(非空)目录上设置顶级可写权限。

例如,在

Dockerfile
中,您可以添加
RUN find -type d -exec chmod u+w {} +
。对于现有容器,您可以简单地从容器内运行相同的
find
命令。

相关问题:https://github.com/moby/moby/issues/3986#issuecomment-316966200


0
投票

正如已经提到的,目录权限是首先要检查的事情。特别是,如果正在访问的文件夹设置了正确的权限是不够的 - 其父文件夹(直到您的主目录)至少需要具有“列出目录”权限。另请参阅我的回答这里 但是,什么解决了

的问题

cp:无法打开“/directory/./file”:权限被拒绝

在我的例子中是
Windows EFS(加密文件系统)

。确保源中的文件或文件夹没有基于文件系统进行加密。 Docker 尝试从 Linux 访问文件系统,并且与 Windows 不同,在读取时不会透明地解密文件。 可以通过右键单击文件/文件夹,然后

属性

> 常规选项卡 > 高级按钮 > 加密内容以保护数据来切换加密。


0
投票

chmod 777 source_file.txt # <-- this is unsafe (change to a better set of permissions) docker cp source_file.txt <container>:/path/to/file.txt

您的容器现在可以以 root 或非 root 用户身份运行该文件。

© www.soinside.com 2019 - 2024. All rights reserved.