对于自己部署的JupyterHub的一次总结,其实本人Linux方面也只小白,很多做法可能不算最佳实践,摸爬滚打终究还是把服务给Host起来了,希望能用自己的经验给其他人一些参考。关于JupyterHub更多细节,可以访问他们的文档。
JupyterHub是为Jupyter Notebook和JupyterLab提供多用户支持的服务,支持在Linux/Unix系统上部署。我主要是为了方便在云服务器上使用JupyterLab,所以尝试部署了下。
安装JupyterHub
JupyterHub目前仅支持在Linux/Unix系统上安装,不支持Windows系统。我是在阿里云ECS实例上部署的,系统直接安装的阿里云提供的CentOS7的镜像。
安装依赖项
安装JupyterHub需要先安装Python3.5+和nodejs/npm。我是在阿里云ECS实例上部署的,因为默认只安装了Python2,出于方便起见,我直接安装的Anaconda 5.3.1。
关于Anaconda3的安装,如果不熟悉的同学可以参考这篇。Anaconda默认会被安装在执行用户的HOME目录下。因为后续会被多用户使用,建议将安装位置放在公共的地方,比如我放在了/opt/anaconda3下头。
安装完成conda
后,其实Python3、jupyter也已经安装完成了。另外需要安装下nodejs/npm,执行下面的命令可以进行安装:
conda install -c conda-forge nodejs
安装JupyterHub
如果是已经安装了anaconda,可以使用conda
执行下面的命令进行安装:
conda install -c conda-forge jupyterhub
当然也可以使用pip
和npm
安装:
python3 -m pip install jupyterhub
npm install -g configurable-http-proxy
执行下面的命令确认安装成功:
jupyterhub -h
configurable-http-proxy -h
JupyterHub配置
JupyterHub可以说就是开箱即用的,但是如果有些特殊需求也可以进一步配置。
要配置JupyterHub,首先需要生产一个默认配置文件,执行下面的命令,在执行的目录下会生成一个jupyterhub_config.py文件。
jupyterhub --generate-config
在jupyterhub_config.py文件中找到想要修改的内容,进行修改,并取消注释,然后执行:
jupyterhub -f /path/to/jupyterhub_config.py
就能让JupyterHub按照你的配置运行了。
JupyterHub的配置主要分为以下几大块:Application、JupyterHub、Spawner、Authenticator,涉及的东西不少,具体的按需配置。下面只根据我个人的配置说几个简单的配置项,更多配置请访问官方文档查看。
登录方式配置
JupyterHub默认采用PAMAuthenticator授权:c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator'
。
这个授权方式其实就是走服务器用户的登录认证。你在服务器加了个user1的用户,你就可以配置允许这个用户登录。
JupyterHub也支持别授权方式,比如接入GitHub、Google的OAuth认证。
登录用户控制
JupyterHub支持多用户登录,对于用户登录的控制也提供多种方式:
- 用户黑名单控制 –
c.Authenticator.blacklist
写在黑名单的用户会被限制登录。如配置:c.Authenticator.whitelist = { 'user1' }
,则user1就不能登录了。 - 用户白名单控制 –
c.Authenticator.whitelist
写在白名单的用户才能登录。如配置:c.Authenticator.whitelist = { 'user1' }
,则只有user1能登录。该项优先级高于黑名单。 - 管理员用户 –
c.Authenticator.admin_users
管理员用户可以查看登录的用户,某些授权方式下可以添加/删除用户,可以重启或停止Hub,可以停止其他用户的服务,如果有配置的话还可以访问其用户的内容。 - 用户组白名单 –
c.LocalAuthenticator.group_whitelist
如果是采用默认的基于本地用户的授权方式,还能够通过用户组白名单来进行授权。如果配置了这项,用户白名单会失效。
c.Authenticator.whitelist
是配置控制用户登录的配置项,默认不限制任何用户登录。如果有配置内容,则限制只有配置的这些用户可以登录。如:c.Authenticator.whitelist = { 'user1' }
,则只有user1能登录。
运行端口
默认JupyterHub运行在8000端口上,可以通过修改默认配置c.JupyterHub.bind_url = 'http://:8000'
中的端口号来指定运行的端口。
文件保存位置
默认在JupyterHub下头创建的文件会创建在登录用户的HOME目录下。可以通过修改默认配置c.Spawner.notebook_dir
来修改生成文件目录。设置这个值的时候有两个特殊的标识可以用:~
会被实际展开为登录用户的HOME目录,{username}
会被实际展开为登录用户的用户名。
需要注意配置的目录,登录用户需要有读写权限,不然会出问题。
配置完成后,通过-f指定配置文件,就可以让JupyterHub按你配置的执行了:
jupyterhub -f /path/to/your/jupyterhub_config.py
访问JupyterHub
运行起来后,我们肯定是希望能够通过公网访问,我们可以直接通过端口访问,或者也可以通过Nginx进行反向代理。
开放端口访问
阿里云ECS的端口开放是通过安全组控制的,具体参考阿里云文档
Nginx反向代理
为了通过公网访问,我们可以配置nginx方向代理,将80端口的请求转发到8000端口。我是直接在nginx.conf中修改的,具体配置如下:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name YOUR_SERVER_NAME;
# Load configuration files for the default server block.
location ~* ^/user/\w+/api/kernels {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
proxy_pass http://127.0.0.1:8000;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
上面的配置就是简单的监听80端口(域名备案还没弄下来,所以直接更改默认配置了,有域名的可以把server_name后面改成自己想要的域名),通过proxy_pass http://127.0.0.1:8000;
配置就把请求转发给8000端口了。
JupyterHub的API接口里,有个请求很特殊,是个WebSocket请求:
ws://example.com/user/user1/api/kernels/4cad141f-0885-4dd2-b963-7c9b2cc2bf37/channels?session_id=3fe22e75-66f1-4eaa-b00c-5741166d955e&token=9fbea75abdf14fad934951fa36c46f35
如果这个请求简单的走Http代理的话,请求返回会是400Bad Request。好在nginx在1.3版本后支持代理WebSocket协议,所以像上面那样特殊处理下这个请求就可以了。
创建个JupyterHub服务
上面说的运行JupyterHub是直接从命令行运行起来的,调试阶段这样很适合,因为在终端上会一直输出JupyterHub的运行情况。但是真的让它就这样一直跑着,无论从使用还是后续的管理上都不是很方便。最好还是把它变成个系统服务。
vim /usr/lib/systemd/system/jupyterhub.service
在编辑器里像下面这样写:
[Unit]
Description=Jupyterhub
After=network-online.target
[Service]
User=root
Environment="PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/anaconda3/bin"
ExecStart=/opt/anaconda3/bin/jupyterhub -f /home/.config//jupyterhub_config.py
WorkingDirectory=/etc/jupyterhub
[Install]
WantedBy=multi-user.target
ExecStart
和WorkingDirectory
根据个人实际情况修改,如果不知道jupyterhub是在哪,可以执行whereis jupyterhub
查看。
安装JupyterLab和jupyter-labhub
JupyterHub默认是使用Jupyter Notebook,如果有和我一样喜欢用JupyterLab的人,可以参照以下内容进行配置。
关于JupyterLab的更多细节,参见官方文档。
安装JupyterLab和所需拓展
首先得安装JupyterLab。安装了anaconda的话可以直接使用conda
安装JupyterLab:
conda install -c conda-forge jupyterlab
也可以通过pip
进行安装:
pip install jupyterhub
要想在JupyterHub使用JupyterLab还需要安装个插件,执行下面的命令可以进行安装:
jupyter labextension install @jupyterlab/hub-extension
配置JupyterHub使用JupyterLab
配置JupyterHub使用JupyterLab还需要在修改jupyterhub_config.py文件,修改配置:c.Spawner.cmd = ['jupyterhub-singleuser']
,将jupyterhub-singleuser
修改为jupyter-labhub
,重启服务就行。
后记
在使用服务方式启动JupyterHub的时候如果遇到问题可以执行journalctl -l -u jupyterhub.service | less
或者systemctl -l status jupyterhub.service
查看服务运行日志来排查问题。
安装完成后,其实还有个遗留的错误:pam_loginuid(login:session): set_loginuid failed
。但是因为对于我的使用没有影响我也就没有处理。关于这个问题在JupyterHub项目有Issue,如果有需要处理这个问题的可以查看下这个Issue。