【问题标题】:permission denied, mkdir in container on openshift权限被拒绝,openshift 上容器中的 mkdir
【发布时间】:2021-12-07 22:33:18
【问题描述】:

我有一个带有 nodejs 和 pm2 作为启动命令的容器,在 OpenShift 上我在启动时收到此错误:

错误:EACCES:权限被拒绝,mkdir '/.pm2'

我在马拉松主持人上尝试了相同的图像,效果很好。

我需要用 UserIds 改变一些东西吗?

Dockerfile:

FROM node:7.4-alpine

RUN npm install --global yarn pm2

RUN mkdir /src

COPY . /src

WORKDIR /src

RUN yarn install --production

EXPOSE 8100

CMD ["pm2-docker", "start", "--auto-exit", "--env", "production", "process.yml"]

更新
节点映像已经创建了一个 UID 为 1000 的新用户“节点”,以不以 root 身份运行该映像。
我还尝试修复权限并将用户“节点”添加到根组。
此外,我告诉 pm2 它应该与 ENV var 一起使用哪个目录:

PM2_HOME=/home/node/app/.pm2

但我仍然得到错误:

Error: EACCES: permission denied, mkdir '/home/node/app/.pm2'

更新的 Dockerfile:

FROM node:7.4-alpine

RUN npm install --global yarn pm2

RUN adduser node root
COPY . /home/node/app
WORKDIR /home/node/app
RUN chmod -R 755 /home/node/app
RUN chown -R node:node /home/node/app

RUN yarn install --production

EXPOSE 8100

USER 1000

CMD ["pm2-docker", "start", "--auto-exit", "--env", "production", "process.yml"]

更新2 感谢 Graham Dumpleton,我得到了它的工作

FROM node:7.4-alpine

RUN npm install --global yarn pm2

RUN adduser node root
COPY . /home/node/app
WORKDIR /home/node/app

RUN yarn install --production

RUN chmod -R 775 /home/node/app
RUN chown -R node:root /home/node/app

EXPOSE 8100

USER 1000

CMD ["pm2-docker", "start", "--auto-exit", "--env", "production", "process.yml"]

【问题讨论】:

  • 哪条 RUN 行给你这个错误?编辑:抱歉,运行容器时会发生这种情况......
  • 看起来 pm2-docker 正在忽略当前工作目录。此外,通过检查映像历史记录(我找不到 7.4 的 Dockerfile),看起来预期的工作目录是 /home/node。可能 pm2-docker (从未使用过)也希望这是工作目录。您可以尝试更改 COPY 和 WORKDIR 以使源位于 /home/node 内吗?
  • Dockerfile 应该是这样的:github.com/nodejs/docker-node/blob/…
  • 其实我想知道我是否需要pm2,当节点进程崩溃时容器不是自动重启吗?
  • 您是哪个内核版本,您在守护进程中使用哪个存储驱动程序?您可能会遇到关于权限和旧内核的覆盖驱动程序的已知问题。

标签: node.js docker openshift pm2


【解决方案1】:

默认情况下,OpenShift 将以非 root 用户身份运行容器。因此,如果您的应用程序需要以 root 身份运行,它可能会失败。是否可以将容器配置为以 root 身份运行将取决于您在集群中拥有的权限。

最好设计您的容器和应用程序,使其不必以 root 身份运行。

一些建议。

  • Dockerfile 的 USER 语句中创建一个特殊的 UNIX 用户来运行应用程序并设置该用户(使用其 uid)。将用户所在的组设为根组。

  • 修复/src 目录及其下由特殊用户拥有的所有内容的权限。确保一切都是组根。确保任何需要可写的内容都可写入到 root 组。

  • 确保在Dockerfile 中将HOME 设置为/src

完成后,当 OpenShift 将容器作为分配的 uid 运行时,其中 group 是 root,然后由于所有内容都是组可写的,应用程序仍然可以更新 /src 下的文件。设置的HOME 变量确保通过代码写入主目录的任何内容都进入可写/src 区域。

【讨论】:

  • 我尝试使用您的所有建议,但仍然失败,请参阅更新的问题
  • 除非你没有完全正确。 chmod 应该是 775,chown 应该是 node:root。并在所有其他命令运行后执行此操作,因此在yarn install 之后,以防它正在写入 workdir。
  • @GrahamDumpleton:用户(在本例中为node)是否需要也存在于主机上,或者只是在 Dockerfile 中指定?
  • node 用户需要存在于容器镜像中的/etc/passwd 中。它不需要存在于底层 OpenShift 节点主机上。
  • 第一步,Create a special UNIX user to run the application as and set that user (using its uid), in the USER statement of the Dockerfile.,毫无意义。 Openshift 不允许自定义用户,除非您深入他们的设置来更改它。也就是说,授予 DockerImages 的所有用户都在组根目录内,所以这些指令仍然可以正常工作。
【解决方案2】:

您还可以运行以下命令,授予您登录项目的 root 访问权限:

oc adm policy add-scc-to-user anyuid -z default

【讨论】:

    【解决方案3】:

    Graham Dumpleton 的解决方案有效,但不推荐。

    Openshift,在运行容器时将使用随机 UID。

    您可以在 Pod 生成的 Yaml 中看到。

    spec:
        - resources:
          securityContext:
            runAsUser: 1005120000
    

    您应该改为应用 Docker 安全最佳实践来编写您的 Dockerfile。

    1. 不要将应用程序的执行绑定到特定的 UID:使资源在世界范围内可读(即 0644 而不是 0640)并在需要时可执行。

    2. 使可执行文件归根用户所有且不可写

    有关推荐的完整列表,请参阅:https://sysdig.com/blog/dockerfile-best-practices/

    在你的情况下,不需要:

    RUN adduser node root
    ...
    RUN chown -R node:node /home/node/app
    USER 1000
    

    在原始问题中,应用程序文件已归 root 所有。
    以下 chmod 足以使它们对全世界都具有可读性和可执行性。

    RUN chmod -R 775 /home/node/app
    

    【讨论】:

      【解决方案4】:

      您使用的是哪种 openshift?

      您可以编辑“受限”安全上下文约束:

      来自 openshift CLI:

      oc edit scc restricted 
      

      然后改变:

      runAsUser:
        type: RunAsUSer
      

      runAsUser:
        type: RunAsAny
      

      请注意,格雷厄姆·邓普顿的回答是正确的

      【讨论】:

        猜你喜欢
        • 2011-06-25
        • 2016-08-24
        • 2013-07-01
        • 2012-08-13
        • 1970-01-01
        • 2023-03-22
        • 2018-03-19
        相关资源
        最近更新 更多