在完成JupyteHub on k8s的基本部署后翔悠,還需要一些用戶定制的自定義配置业崖,本文重點介紹JupyterHub的身份驗證(Authentication)。
1. JupyteHub自帶的Authentication方法
默認條件下蓄愁,JupyterHub允許用戶輸入任意的用戶名和密碼双炕,登錄注冊自己的Jupyter Notebook。顯然這種模式不符合生產(chǎn)要求撮抓,必須有一套身份認證機制妇斤。
根據(jù)官網(wǎng)的描述,JupyterHub自帶了一些身份認證方法丹拯,比如Dummy站超、OAuth2、LDAP等乖酬,詳細信息可以參閱:
https://zero-to-jupyterhub.readthedocs.io/en/latest/authentication.html
但是如果條件不允許死相,JupyteHub可否支持基于常見數(shù)據(jù)庫(MySQL、SQLite)的Authentication方法了剑刑?答案是肯定的媳纬,但是需要自己編寫,所以接下來分別介紹基于SQLite和MySQL的身份驗證方法施掏,詳細代碼請參考我的https://github.com/tygxy/jupyterhub_localauthenticor
2. JupyteHub Authentication Based on SQLite
2.1 編寫sqliteauthenticator包
首先需要完成sqliteauthenticator的基本功能钮惠,其包結(jié)構如圖所示:
核心的模塊就是實現(xiàn)SQLiteAuthenticator類,很簡單七芭,只需要從SQLite的DB中查詢數(shù)據(jù)做匹配即可素挽,我這里為了演示,密碼用了明文狸驳。
# 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 創(chuàng)建SQLite用戶表
第二步需要創(chuàng)建users表预明,基本操作這里就不贅述了缩赛。如果對SQLite不熟悉的同學可以網(wǎng)上找找資料,很簡單撰糠。庫名就叫user.db酥馍,表名叫users,表的結(jié)構如圖所示:
插入一條記錄阅酪,以備后續(xù)驗證旨袒。
insert into users (username,password) values ('kjsx-guoxingyu','123456')
2.3 拷貝內(nèi)容到鏡像
第三步需要把前兩步的內(nèi)容拷貝到jupyter/k8s-hub鏡像中,這個鏡像是官網(wǎng)自帶的hub鏡像术辐,我們直接在此鏡像上添加內(nèi)容就可以了砚尽,步驟如下,具體的命令我就不寫了辉词,自行查找必孤。
- 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。
3. JupyteHub Authentication Based on MySQL
基本上MySQL的身份認證和SQLite差不多脐瑰,只有細微的差別妖枚,這里就簡單敘述一下。
3.1 編寫mysqlauthenticator包
包結(jié)構:
跟之前的差不多苍在,只不過將MySQL的一些操作封裝在了DAO里绝页,此外使用到了sqlalchemy荠商。具體代碼就不貼了,需要的話直接去我github上看吧续誉,也很簡單莱没。稍微需要注意的就是連接MySQL的格式:
db_url = "mysql+mysqlconnector://root:<password>@<ip>:3306/<talbe_name>"
3.2 創(chuàng)建MySQL用戶表
需要在一臺服務器上提供MySQL服務,并創(chuàng)建User表酷鸦,這個我就不多說了饰躲,相信大家都會。唯一注意的是要賦予mysql遠程登陸的權限井佑,否則鏡像訪問MySQL會報錯属铁。
3.3 拷貝內(nèi)容到鏡像
這個跟之前的一樣,把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 啟動服務
效果一樣盒发,這里貼一張認證成功的效果
4. 總結(jié)
整體來說例嘱,這部分自定義身份認證的參考資料很少,只能自己摸索和試錯宁舰。所以我也花了一些時間拼卵。兩種基于SQLite和MySQL的JupyterHub認證方式我都在自己Mac上,和服務器的測試集群上試過蛮艰,均可用腋腮。當然這里也只是一個demo,更成熟可靠的代碼壤蚜,還需要進一步迭代即寡,希望幫助到大家。