-
Notifications
You must be signed in to change notification settings - Fork 802
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
[Part 7 of #758] Added singleuser.tolerations
, for node taints
#925
Conversation
5ea6df9
to
7d64171
Compare
{{- $dummy := include "jupyterhub.prepareScope" $_ }} | ||
{{- if $_.hasTolerations }} | ||
{{- include "jupyterhub.tolerations" $_ | nindent 6 }} | ||
{{- end }} |
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.
prepareScope prepopulates $_ with various stuff, and then the jupyterhub.tolerations
template utilizes that. The $_ will be reused by a future jupyterhub.affinity
template so it makes sense to prepare the scope once instead of twice.
I think we need to be careful with these helpers. I am finding that they are making it harder to understand and work on the chart. I genuinely can't tell what tolerations are being added to the 'core' pods in this PR, which have all this extra labelling and prepareScope logic. What are the resulting tolerations on each pod? In particular, I'm interested in what this patch would look like if we:
I think we should try to minimize new helpers in the future, only adding them where they really are solving a problem. If we had a simple helper that was a macro for "tolerate-user-node-taint", with no other logic dependent on the parent scope, I think this might be simpler to write and understand. |
Yes I certainly agree, it is a mess to grasp this code. The big crux is to have something DRY used by both the kubespawner configured in jupyterhub_config.py as well as resources created by helm templates. The key solution to avoiding complexity would be to have the kubespawner not be configured by jupyterhub_config.py, but by a configmap or similar directly which it observed. This PR could be simpler by not having the preparescope etc, but the future PR with affinities and presets for configuring affinities. In order for configurable tolerations to be useful at the same time as supporting for example the image pullers, they must be configured with the same tolerations also, and hence we have the helm templates + jupyterhub_config.py configuration from the same source challenge. Also, by having presets the challenge becomes a bit harder. |
👍 |
jupyterhub.tolerations | ||
Refactors the setting of the user pods tolerations field. | ||
*/}} | ||
{{- define "jupyterhub.tolerations" -}} |
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 think this helper is at least one too far. The define/end is more than the code it's deduplicating by being reused.
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.
If you would add
tolerations:
without any entries within it, you get invalid YAML. To know if you should add the tolerations:
entry or not, you must first figure out if you have content within it.
tolerationsList
is the content for the tolerations
. It would have been a better name with tolerationsContent
.
A lot of the struggles I've faced relates to "should i add this or not, do i have content for the field or not?", the prepareScope helper takes care of a lot of those questions.
I have tried to make do with less helpers and It is really hard... =/ I could try more and more, but I'm currently out of ideas on how to solve the challenges. I'll try address things better in a single point to avoid spreading discussion.
@@ -23,6 +23,11 @@ spec: | |||
{{- if .Values.rbac.enabled }} | |||
serviceAccountName: user-scheduler | |||
{{- end }} | |||
{{- $_ := merge (dict "podKind" "core") . }} |
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.
These lines {{- $_ := merge (dict "podKind" "core") . }}
are I think the hardest to follow, and make contributing to/understanding the chart very difficult. I genuinely don't know what this means or how to use it, so I can't really evaluate whether this is the right thing to do and if/when we might need to do the same or similar thing in other templates.
There's now a lot of hidden logic that is several layers deep.
If, instead, this were a single:
{{- include "jupyterhub.tolerations" "core" | nindent 6 }}
I feel like that would be simpler and easier to grok as "include the tolerations for a core pod". Is that achievable?
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.
Perhaps we can reduce the complexity slightly, I dare not prove a negative, but I have found it very challenging. The merge thing could be simplified by using one or more set
statements at least.
The reason for the merge, is that you can only pass one object to a helper, and the helper needs a lof of stuff that exists within the default scope referred to as .
--- By augmenting the default scope, we would change a state globally, which also isnt great. What I have done here is to create a new variable called $_ that creates a new scope by creating a new dictionary, and merging the current scope to it.
{{- include "jupyterhub.tolerations" "core" | nindent 6 }}
This helper would not be aware of what .Release.Name
was if it isnt passed the .
scope or something that got the .
scope merged with it. If in the scope of the tolerations helper one would reference .
it would get "core"
only. This is sometimes enough for certain helpers, but tend not to be for a lot of helpers.
{{- /* Fetch relevant information */}} | ||
{{- $dummy := set . "tolerationsList" (include "jupyterhub.tolerationsList" .) }} | ||
{{- $dummy := set . "tolerations" (include "jupyterhub.tolerations" .) }} | ||
{{- $dummy := set . "hasTolerations" .tolerations }} |
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.
Let's try to do this without prepareScope. I think helpers that setup the state for other helpers, rather than being self-contained is something we should try to avoid.
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.
Will attempt to address concerns at a single discussion entry, not in a review comment.
The pod-kind labels are not needed for any logic. I got confused. I think I know your answer, I'll delete them. :D |
7d64171
to
cbe8418
Compare
singleuser.tolerations: | | ||
{{- $_.tolerationsList | nindent 4 }} | ||
{{- end }} | ||
{{- include "jupyterhub.userTolerations" | nindent 4 }} |
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.
We can assume userTolerations has content, we cant with the affinity later though...
{{- $dummy := include "jupyterhub.prepareScope" $_ }} | ||
{{- if $_.hasTolerations }} | ||
{{- include "jupyterhub.tolerations" $_ | nindent 6 }} | ||
{{- end }} |
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.
There was a hatch for tolerations on core nodes, but it was not adding anything by default anyhow.
{{- include "jupyterhub.tolerations" $_ | nindent 6 }} | ||
{{- end }} | ||
tolerations: | ||
{{- include "jupyterhub.userTolerations" . | nindent 8 }} |
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.
The image puller also needs the same tolerations
9b9f6dd
to
b263568
Compare
Extra storage labels are now configurable through config.yaml and `singleuser.storageExtraLabels`.
b263568
to
09d8263
Compare
<core|user> pods now get `tolerations` for the node taint `hub.jupyter.org/dedicated=<user|core>:NoSchedule` that could optionally be added to nodes or all nodes in a node group (aka. node pool). Note that due to a bug with using the `gcloud` CLI, we also add the toleration for the same taint where `/` is replaced with `_`. In this commit, `singleuser.extraTolerations` are now also made configurable allowing you to add your own custom tolerations to the user pods.
09d8263
to
f243103
Compare
To review
singleuser.tolerations
, for node taints