【问题标题】:How to let dockerd create bind volume dirs with the correct permission如何让 dockerd 创建具有正确权限的绑定卷目录
【发布时间】:2018-05-11 19:50:03
【问题描述】:

当我使用以下命令运行 docker 容器时:

docker run -ti -v /tmp/michael:/opt/jboss/wildfly/standalone/log jboss

dockerd 使用所有者和组 = root 创建目录 /tmp/michael。这当然会导致 jboss 在尝试写入其日志文件时出现权限被拒绝错误。

我必须手动创建 /tmp/michael 并授予 chmod g+w 权限来修复它。 dockerd 然后以正确的权限重用现有的目录。这不是我想要的。有谁知道如何强制 dockerd 以正确的权限创建这些目录

附加信息:

Docker 文件:

FROM jboss/wildfly
ADD entrypoint.sh /
ENTRYPOINT "/entrypoint.sh"

entrypoint.sh :(为了测试目的,只需触摸文件而不是启动 jboss)

#!/usr/bin/env bash
chown jboss:jboss /opt/jboss/wildfly/standalone/log
myfile=lala.`date +"%s"`
touch /opt/jboss/wildfly/standalone/log/${myfile}

但即使在这里,如果 /tmp/michael 不存在并且没有组 +w 我确实收到权限被拒绝。我不知道如何摆脱它

【问题讨论】:

  • 您需要直接访问主机上的文件,还是只需要在容器实例之间持久化文件?
  • 我需要从主机直接访问这些文件。

标签: docker wildfly


【解决方案1】:

你有两种可能:

  1. chown 在 ENTRYPOINT 的某处(为入口点创建一个 .sh)(以便从容器内部实现这一点)

    类似chown jboss:jboss /opt/jboss/wildfly/standalone/log

  2. 直接在容器外(宿主机内)更改权限

    您不会有jboss 用户或组,您需要直接使用de id。 查看容器 /etc/passwd 并获取 jboss 用户 id (docker exec jboss cat /etc/passwd),记下 id 并在主机中创建 chown

    chown 1001:1001 /tmp/michael

当然,最好的方法是 1。您可以为其使用 docker 卷等。最简单的方法是 2。

【讨论】:

  • 我个人的偏好是选项 1,让入口点进行这种初始化,因为它使图像更便携。 +1
  • 为了测试我有一个简单的 dockerfile FROM jboss/wildfly ADD entrypoint.sh / ENTRYPOINT "/entrypoint.sh" entryfile.sh 是 #!/usr/bin/env bash chown jboss:jboss /opt/jboss/wildfly/standalone/log myfile=lala.`date +"%s"` touch /opt/jboss/wildfly/standalone/log/${myfile} 但即使在这里,如果 /tmp/michael 不存在并且没有组 +w 我确实收到权限被拒绝。
  • 我能够在我的 CMD 中 chown jboss:jboss,因为我的图像不是基于 jboss/wildfly。但是,这种方法对于基于 wildfly 的图像是不可能的。所以我很幸运....但在这种情况下,BMitch 第三种方法可能是一种选择
  • 我有一个示例 repo,其中包含一系列使用入口点修复权限的步骤。我正在使容器与主机匹配,而不是像您正在做的那样相反。您看到的问题是您的入口点没有以 root 身份运行。 github.com/bmitch3020/jenkins-docker
【解决方案2】:

除了 Alfonso 的回答之外,还有第三个选项可以使用命名卷来初始化目录。您需要首先在图像中创建具有正确权限的目录。例如。您的 Dockerfile 可能包含以下行:

RUN mkdir -p /opt/jboss/wildfly/standalone/log \
 && chmod 775 /opt/jboss/wildfly/standalone/log

然后你可以在你的主机上提前创建命名卷:

docker volume create --driver local \
  --opt type=none \
  --opt device=/tmp/michael \
  --opt o=bind \
  jboss_logs

最后使用该命名卷运行您的容器:

docker run -ti -v jboss_logs:/opt/jboss/wildfly/standalone/log jboss

只要/tmp/michael存在但为空,就会在容器启动前用你的镜像内容初始化,包括文件和目录权限。

【讨论】:

  • 问题是 /tmp/michael 在 docker run 命令之前不存在。我目前正在尝试那个入口点东西我
  • 只要 /tmp/michael 存在,您的提案就非常有效
猜你喜欢
  • 2012-04-26
  • 2012-01-17
  • 2017-07-10
  • 2018-02-09
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 2018-11-20
  • 2015-06-13
相关资源
最近更新 更多