JupyterHub on Kubernetes的SQLite、

作者: 北邮郭大宝 | 来源:发表于2019-04-03 14:57 被阅读5次

    在完成JupyteHub on k8s的基本部署后,还需要一些用户定制的自定义配置,本文重点介绍JupyterHub的身份验证(Authentication)。

    1. JupyteHub自带的Authentication方法

    默认条件下,JupyterHub允许用户输入任意的用户名和密码,登录注册自己的Jupyter Notebook。显然这种模式不符合生产要求,必须有一套身份认证机制。

    根据官网的描述,JupyterHub自带了一些身份认证方法,比如Dummy、OAuth2、LDAP等,详细信息可以参阅:

    https://zero-to-jupyterhub.readthedocs.io/en/latest/authentication.html

    但是如果条件不允许,JupyteHub可否支持基于常见数据库(MySQL、SQLite)的Authentication方法了?答案是肯定的,但是需要自己编写,所以接下来分别介绍基于SQLite和MySQL的身份验证方法,详细代码请参考我的https://github.com/tygxy/jupyterhub_localauthenticor

    2. JupyteHub Authentication Based on SQLite

    2.1 编写sqliteauthenticator包

    首先需要完成sqliteauthenticator的基本功能,其包结构如图所示:


    1554261481417.jpg

    核心的模块就是实现SQLiteAuthenticator类,很简单,只需要从SQLite的DB中查询数据做匹配即可,我这里为了演示,密码用了明文。

    # coding:utf-8
    
    from jupyterhub.auth import Authenticator
    from tornado import gen
    
    import os
    import sqlite3
    
    
    class SQLiteAuthenticator(Authenticator):
    
        """JupyterHub Authenticator Based on SQLite"""
    
        def __init__(self, **kwargs):
            super(SQLiteAuthenticator, self).__init__(**kwargs)
    
        @staticmethod
        def _verify_password(username, password):
            try:
                # to define sqlite db location in hub images
                os.environ["JUPYTERHUB_SQLITEDB_PATH"]="/home/jovyan/user.db"
    
                sql_cnn = sqlite3.connect(os.getenv('JUPYTERHUB_SQLITEDB_PATH'))
                cursor = sql_cnn.cursor()
                sql = ("SELECT `password` FROM users WHERE `username` = '{}'").format(username)
                cursor.execute(sql)
    
                user_passwd = cursor.fetchone()[0]
                input_passwd = password
    
                if user_passwd == input_passwd:
                    cursor.close()
                    sql_cnn.close()
                    return True
                else:
                    cursor.close()
                    sql_cnn.close()
                    return False
            except:
                cursor.close()
                sql_cnn.close()
                return False
    
        @gen.coroutine
        def authenticate(self, handler, data):
            username = data['username']
            passwd = data['password']
    
            if self._verify_password(username, passwd):
                return data['username']
            else:
                return None
    

    2.2 创建SQLite用户表

    第二步需要创建users表,基本操作这里就不赘述了。如果对SQLite不熟悉的同学可以网上找找资料,很简单。库名就叫user.db,表名叫users,表的结构如图所示:

    1554262124230.jpg

    插入一条记录,以备后续验证。

    insert into users (username,password) values ('kjsx-guoxingyu','123456')
    

    2.3 拷贝内容到镜像

    第三步需要把前两步的内容拷贝到jupyter/k8s-hub镜像中,这个镜像是官网自带的hub镜像,我们直接在此镜像上添加内容就可以了,步骤如下,具体的命令我就不写了,自行查找。

    • docker 先启一个hub镜像,用到的命令docker run
    • 查看该镜像container id,用到的命令docker ps
    • 拷贝user.db到镜像中,用到的命令docker cp,注意路径要跟sqliteauthenticator.py里保持一致,我这里是/home/jovyan/
    • 拷贝sqliteauthenticator包,注意路径是pip3保持包的路径。在该镜像中,是/home/jovyan/.local/lib/python3.6/site-packages下。这样运行时才能import到该包,如图:
      1554270146882.jpg
    • 保存该镜像,用到的命令是docker commit,可以指定Tag

    2.4 修改配置文件

    最后需要修改一些配置文件,在values.yaml中,包括:

    • auth:type: custom
    • auth:custom:className: sqliteauthenticator.SQLiteAuthenticator
    • hub.image.tag: 0.1.0 (需要和保存的镜像的tag匹配上,我这里是0.1.0)

    2.5 启动服务

    到此为止,基于SQLite的身份认证应该就可以用了,重新启动我们的jupyterhub服务,在登录页面验证一下,如图当username是kjsx-guoxingyu1的时候,显示的是Invalid username or password。

    1554270759313.jpg

    3. JupyteHub Authentication Based on MySQL

    基本上MySQL的身份认证和SQLite差不多,只有细微的差别,这里就简单叙述一下。

    3.1 编写mysqlauthenticator包

    包结构:

    1554271023757.jpg

    跟之前的差不多,只不过将MySQL的一些操作封装在了DAO里,此外使用到了sqlalchemy。具体代码就不贴了,需要的话直接去我github上看吧,也很简单。稍微需要注意的就是连接MySQL的格式:

    db_url = "mysql+mysqlconnector://root:<password>@<ip>:3306/<talbe_name>"
    

    3.2 创建MySQL用户表

    需要在一台服务器上提供MySQL服务,并创建User表,这个我就不多说了,相信大家都会。唯一注意的是要赋予mysql远程登陆的权限,否则镜像访问MySQL会报错。

    3.3 拷贝内容到镜像

    这个跟之前的一样,把mysqlauthenticator包放在pip3的安装路径下,此外还需要安装一些包,包括

    • pip3 install wheel
    • pip3 install sqlalchemy
    • pip3 install mysql-connector

    3.4 修改配置文件

    • auth:type: custom
    • auth:custom:className: mysqlauthenticator.MysqlAuthenticator
    • hub.image.tag: 0.1.0 (需要和保存的镜像的tag匹配上,我这里是0.1.0)

    3.5 启动服务

    效果一样,这里贴一张认证成功的效果

    1554271904139.jpg

    4. 总结

    整体来说,这部分自定义身份认证的参考资料很少,只能自己摸索和试错。所以我也花了一些时间。两种基于SQLite和MySQL的JupyterHub认证方式我都在自己Mac上,和服务器的测试集群上试过,均可用。当然这里也只是一个demo,更成熟可靠的代码,还需要进一步迭代,希望帮助到大家。

    5. 参考文献

    相关文章

      网友评论

        本文标题:JupyterHub on Kubernetes的SQLite、

        本文链接:https://www.haomeiwen.com/subject/hrczbqtx.html