【问题标题】:JupyterHub with SystemUserSpawner fails带有 SystemUserSpawner 的 JupyterHub 失败
【发布时间】:2019-02-26 16:15:00
【问题描述】:

我正在尝试在虚拟机上运行 JupyterHub,使用 dockerspawner.SystemUserSpawner,生成 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 容器)root。例如,在 VM 内部,testuser 无法删除这些文件。

(注意c.DockerSpawner.remove = True:如果我不包含它,JupyterHub 会卡在没有--allow-root 的前一个容器上)

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

作为比较,使用dockerspawner.DockerSpawner 效果很好。

我没有看到我缺少什么,或者在哪里寻找更多调试选项。因此,欢迎提出任何建议。

Ubuntu 18.04.2 上的 Jupyter(Hub) 版本 0.9.4

【问题讨论】:

    标签: jupyterhub


    【解决方案1】:

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

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

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

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

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

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

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

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

      这会将start-notebook.sh 命令替换为start.sh(通常没问题;第一个是第二个的小包装),然后jupyter labhub 将作为start.sh 的参数提供。这正是我们所需要的。

    2. 设置环境变量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(由SystemUserSpawner 传递到 Docker 容器),并在设置此变量时运行实验室(因此,它不需要必须设置为'1')。在这种情况下,不需要将额外的参数传递给 Docker 容器或 start.sh 脚本,因此 c.Spawner.cmd 被禁用。

    【讨论】:

    • 非常彻底!谢谢!
    猜你喜欢
    • 2020-08-15
    • 2021-04-02
    • 2020-06-05
    • 1970-01-01
    • 2020-05-31
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多