-
Notifications
You must be signed in to change notification settings - Fork 245
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
Add experimental volumes and volumeMounts properties to jobs #966
Conversation
Signed-off-by: Radu M <[email protected]>
Signed-off-by: Radu M <[email protected]>
brigade-worker/src/k8s.ts
Outdated
if (cfg.volume.hostPath != undefined && !project.allowHostMounts) { | ||
throw new Error(`allowHostMounts is false in this project, not mounting path ${cfg.volume.hostPath.path}`) | ||
} | ||
this.runner.spec.volumes.push(cfg.volume); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any scenario where you would need to mount the same volume twice in a single job pod?
The only scenario I can think of is mounting to different paths, although it doesn't seem to be that common - see kubernetes/kubernetes#34453.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have never got to do it myself. But I see some use with subpath, as mentioned in the issue.
Just curious, but does whether to support mounting the same volume multiple times affect our design/implementation? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I got it! You've paired a volume and its corresponding mount in each volumeConfig.
I'd rather suggest exposing volumes
and volumeMounts
without any abstraction first, so that we can provide a standard library feature like this volumeConfig
on top of that, or users can build their own.
IMHO for the standard library, something that solves 80% of the use-cases will be enough, that justifies dropping support for mounting the same volume multiple times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading radu-matei/brigadier@94f56c2 - If you agree, implementation-wise, I think adding volumeMounts
and volumes
that are allowed/used only when volumeConfig
doesn't exist would suffice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That totally makes sense - I initially thought maybe we could simplify and boil things down to a single property, but yeah, you're right, we should keep in line with the Kubernetes abstraction.
Updating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I like the idea of pairing volumes and mounts.
I even think we can happily merge the volume and the mount as in many cases each volume is mounted only once:
job.volumeConfig = [
{
name: "modules",
mountPath: "/lib/modules",
readOnly: true,
hostPath: {
path: "/lib/modules",
type: "Directory"
}
},
{
name: "cgroup",
mountPath: "/sys/fs/cgroup",
hostPath: {
path: "/sys/fs/cgroup",
type: "Directory"
}
},
{
name: "docker-graph-storage",
mountPath: "/var/lib/docker",
emptyDir: {}
}
]
And I believe name
s can be usually omitted because they can be generated from mount-path(which are guaranteed to not collide:
job.volumeConfig = [
{
// name: "lib-modules",
mountPath: "/lib/modules",
readOnly: true,
hostPath: {
path: "/lib/modules",
type: "Directory"
}
},
{
// name: "sys-fs-cgroup",
mountPath: "/sys/fs/cgroup",
hostPath: {
path: "/sys/fs/cgroup",
type: "Directory"
}
},
{
// name: "var-lib-docker",
mountPath: "/var/lib/docker",
emptyDir: {}
}
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually don't think we should keep both volume + volumeMounts and volumeConfig, as it just invites confusion - what do you think?
So I'd vote for starting with only volumes
+ volumeMounts
if I need to choose one.
// But I do believe something like volumeConfig
has a lot of potential, and worth it, even if it needs an extensive documentation to not confuse users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I initially thought that something like volumeConfig
could be an abstraction over how volumes and volume mounts work in Kubernetes and simplify setting them up for a job.
But I agree, let's start with plain volumes
and volumeMounts
, then decide whether to add a higher level abstraction, how you suggested.
Thanks a lot, this has been really helpful!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Brigadier change: brigadecore/brigadier@8c53a1c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated - could you please give this another look?
Thanks!
Deploy preview for brigade-docs ready! Built with commit ef8e1a7 |
Signed-off-by: Radu M <[email protected]>
Signed-off-by: Radu M <[email protected]>
brigade-worker/package.json
Outdated
@@ -38,7 +38,7 @@ | |||
"typescript": "^3.2.2" | |||
}, | |||
"dependencies": { | |||
"@brigadecore/brigadier": "^0.5.0", | |||
"@brigadecore/brigadier": "radu-matei/brigadier#job-volume-config-out", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After brigadecore/brigadier#22 is merged and a new version is published, update this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had one question as well as the request to add an example around a basic configuration somewhere in the docs. Otherwise, looks great!
} | ||
|
||
// If the job defines volume mounts, add them to every container's spec. | ||
for (let m of job.volumeMounts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since volumeMounts
and volumes
appear to be un-coupled, should we add the same check here to be sure project.allowHostMounts
is true?
And/or, in general, should we somehow check for proper API usage? (If, say, configured with a volumeMount setup but no corresponding volume defined, etc. -- or is that allowed?) I suppose as long as we can show the user the k8s library error that should result on mis-configuration, we'd be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you need to declare both volume and volume mount, I think checking is unnecessary - it would end up just taking the volume mount name and iterating through the volumes to check if it's mounting a host path - which already do for all volumes.
As for checking the existence of the volume you reference in the volume mount, that is a good idea, I'll add that.
These two checks should cover both of your questions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a check for the referenced volume, together with a test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed radumatei/brigade-worker:volume-mounts-check
if you need to try it on a project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the extra validation with volumeExists
because that provides us a faster feedback loop 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect, thanks Radu!
Signed-off-by: Radu M <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I believe we can merge this once brigadecore/brigadier#22 gets merged/published.
Merged brigadecore/brigadier#22, rebasing, updating, and adding a doc. |
Do we imagine being able to one day orchestrate job containers using something other than Kubernetes? It wasn't on my radar, but even if the answer were yes, I think this could be accommodated with other orchestrators. |
Signed-off-by: Radu M <[email protected]>
Rebased and added a simple doc. @krancour - not really, or at least not the JS worker anyway. Just trying to make sure we're not overlooking something that might be affected by this - thanks! |
Thanks a lot for the help, everyone! |
depends on brigadecore/brigadier#22
This PR enables experimental support for adding volumes and volume mounts to jobs.
Note that for the simple use case of sharing a volume across all jobs,
storage.enabled
should still be used.A pre-built image for the worker:
radumatei/brigade-worker:volume-mounts-check
.cc @krancour - this is a very Kubernetes-specific addition - how would this impact non-Kubernetes targets?
Use cases: #955 (comment) and Mounting volumes for ETL jobs
Example: