JupyterHub与SystemUserSpawner失败

时间:2019-02-26 16:15:01

标签: jupyterhub

我正在尝试使用dockerspawner.SystemUserSpawner在虚拟机上运行JupyterHub,并生成Jupyter Lab实例。

我的jupyterhub_config.py具有以下(附加)行:

c.Spawner.default_url = '/lab'
c.Spawner.cmd = ['jupyter', 'labhub']
c.JupyterHub.spawner_class = 'dockerspawner.SystemUserSpawner'

(为bind_urlhub_ip添加行)。其他所有内容都应为默认设置。

运行(jupyterhub -f /etc/jupyterhub/jupyterhub_config.py)并登录浏览器后,出现500错误。命令行上的日志如下所示:

[D 2019-02-26 16:55:37.869 JupyterHub dockerspawner:644] Getting container 'jupyter-testuser'
[D 2019-02-26 16:55:37.873 JupyterHub dockerspawner:629] Container 8bf627d status: {'Dead': False,
     'Error': '',
     'ExitCode': 1,
     'FinishedAt': '2019-02-26T15:55:29.518823812Z',
     'OOMKilled': False,
     'Paused': False,
     'Pid': 0,
     'Restarting': False,
     'Running': False,
     'StartedAt': '2019-02-26T15:55:28.446881243Z',
     'Status': 'exited'}
[W 2019-02-26 16:55:37.874 JupyterHub web:1667] 500 GET /hub/user/testuser/ (www.xxx.yyy.zzz): Spawner failed to start [status=ExitCode=1, Error='', FinishedAt=2019-02-26T15:55:29.518823812Z]. The logs for testuser may contain details.
[D 2019-02-26 16:55:37.875 JupyterHub base:880] No template for 500

然后,JupyterHub自身陷入(无限循环)循环,试图每10秒刷新一次容器。

忽略丢失的500个模板,从容器状态消息中我一点都不明智,但是docker logs jupyter-testuser显示:

....
[C 2019-02-26 15:55:29.360 SingleUserLabApp notebookapp:1707] Running as root is not recommended. Use --allow-root to bypass.
[D 2019-02-26 15:55:29.360 SingleUserLabApp application:647] Exiting application: jupyter-notebook

当我将jupyterhub_config.py更改为包含

c.Spawner.cmd = ['jupyter', 'labhub', '--allow-root']
c.DockerSpawner.remove = True

一切正常,但有一个令人讨厌的警告:我现在是根用户,并且在主目录中创建的任何文件都不是testuser的所有者,而是(Docker容器){{ 1}}。在虚拟机本身内部,root无法删除这些文件。

(请注意testuser:如果我不包括该内容,JupyterHub将卡在先前没有c.DockerSpawner.remove = True的容器上)

文档建议初始配置应该正确,对于标准docker堆栈,--allow-root并不是必需的(我显然在这里使用默认的--allow-root)。

为进行比较,使用jupyterhub/singleuser:0.9效果很好。

我看不到我所缺少的内容,或者在哪里可以找到更多的调试选项。因此,欢迎提出任何建议。

Ubuntu 18.04.2上的Jupyter(Hub)0.9.4版本

1 个答案:

答案 0 :(得分:1)

错误出在c.Spawner.cmdc.Spawner.cmd = ['jupyter', 'labhub'])。

这将以参数jupyter labhub启动Docker容器,类似于从命令行以docker run jupyter/singleuser:0.9 jupyter labhub的方式运行它(带有一些其他环境变量)。

但是,Docker将读取容器名称之后的第一个参数为CMD,而不是Dockerfile中CMD的参数。也就是说,基本笔记本的Dockerfile(以及jupyter / singleuser的Dockerfile)具有以下内容:

# Configure container startup
ENTRYPOINT ["tini", "-g", "--"]
CMD ["start-notebook.sh"]

这将使用下一个命令tini -g -- start-notebook.sh,然后是给docker run的参数来运行入口点。但是,由于第一个参数替换了CMD,因此执行的是tini -g -- jupyter,其中labhub作为参数传递给jupyter。后者绕过start-notebook.sh并因此绕过start.sh脚本,这些脚本实际上负责处理容器内的用户ID设置。也就是说,这些启动脚本会阻止root实际运行jupyter命令。跳过脚本并不能阻止脚本的出现,而jupyter命令以root身份运行,出现问题中指出的问题。

有两种可能的解决方法;我不清楚哪个是首选:

  1. start-notebook.sh设置中包含start.shc.Spawner.cmd(我直接选择了start.sh):

    c.Spawner.cmd = ['start.sh', 'jupyter', 'labhub']
    

    这将用start-notebook.sh代替start.sh命令(通常很好;第一个是第二个的小包装),然后将jupyter labhub作为{的参数{1}}。正是需要的。

  2. 设置环境变量start.sh,并禁用 JUPYTER_LAB_ENABLE

    c.Spawner.cmd

    #c.Spawner.cmd = ['start.sh', 'jupyter', 'labhub'] c.SystemUserSpawner.environment = {'JUPYTER_ENABLE_LAB': '1'} 查看环境变量start.sh(由JUPYTER_ENABLE_LAB传递到Docker容器),并在设置此变量后运行实验室(因此,不一定需要将其设置为SystemUserSpawner。在这种情况下,不需要将额外的参数传递给Docker容器或'1'脚本,因此start.sh被禁用。