Gradle as non root

4/28/2020

Could you please let me know how to run a gradle image (pulled from docker repository), with jib plugin and running as non-root user in Kubernetes pod?

I have build a gradle image using Gradle 4.6.

I’m using this image in my Kubernetes pod.

When I run the image as user - root, the gradle build is successful.

When I run the image as non-root user (because of pod RBAC enablement), the build fails as gradle is unable to create /.gradle directory and there are no sufficient privileges and getting the below error.

Failed to load native library 'libnative-platform.so' for Linux amd64.

Is there any way to grant the non-root user passed via securityContext to perform the build successfully using the gradle image?

Is there a better way to resolve the issue without changing the directory permission to 777 .

Thanks in advance!!

-- testbg testbg
gradle
jib
kubernetes
kubernetes-security

2 Answers

4/28/2020

I believe you are talking about the official Gradle image on Docker Hub.

The gradle:4.6 image is designed and meant to be run as user 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)

Therefore, it only works when running the image as user root (UID 0) or 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

Therefore, you just need to make sure that you run the container as user 1000 or gradle (on whatever container runtime environment you use). And because the image gradle:4.6 is configured to run as 1000, when you build a new image based on gradle:4.6, it should run OK on almost all container runtime platforms (unless you override the configured user at the platform level).


(Now, the following assumes that you are using Jib to build another Gradle-like image based on gradle:4.6 and that you are using this new Gradle-like image on Kubernetes. That is, the following doesn't apply if you are using Jib to containerize a normal application image inside gradle:4.6.)

However, there is a bug in Jib that does not inherit the configured user from the base image. The bug will be fixed in the next 2.3.0 release. In the meantime, you can explicitly tell Jib to configure the user in the built image. In build.gradle, set

jib.container.user = 'gradle:gradle'

or if you prefer numeric UID and GID,

jib.container.user = '1000:1000'

. Or you can set the system property on the command-line:

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

Another option is to set the correct user on the Kubernetes side. For example, within securityContext, you can set runAsUser: 1000 and runAsGroup: 1000.

Finally, although gradle:4.6 is built to run as user gradle (UID 1000), I see that recently they have reverted this decision. Now gradle:latest is configured to run as root.

$ docker run --rm --entrypoint id gradle
uid=0(root) gid=0(root) groups=0(root)
-- Chanseok Oh
Source: StackOverflow

4/28/2020

Most likely the reason is that the /.gradle directory is already created by root

So, if you check the owner using stat command.

You'll see that current user doesn't have enough permissions to work with it:

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

If so, change owner of the directory:

$ sudo chown -R $USER ~/.gradle

Where

  • -R means recursive owner update
  • $USER contains current username
-- Yasen
Source: StackOverflow