Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle Jib - Run as root user? #289

Closed
2020testuser opened this issue Apr 22, 2020 · 8 comments
Closed

Gradle Jib - Run as root user? #289

2020testuser opened this issue Apr 22, 2020 · 8 comments
Labels
kind/documentation Categorizes issue or PR as related to documentation. kind/question Issues or PRs that are questions around the project or a particular feature

Comments

@2020testuser
Copy link

Does Tekton Gradle Jib need to be run as user? I need to deploy the Jib Gradle built application in Kubernetes in its own Pod. So, if I run the Gradle build task as root -user, when I deploy using Tekton Pipeline in Kubernetes, because of enabled Pod RBAC, my deployment will fail.

Could anyone please provide more insight on this? Is using a ServiceAccount solve the issue?

Also, to push to the organization's docker registry, does any additional setting needed in gradle/jib properties/config file?
Any info. would be greatly helpful.

Thanks!

@2020testuser
Copy link
Author

Could someone reply to the above please ? (if you have the info.)Thanks!

@ghost ghost added kind/documentation Categorizes issue or PR as related to documentation. kind/question Issues or PRs that are questions around the project or a particular feature labels Apr 27, 2020
@vdemeester
Copy link
Member

Didn't dig too deep but #214. On OpenShift, jib had to be root to run, but I think it's something related to gradle and $HOME (and where gradle stores stuff)

@chanseokoh
Copy link
Contributor

chanseokoh commented Apr 29, 2020

but I think it's something related to gradle and $HOME (and where gradle stores stuff)

Correct.

Note that the root cause of the issue #214 is from Gradle, not Jib. Running Gradle (even without Jib) does need to write some Gradle stuff (like Java JAR artifacts downloaded for caching), but the directory at /tekton/home (hence /tekton/home/.gradle, for example) supplied by Tekton cannot be written by a non-root user.

BTW, I know there's a plan to remove /tekton/home. That and knowing that newer Jib versions search more places for Docker configs and also can use $DOCKER_CONFIG, I wonder if if there would be a way to lift the runAsUser: 0 restriction. (The main reason we changed $HOME and the Gradle home was to enable Jib read /tekton/home/.docker/config.json.)

Refs:

@2020testuser
Copy link
Author

Thanks Much for the explanation.Getting to understand the original cause of the issue. Could you please let me know whether the below would solve the problem for now?

  1. How about using a ServiceAccount for my PipelineRun and that ServiceAccount will have access to the Persistent Volume Claim used by the PipelineRun. Came across use of Service Account in one of the issue posts.

Since, the volume used by the Task cannot be used in 'write' mode by the non-root user (to store cache data, logs etc.), the TaskRun fails. I'm using Docker Hub's gradle 4.6 image (and included the Jib plugin setup as part of my project's build.gradle file) and not using Google Tool's Gradle Jib Image (used in the Jib Gradle example in Tekton Catalog ) as I'm using old version of Gradle (4.6) and Jib.

Thanks!

=================================================================

BTW, I know there's a plan to remove /tekton/home. That and knowing that newer Jib versions search more places for Docker configs and also can use $DOCKER_CONFIG, I wonder if if there would be a way to lift the runAsUser: 0 restriction. (The main reason we changed $HOME and the Gradle home was to enable Jib read /tekton/home/.docker/config.json.)

@chanseokoh
Copy link
Contributor

chanseokoh commented Apr 30, 2020

Before I explain other things, I think this is what's happening to you.

  1. Your gradle:4.6 Tekton Task probably runs as user 1000:1000 (assuming you didn't use runAsUser in a Tekton Task spec to override it as a different user), because the official image gradle:4.6 itself is configured to run it that way.
  2. When you run gradle, it needs to create a "Gradle User Home" directory (usually $HOME/.gradle). (BTW, Tekton is making changes to what it means by $HOME recently, so I think it will be a bit unreliable to depend on $HOME.) In any case, obviously, it cannot create this directory with the user 1000:1000. If it cannot, you'll get the Cannot load 'libnative-platform.so' error. But I think you already resolved this error one way or another, knowing that you hit the next error below.
  3. Also, gradle needs to create directories inside a project source (e.g., /workspace/app/service in your case). But it looks like your project source is not writable by 1000:1000. So you'll get an error like Failed to create parent directory '/workspace/app/service/.gradle' when creating directory.

I'm not a Tekton expert, but from my recent experiments, I think there are a few options for these issues on Tekton.

For 2), you can change the "Gradle User Home" with the flag -g (or --gradle-user-home). So, maybe you could do gradle --gradle-user-home=/workspace/.gradle (I think /workspace is globally writable), use /tmp (I don't think this is a good idea), or use a directory where you mount a volume (whether a persistent volume claim or emptyDir). AFAIK, volumes mounted on Tekton is globally writable. Just remember if you allow mounting a persistent volume, all the stuff Gradle writes into the "Gradle User Home" will be persisted; maybe that's actually what you want to boost Gradle build performance (i.e., caching Gradle stuff).

For 3), I guess you are probably getting project source from a remote git repo. What I learned is that, if you set runAsUser in a TaskRun spec (note, not Task spec but TaskRun), the source project directory will be owned by that user. So, I think you should set runAsUser: 1000 and runAsGroup: 1000 in a TaskRun spec, because your gradle:4.6 image will run as 1000:1000. Perhaps it's also safe to set runAsUser and runAsGroup in a Task too, to make sure the image runs as 1000:1000.

So, in sum, try these

  • Set runAsUser: 1000 and runAsGroup: 1000 in TaskRun to make the source directory owned by 1000:1000. (Perhaps also set them in Task to ensure gradle:4.6 run as 1000:1000.)
  • Use --gradle-user-home to set a writable directory. (A persistent volume sounds like a good idea for caching. A volume should be globally writable; at least this was the case in my testing.) For initial testing, /tmp or /workspace may work. (Note you probably want --gradle-user-home=/workspace/.gradle.)

Lastly, I don't really get the real connection between using a ServiceAccount and permissions of a mounted volume. In my testing with Tekton, whatever volumes I mount is always globally writable. For initial testing, you can first try an emptyDir volume, which doesn't need any volume configuration. (FYI, an emptyDir volume is not persistent, but its contents survives across multiple Task steps.)

@2020testuser
Copy link
Author

Every time I read your explanation , I'm learning something new . Thanks Much! I'm using PersistentVolumeClaim now. Will try the above and do testing . Will keep posted on the findings. Thanks again!

@chanseokoh
Copy link
Contributor

chanseokoh commented Apr 30, 2020

Great. And, actually, just realized it should be --gradle-user-home=/workspace/.gradle instead of just /workspace. (--gradle-user-home=/workspace can still technically work, but it's probably not what you want.)

@2020testuser
Copy link
Author

Finally, I was able to get it working. Appreciate all your inputs. Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/documentation Categorizes issue or PR as related to documentation. kind/question Issues or PRs that are questions around the project or a particular feature
Projects
None yet
Development

No branches or pull requests

3 participants