利用docker部署jupyterhub接入ldap

最近新增了一台显卡性能强劲的服务器,但由于训练任务不多,还处理闲置状态,跟公司领导商量了一下后决定在上面部署一个jupyter notebook,以便开放机器算力让更多同事可以把这台计算机利用起来。
对比了一下jupyter生态圈的几个产品后,我们决定用jupyterhub+ldap的方式对待部署,以便达到以下效果:

  1. 用户拥有个人notebook服务及文件空间(虚拟化);
  2. 直接利用AD账号登录。

Jupyterhub简介

JupyterHub是由Jupyter团队推出的一个支持多用户notebook的服务器。JupyterHub本身具有权限管理配置管理启动Notebook反向代理等功能。官网的示意图很好地阐述了JupyterHub的功能:
在这里插入图片描述
其中需要特别注意的是图中的spawners,它所表达的意思是,Hub会为每一个登录的用户Spawn(直译为繁衍,实际上是启动一个新的实例)一个notebook,而后对于访用户的所有操作,Hub都会把它路由到这个notebook实例。这就是JupyterHub实现用户工作区虚拟化的方式。

部署方式

1. jupyterhub部署

使用Docker进行JupyterHub部署是最方便快捷的方式,参照官方教程,键入命令
docker run -d -p 8000:8000 --name jupyterhub jupyterhub/jupyterhub jupyterhub
可以快速地搭建起一个JupyterHub容器。打开浏览器访问http://localhost:8000,会出现登录页面。
在这里插入图片描述
这时候Hub用的是系统(Docker中的Linux内核)用户。而系统中此时只有root用户,而且没有密码,因此我们需要给容器中的系统添加一个用户
步骤1. 先找到JupyterHub所在的容器
docker ps
步骤2. 进入JupyterHub容器
docker exec -ti xxx(容器id) bash
步骤3. 添加系统用户
adduser xxx

完成这些步骤后,我们就可以用账号xxx登录JupyterHub了,这时候会出现以下问题
在这里插入图片描述
通过docker log xxx(容器id)可以查看到以下报错

[I 2020-04-03 12:57:47.593 JupyterHub spawner:1417] Spawning jupyterhub-singleuser --port=53985
Traceback (most recent call last):
File “/usr/local/lib/python3.6/dist-packages/jupyterhub/singleuser.py”, line 24, in
import notebook
ModuleNotFoundError: No module named ‘notebook’

原因是JupyterHub只有刚才所说的路由转发等功能,它本身是不具备notebook模块的,启动notebook有几种方式

  1. systemdspawner
  2. dockerspawner

其中systemdspawner是默认的spawner,它会为每个用户创建一个notebook进程,并把用户的notebook请求转发到这个进程里,而dockerspwaner会通过主机的docker.sock去创建notebook容器实例。
由于我们没有对spawner进行任何定义,所以只需要进入窗口bash执行以下命令

pip intall jupyter

回到http://localhost:8000重新登录,可以看到系统 spawn成功,并且进到熟悉的notebook界面了。

2. LDAP接入

要接入LDAP需要在容器中安装jupyterhub-ldapauthenticator

pip install jupyterhub-ldapauthenticator

并且通过挂载jupyterhub_config.py进行ldap配置实现,以下是接入AD的配置示例:

c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.server_address = "x.x.x.x"
c.LDAPAuthenticator.lookup_dn = False
c.LDAPAuthenticator.lookup_dn_search_filter = '({login_attr}={login})'
c.LDAPAuthenticator.lookup_dn_search_user = ''             #格式为'domain\user"
c.LDAPAuthenticator.lookup_dn_search_password = ''		#密码
c.LDAPAuthenticator.user_search_base = 'OU=xx,OU=xx,OU=xx,DC=xxx,DC=xx'	#按照实际情况填写xx内容
c.LDAPAuthenticator.user_attribute = 'sAMAccountName'
c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'xx'
c.LDAPAuthenticator.bind_dn_template = 'domain\{username}'			#按照实际情况填写domain

另外有一个需要注意的地方是,使用LDAP接入时,jupyterhub的宿主系统需要有对应的系统账号,例如需要登录LDAP中用户名为zhang的用户,那么需要通过命令useradd -d /home/zhang zhang创建一个名为zhang的系统账户。

这时候重新进入http://locahost:8000,就可以用AD账号登录到jupyterhub了。

3. Dockerfile和docker-compose.yml文件

Dockerfile

FROM jupyterhub/jupyterhub:latest

RUN pip install jupyterhub-ldapauthenticator
RUN pip install jupyter
RUN pip install jupyterlab

RUN useradd -d /home/zhangxi1 zhang		#在这里通过useradd创建允许AD登入的账户

RUN chmod -R 777 /home

Docker-compose.yml

version: "2"

services:
  hub:
    build: .
    volumes:
      - //var/run/docker.sock:/var/run/docker.sock
    ports:
      - 8000:8000

通过docker-compose up -d启动容器

优化方向

目前使用的是systemdspawner,对于系统横向扩展并不友好 ,后期会考虑使用dockerspawner以及kubernetes接入


版权声明:本文为hey_zng原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。