-
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
Allow specifying image pull secret #801
Allow specifying image pull secret #801
Conversation
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.
@AlexMorreale Thanks for the PR! ❤️
I lack experience of using image pull secrets like this, but I know a lot of how to handle the helm templates so I added some comments about such details.
I'm hoping to find time to follow up later, working intensively to prepare for JupyterCon 2018 and a release of the chart before it.
images/hub/jupyterhub_config.py
Outdated
@@ -48,6 +48,10 @@ | |||
|
|||
c.KubeSpawner.image_pull_policy = get_config('singleuser.image-pull-policy') | |||
|
|||
image_secret = get_config('singleuser.image-pull-secret', None) | |||
if image_secret: | |||
c.KubeSpawner.image_pull_secrets = image_secret |
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.
Its fine to assign it right away without the conditional.
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.
right cause the default is 'None' derp. ill get this changed
apiVersion: v1 | ||
metadata: | ||
name: {{ .Values.singleuser.image.pullSecret.name }} | ||
namespace: {{ .Release.Namespace }} |
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 don't have to set the namespace explicitly.
- The file itself should be moved to the singleuser folder.
- We should add labels to it:
metadata:
name: singleuser-image-credentials
labels:
{{- $_ := merge (dict "componentSuffix" "-image-credentials") . }}
{{- include "jupyterhub.labels" $_ | 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.
You could name the file image-credentials-secret.yaml
perhaps.
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 will move the file it makes more sense to put it in there.
I am pretty sure this secret needs to be in the same namespace as the pods being spun up. dockerconfig secrets are not global.
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 namespace is decided implicitly, if you look at other files, they all end up in the correct namespace even though it isn't explicitly written out. This would work as well though!
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.
oh that makes sense.
@@ -133,6 +133,9 @@ data: | |||
{{- .Values.singleuser.cloudMetadata | toYaml | trimSuffix "\n" | nindent 4 }} | |||
singleuser.start-timeout: {{ .Values.singleuser.startTimeout | quote }} | |||
singleuser.image-pull-policy: {{ .Values.singleuser.image.pullPolicy | quote }} | |||
{{- if .Values.singleuser.image.pullSecret }} | |||
singleuser.image-pull-secret: {{ .Values.singleuser.image.pullSecret | quote }} |
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 value .Values.singleuser.image.pullSecret
is not just a string so it can't be added like this, but you must instead use some toYaml
trick. Something like this:
{{- if .Values.auth.github.org_whitelist }}
auth.github.org_whitelist: |
{{- .Values.auth.github.org_whitelist | toYaml | trimSuffix "\n" | nindent 4 }}
{{- 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.
sorry this was supposed to be {{- if .Values.singleuser.image.pullSecret.name }}
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 looked at the source code of Kubespawner and Kubernets API and learned some things!
I learned that KubeSpawner's setting image_pull_secrets
is not named properly, it should really be named image_pull_secret_name
. I suggested below we could name the secret singleuser-image-credentials
, this is what we need to assign to singleuser.image-pull-secret
, as this is used to set KubeSpawners.image_pull_secrets
setting in the jupyterhub_config.py
file, and that in turn through make_pod
in KubeSpawner creates a pod with a pod having spec.imagePullSecrets
being [{'name': 'singleuser-image-credentials'}]
Pweh, this was tricky to detangle!
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 dug all yesterday. quite a bit of layers. take a look at what i have now and let me know if that makes sense.
namespace: {{ .Release.Namespace }} | ||
type: kubernetes.io/dockerconfigjson | ||
data: | ||
.dockerconfigjson: {{ .Values.singleuser.image.pullSecret.dockerConfigJson }} |
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 read in the link referenced by the kubespawner documentation that we are supposed to base64 encode the json...
Good thing, Helm will allows to do this quite easily I think. Oh so I googled for helm base64 and found this very relevant documentation!
From the looks of it, perhaps a config like this would make sense?
singleuser:
image:
name: someimagename
tag: sometag
credentials:
registry: quay.io
username: someone
password: sillyness
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.
so my thought here was someone with "pre" base64 encode this because it is a json blob and that could be a mess in the chart.yml.
If this is against helm best practices i will gladly change it.
I am new helm, we wrote our own kubernetes manifest/deploy at ezCater and don't leverage helm.
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 figure it would be quite easy to grasp for other users of the chart if we set it up like above. It would also be relatively easy to communicate and write the documentation what the users of the chart should do to set an image pull secret.
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 figure reducing the effort of the chart user is good enough as motivation to take care of the base64 encoding for the chart users, but I'm afraid that some chart users might think that the credentials are encrypted just because they were base64 encoded even though they are not as base64 is easy to decode. If we make the user write out the credentials in plain text the chart user can't be mislead.
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.
all of this makes sense will fix in my next commit.
@AlexMorreale Thank you for the work you put in, I appreciate that you are taking time in order to contribute! ❤️ |
@consideRatio loving the feedback. Like i said in the comments very very very new to helm so the feedback is great. We love Jupyterhub and Kubernetes at ezCater so I want to help in anyway I can. I will fix the base64 encoding of the dockerconfigjson in my next push!
|
@@ -8,5 +8,5 @@ metadata: | |||
{{- include "jupyterhub.labels" $_ | nindent 4 }} | |||
type: kubernetes.io/dockerconfigjson | |||
data: | |||
.dockerconfigjson: {{ .Values.singleuser.image.pullSecret.dockerConfigJson }} | |||
.dockerconfigjson: {{ .Values.singleuser.image.pullSecret.dockerConfigJson| b64enc }} |
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.
This assumes we have something like this:
singleuser:
image:
name: ...
tag: ...
pullSecrets:
dockerConfigJson: ...
Do you mind we do it like this instead?
singleuser:
image:
name: someimagename
tag: sometag
credentials:
registry: quay.io
username: someone
password: sillyness
You could copy->paste->adjust the template from the Helm tips and tricks section and put it in _helpers.tpl
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.
crap yes
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 comment got lost in me pushing stuff
@@ -8,5 +8,5 @@ metadata: | |||
{{- include "jupyterhub.labels" $_ | nindent 4 }} | |||
type: kubernetes.io/dockerconfigjson | |||
data: | |||
.dockerconfigjson: {{ .Values.singleuser.image.pullSecret.dockerConfigJson| b64enc }} | |||
.dockerconfigjson: {{ template "singleuser.image.pullSecret" . }} |
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.
Looking great! Helm is silly, they have two functions doing the same thing: template
and include
, but include
is superior to template
so we use it all over instead. In this case both will work fine though but Helms own best practices is to use include
even though we actually copied this template from their tips and tricks haha :D
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.
hehe ill update!
@@ -133,6 +133,9 @@ data: | |||
{{- .Values.singleuser.cloudMetadata | toYaml | trimSuffix "\n" | nindent 4 }} | |||
singleuser.start-timeout: {{ .Values.singleuser.startTimeout | quote }} | |||
singleuser.image-pull-policy: {{ .Values.singleuser.image.pullPolicy | quote }} | |||
{{- if .Values.singleuser.image.pullSecret }} | |||
singleuser.image-pull-secret: singleuser-image-credentials |
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.
Oh thinking about it, let us not propagate this mistake in KubeSpawner but instead try to alleviate it by calling this image-pull-secret-name
instead.
Wieee this looks great!!! It may work as it is but my experience is telling me to be cautious for the unknown so I'd like us to have it tested once at least. If you can do it yourself that would be fine but it may be a bit cumbersome. Have you upgraded a cluster to use the locally cloned helm chart before? If not I'll find time to do it later, we should update the documentation on how to get setup in order to do this better. It would also be great to have some documentation in schema.yaml about the added fields. That documentation will propagate to the guide's Helm chart configuration reference. I can do it also later. |
I have tested this locally in Minikube and it works like a charm. I actually dont use Helm or this helm chart for my companies cluster. We use a statefulset for the hub.... either way. I can kill and recreate testing with the ezCater private reg in minikube. Would that be okay? Also i can update the docs as well, if you can point me in the right direction. Also also let me fix the code related to this comment:
|
also should i consider this changing it from
to:
to be more like imagePullPolicy? which is not under the |
Awesome! I have never used a secret for image pulling before so It's great that you verify that it works as it should. The documentation (mainly a reference) can be written in the schema.yaml file. Simply try to mimic what they have done there. Ah yes excellent reflection! I considered that also and I don't know what will be best. In the future we may want to be able to specify various images and not only one. Hmmm... When the image is being pulled, what binary does the pulling and is actually consuming the secret? How does that application know what secret to use for a certain image? Aaaa... The application doing the pulling is probably looking for secrets with a certain registry, and then uses those credentials... If that is the case, we should indeed switch so that imagePullSecret is extracted so it later can become a List of imagePullSecrets. |
Oh well the pod has a field called imagePullSecrets, only those listed there will be used, hmmm... Let us go with the latter option that you proposed, where the secret is not nested under the image! |
After my latest changes:
Then:
Something to note: If you have a larger singleuser image with multiple languages like we do at ezCater(R, Python, & Julia) it's worth bumping the singluser.startTimeout |
if i get some cycles tonight i will update the docs with the info i posted above in my testing cycle |
@consideRatio added documentation for |
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!
Wieeeeeeeeeeeee this is awesome!!! @AlexMorreale thank you for your time making this contribution! Congratulations on your first PR to this repo! I hope to give you and others a better contributing experience where we help out more with having more tests etc setup as well as guidance on what is appreciated pre-merge such as adding documentation where applicable. Thank you for staying with it even though that wasn't in place already. ❤️ |
@AlexMorreale I'm working on adding the email part, could you verify if it still works if you specify an email as well? Using the command to generate a secret forced the user to use a email hmmm... |
Or nevermind, i made a helper allowing specification of the email to be optional as well as the image registry to default to Docker the companys image repository - like kubectl does when creating secrets. |
@consideRatio let me know if you need review on the code! |
what / why
Allows you to specify an image_pull_secrets option in the jupyterhub docker image.
PS: I have no idea how to contribute to this repo.