【问题标题】:Gradle as non rootGradle 作为非 root
【发布时间】:2020-08-12 12:58:58
【问题描述】:

您能否告诉我如何运行gradle 图像(从docker 存储库中提取),使用jib 插件并在Kubernetes pod 中以非root 用户身份运行?

我已经使用Gradle 4.6 构建了一个gradle 图像。

我在我的Kubernetes pod 中使用了这张图片。

当我以用户 root 运行映像时,gradle 构建成功。

当我以非root 用户身份运行映像时(由于启用了pod RBAC),构建失败,因为gradle 无法创建/.gradle 目录并且没有足够的权限并出现以下错误.

无法为 Linux amd64 加载本机库“libnative-platform.so”。

有没有办法让通过securityContext 传递的非root 用户使用gradle 图像成功执行构建?

在不将目录权限更改为 777 的情况下,有没有更好的方法来解决问题。

提前致谢!!

【问题讨论】:

    标签: gradle kubernetes kubernetes-security jib


    【解决方案1】:

    最可能的原因是/.gradle 目录已经由root 创建

    因此,如果您使用stat 命令检查所有者。

    您会看到当前用户没有足够的权限使用它:

    $ stat ~/.gradle | grep Uid
    > Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
    

    如果是,请更改目录的所有者:

    $ sudo chown -R $USER ~/.gradle
    

    在哪里

    • -R 表示递归所有者更新
    • $USER 包含当前用户名

    【讨论】:

    • 谢谢!您能否让我知道是否还有其他更好的选择无法更改 gradle 图像?此外,我希望任何非 root 用户都可以运行 pod。
    • 如果您在清除主机上或与其他用户(还没有.gradle 目录)一起运行图像 - 它会正常运行,没有问题。 gradle 是在用户模式下设计的,非root 模式
    • 另外,您可以尝试删除.gradle 目录并重试。
    • 谢谢!从我的本地机器运行命令时,我无权访问主机。有什么办法可以删除 .gradle 目录。另外,因为我的 gradle 命令中有 --rerun-tasks ,它不会从头开始吗?否则,我可以更改安装位置。如果您知道任何更好的选择,请告诉我。谢谢!
    【解决方案2】:

    我相信你说的是Docker Hub上的官方Gradle镜像。

    gradle:4.6 映像旨在以用户 gradle (UID 1000) 的身份运行。

    $ docker inspect gradle:4.6 --format '{{.Config.User}}'
    gradle
    $ docker run --rm --entrypoint id gradle:4.6
    uid=1000(gradle) gid=1000(gradle) groups=1000(gradle)
    

    因此,它仅在以用户 root (UID 0) 或 gradle (UID 1000) 身份运行图像时有效。

    # These all work.
    $ docker run --rm --user 0 gradle:4.6
    $ docker run --rm --user root gradle:4.6
    $ docker run --rm --user 1000 gradle:4.6
    $ docker run --rm --user gradle gradle:4.6
    
    # However, this doesn't work.
    $ docker run --rm --user 1234 gradle:4.6
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Failed to load native library 'libnative-platform.so' for Linux amd64.
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    

    因此,您只需确保以用户 1000gradle 的身份运行容器(在您使用的任何容器运行时环境中)。并且由于镜像gradle:4.6被配置为以1000运行,当你基于gradle:4.6构建一个新镜像时,它应该在几乎所有容器运行时平台上运行正常(除非你在平台级别覆盖配置的用户) .


    (现在,以下假设您正在使用 Jib 基于 gradle:4.6 构建另一个类似 Gradle 的镜像,并且您正在 Kubernetes 上使用这个新的类似 Gradle 的镜像。也就是说,以下内容不适用您正在使用 Jib 在 gradle:4.6 中容器化一个普通的应用程序映像。)

    但是,有一个bug in Jib 不会从基本映像继承配置的用户。该错误将在下一个 2.3.0 版本中修复。同时,您可以明确告诉 Jib 在构建的映像中配置用户。在build.gradle,设置

    jib.container.user = 'gradle:gradle'
    

    或者如果您更喜欢数字 UID 和 GID,

    jib.container.user = '1000:1000'
    

    。或者你可以在命令行设置系统属性:

    ./gradlew -Djib.container.user='gradle:gradle' ... jib
    

    另一个选项是在 Kubernetes 端设置正确的用户。例如securityContext内,可以设置runAsUser: 1000 and runAsGroup: 1000

    最后,虽然gradle:4.6 被构建为以用户gradle (UID 1000) 的身份运行,但我看到他们最近恢复了这个决定。现在gradle:latest 被配置为以root 运行。

    $ docker run --rm --entrypoint id gradle
    uid=0(root) gid=0(root) groups=0(root)
    

    【讨论】:

    • 非常感谢您的详细解释!我尝试在我的 Kubernetes SecurityContext 中使用用户 -1000 并没有帮助。原因是我正在安装一个项目卷以从我的 Git 存储库中复制项目并运行 gradle(jib) 映像。由于此卷挂载是在创建 Container 之前设置的,因此我的 /project (挂载目录)的权限为 755 。 User-root 拥有完全权限,并且在 user-root 下一切正常。我正在尝试使用 InitContainer 并将 /project 权限更改为 775 并以用户身份运行 - 1000。如果有更好的解决方案,请告诉我。
    • 嗨 Chanseok,我在 Kubernetes Pod 中尝试了 securityContext: runAsUser: 1000 和 runAsGroup: 1000 并且还在 gradle 命令中将用户设置为 1000(并且还尝试了 user - gradle) pod 使用 Gradle 4.6 映像(来自 docker hub 和在 build.gradle 文件中初始化的 jib 插件),构建失败。但是,当我使用 securityContext: runAsUser: 0 时,构建成功。请问这是否是 gradle 4.6 和 Jib 4.0.4 中的错误?另外,你能告诉我这个问题是否有任何解决方法吗?你的帮助会很有用。谢谢!
    • @testbgtestbg 好像我误解了你的环境。见github.com/GoogleContainerTools/jib/issues/…
    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2016-06-19
    • 2017-11-11
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多