Hello everyone,
i’m currently trying to get to run a BinderHub installation on the k8s cluster of my institution. The steps of building an image are going fine but the following login into JupyterHub fails, thus it’s rather a JupyterHub issue I guess (i can also reproduce the error using cURL). After successfully building an image and pushing it to our private Image Registry, i receive a 403 error when trying to open the application in JupyterHub. The following happens:
After the notebook pod is started, the browser makes following request: GET https://[our-binderhub.de]/hub/user/n_kapp03-notebooks-lcp7toie/?token=token_of_22_chars
Response is 302 which redirects to GET https://[our-binderhub.de]/hub/login?next=/hub/user/n_kapp03-notebooks-lcp7toie/?token=token_of_22_chars
This returns 403 Forbidden
A couple things that might be relevant:
BinderHub runs without authentication (auth_enabled: false)
I’ve noticed is that the redirect looks weird. token looks like a query param bit since it is preceded by ? instead of & it’s not resolved as such. I’ve tried to put token into an additional query param manually with no success.
The required user appears to exist: POST https://[our-binderhub.de]/hub/api/users/n_kapp03-notebooks-lcp7toie returns 409 "User n_kapp03-notebooks-lcp7toie already exists".
Kubernetes Ingress is configured so that requests to https://[our-binderhub.de] go to BinderHub and only requests to https://[our-binderhub.de]/hub go to the JupyterHub pod. Could this possibly be an issue? For our scenario, this is the most straightforward solution.
I’m running JupyterHub using the image jupyterhub/k8s-hub:0.11.1. The BinderHub image is self built using Chartpress with very minor changes so far.
Any help or insight is appreciated!
PS: Is there a chance to edit code inside the JupyterHub pod to put some debug messages in there? There’s probably no such thing as hot reload i suppose.
Sure. Maybe someone could confirm if the requests made to JupyterHub are proper or not?!
Note that .yaml files are mostly unchanged compared to BinderHub GitHub repo and configuration was done through values.
All other files under helm-chart/binderhub/templates are identical to binderhub/helm-chart/binderhub/templates at master · jupyterhub/binderhub · GitHub.
No changes were made to helm-chart/binderhub/files/binderhub_config.py. helm-chart/chartpress.yaml is also identical except for imagePrefix which points to my custom image.
You can observe that a custom image for repo2docker is used as well. This is because we need to work around a proxy within our network. I don’t see how this could be related to my problem though.
Can you share the logs of the user pod and hub pod?
After the notebook pod is started, the browser makes following request: GET https://[our-binderhub.de]/hub/user/n_kapp03-notebooks-lcp7toie/?token=token_of_22_chars
This is the first problem. The request should be sent to /user/n_kapp... not /hub/user/n_kapp.... When using BinderHub without auth, there should be no requests originating in the browser handled by the Hub at all. This is generally a symptom of requests not getting routed correctly, or URLs not being constructed correctly.
This request is what would normally happen when a server is not running. It triggers the login process (the redirect to /hub/login), and back to the running server. The login page return a 403 because without auth, login is disabled. This is the expected behavior when a request goes to the Hub, which is what shouldn’t be happening in the first place.
Kubernetes Ingress is configured so that requests to https://[our-binderhub.de] go to BinderHub and only requests to https://[our-binderhub.de]/hub go to the JupyterHub pod. Could this possibly be an issue?
Yes, I believe this is the issue. I don’t think pathSuffix is the right configuration here. In particular, jupyterhub doesn’t only serve requests from /hub/, it also expects /user/ etc. pathSuffix was introduced by this PR and as I understand it, should ~never be used unless you are using GCE ingress. I think you are getting a confusing bug due to a coincidence that you used pathSuffix that happens to be a URL prefix the Hub already uses (/hub/). If you’d used a different pathSuffix, the error might have been clearer that the URLs were not correct (I’m not sure, though).
Instead, if you want to set the base URL of the hub deployment, use config:
jupyterhub:
hub:
baseUrl: jupyterhub
(I’m not using hub because it could get a little confusing to have URLs with /hub/hub/..., but there’s nothing technically wrong with it). This tells all the jupyterhub URLs to use this prefix. Then the user URL should be /jupyterhub/user/n_kapp... and the hub URL (only for API requests) should be /jupyterhub/hub/api/....