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!!
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)
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