新闻详情

新闻详情

首页 / 资讯中心 / 详情

JupyterHub 技术架构深度解析:Hub、Proxy 与单用户 Notebook 服务器的协作原理

发布时间:2026/9/26 10:15:19来源:尧图网络
JupyterHub 技术架构深度解析:Hub、Proxy 与单用户 Notebook 服务器的协作原理
后端微服务【免费下载链接】jupyterhubMulti-user server for Jupyter notebooks项目地址https://gitcode.com/gh_mirrors/ju/jupyterhub点击查看免费下载JupyterHub 是一个为多人团体提供单用户 Jupyter Notebook 服务器的多用户系统。本文以官方文档的 Technical Overview 为核心结合仓库源码系统讲解 JupyterHub 的三大核心子系统Hub、Proxy、Single-User Notebook Server、它们之间的请求路由机制、从用户访问到登录完成的完整时序以及默认部署形态与两大扩展点Authenticator、Spawner。读完本文你将理解 JupyterHub 的整体运行原理掌握其默认端口、持久化文件、Cookie 加密与认证配置的底层细节并知道如何通过自定义认证器与启动器把 JupyterHub 接入你的组织环境。JupyterHub 的三大核心子系统JupyterHub 本质上是一组进程的集合这些进程协同工作为群体中的每个人提供一个专属的单用户 Jupyter Notebook 服务器。由jupyterhub命令行程序启动的三个子系统分别是子系统技术栈职责HubPython / Tornado管理用户账户与认证并通过 Spawner 协调各个单用户 Notebook 服务器的启动与生命周期Proxy动态代理默认是 configurable-http-proxy基于 node-http-proxyJupyterHub 面向公众的部分负责把 HTTP 请求路由到 Hub 与各单用户 Notebook 服务器Single-User Notebook ServerPython / Tornado用户登录时为每个系统用户启动一个专属的 Jupyter Notebook 服务器启动它的对象就是 Spawner其中Hub是大脑它负责账户数据库、认证流程、Spawner 编排与 APIProxy是门面它是唯一对外暴露的进程所有外部流量都从这里进入Single-User Notebook Server则是每个用户真正执行代码的工作环境。三者之间通过明确的 URL 前缀与内部 API 互相通信。子系统如何交互请求路由的幕后机制用户通过浏览器访问 JupyterHub 所在服务器的 IP 或域名。其基本运作原则可以归纳为四点Hub 启动 Proxy在默认配置下Proxy 是 Hub 的子进程Proxy 默认把所有请求转发给 HubHub 处理登录并按需 spawn 单用户 Notebook 服务器Hub 配置 Proxy将 URL 前缀转发到对应的单用户服务器。关键的网络拓扑是Proxy 是唯一监听公共接口的进程。Hub 位于 Proxy 之后的/hub路径下单用户服务器位于/user/[username]路径下。也就是说外部流量永远先到达 Proxy再由 Proxy 按前缀路由分发。这一点在源码中有直接印证。jupyterhub/app.py 中hub_prefix默认值由base_url拼接得到hub_prefix URLPrefix( /hub/, helpThe prefix for the hub server. Always /base_url/hub/ ) default(hub_prefix) def _hub_prefix_default(self): return url_path_join(self.base_url, /hub/)而 Proxy 的路由注册逻辑集中在 jupyterhub/proxy.py 中例如add_user(user, server_name)、add_route(routespec, target, data)等方法负责把/user/[username]/*这样的前缀动态绑定到实际运行的单用户服务器地址上。同时hub_routespec默认是应用的base_url而非/hub/保证当用户的服务器未运行时Hub 仍然能收到/user/:name的请求并做出响应见 jupyterhub/app.py。从访问 JupyterHub 到用户登录的完整流程当用户访问 JupyterHub 时依次发生以下事件登录数据被交给Authenticator实例进行校验登录信息有效时Authenticator 返回用户名系统为已登录用户spawn一个单用户 Notebook 服务器实例由 Spawner 负责单用户服务器启动后通知 Proxy 把对/user/[username]/*的请求转发到该服务器在/hub/路径下设置一个Cookie内含加密令牌在 0.8 版本之前还会额外设置/user/[username]路径的 Cookie浏览器被重定向到/user/[username]随后的请求由单用户 Notebook 服务器处理。单用户服务器如何通过 OAuth 与 Hub 确认身份那么单用户服务器是如何识别请求者的身份、并与 Hub 完成认证的呢标准流程如下单用户服务器在收到请求时先检查 Cookie若没有 Cookie则重定向到 Hub通过OAuth进行身份验证在 Hub 完成验证后浏览器被重定向回单用户服务器令牌被验证并存入 Cookie若始终无法识别用户身份浏览器最终被重定向回/hub/login。这段 OAuth 交互在 jupyterhub/singleuser/extension.py 中有完整实现单用户服务器通过hub_authHubAuth见 jupyterhub/services/auth.py与 Hub 通信注册/oauth_callback回调处理器并重写登录重定向逻辑以避免 403 或重定向死循环。相关测试见 jupyterhub/tests/test_singleuser.py如test_singleuser_auth、test_token_url_cookie。登录认证本身则由 Authenticator 控制访问权限。默认的 PAM Authenticator 使用 JupyterHub 运行所在服务器上的系统用户账户这意味着你需要为团队中的每个用户创建系统账户。而更换为其他 Authenticator 后用户就可以用 GitHub 账户、或组织已有的任意单点登录SSO系统登录。默认行为开箱即用的部署形态监听地址与端口默认情况下Proxy监听所有公共接口的8000 端口因此你可以通过以下任一方式访问 JupyterHubhttp://localhost:8000或任何指向该系统的公网 IP / 域名这一默认值定义在 jupyterhub/app.py 的port配置项默认8000与bind_url默认http://:8000见 jupyterhub/app.py。而 Hub 与各单用户服务器在默认配置下只在 localhost 上互相通信不直接暴露到公网。启动时写入磁盘的两个文件默认启动 JupyterHub 时会在当前工作目录写入两个文件jupyterhub.sqlite保存 Hub 全部状态的 SQLite 数据库。该文件让 Hub 能够记住哪些用户正在运行、运行在哪里以及其他信息从而支持单独重启 JupyterHub 的各个部分。需要特别注意的是除 Hub 用户名外该数据库不包含任何敏感信息Hub 在存储前会对各类令牌做哈希处理。jupyterhub_cookie_secret用于加密 Cookie 的密钥文件。该文件必须持久存在否则 Hub 重启会使得所有 Cookie 失效反过来删除此文件并重启服务器即可使全部登录 Cookie 作废。这两个文件的路径都可以通过配置项修改。在 jupyterhub/app.py 中db_url默认值为sqlite:///jupyterhub.sqlite并且如果直接给出纯文件名不含://会自动被补全为sqlite:///前缀的 SQLite URL。Cookie 密钥文件的默认名与路径则由cookie_secret_file定义cookie_secret_file Unicode( jupyterhub_cookie_secret, helpFile in which to store the cookie secret. )社区推荐的目录布局是所有配置文件放在标准的 UNIX 系统目录/etc/jupyterhub所有安全与运行时文件放在/srv/jupyterhub。相应的配置示例c.JupyterHub.cookie_secret_file /srv/jupyterhub/jupyterhub_cookie_secret c.JupyterHub.db_url sqlite:////srv/jupyterhub/jupyterhub.sqliteCookie 密钥的三种配置方式Cookie 密钥应为32 字节随机数源码中COOKIE_SECRET_BYTES即 32见 jupyterhub/app.py。以下三种方式均可在 安全设置文档 中找到完整说明1. 使用密钥文件推荐需要持久化以维持登录状态openssl rand -hex 32 /srv/jupyterhub/jupyterhub_cookie_secretc.JupyterHub.cookie_secret_file /srv/jupyterhub/jupyterhub_cookie_secret若文件不存在Hub 启动时会自动生成并写入新密钥见 jupyterhub/app.py。该文件不得被group或other读取否则服务拒绝启动推荐权限为600。2. 使用环境变量避免文件依赖export JPY_COOKIE_SECRET$(openssl rand -hex 32)该环境变量在 jupyterhub/app.py 中被声明为cookie_secret的默认来源envJPY_COOKIE_SECRET。出于安全考虑它只应让 Hub 进程可见若每次启动都动态生成所有用户每次 Hub 重启都会被登出。3. 直接写在配置文件中二进制字符串c.JupyterHub.cookie_secret bytes.fromhex(64 CHAR HEX STRING)此外ConfigurableHTTPProxy.api_token用于 Hub 与 Proxy 之间的认证CONFIGPROXY_AUTH_TOKEN环境变量亦可。若未设置Hub 会自行生成随机令牌这意味着重启 Hub 时必须同时重启 Proxy——在默认配置下 Proxy 是 Hub 的子进程这一过程会自动完成。详情见 安全设置文档的 Proxy 认证令牌章节。JupyterHub 认证相关的 CookieHub 与单用户服务器之间通过以下几类 Cookie 协同完成认证详见 security-basics.mdCookie 名称作用路径限制jupyterhub-hub-loginHub 受保护页面的登录令牌设置后即视为已登录/hub/jupyterhub-user-username单用户服务器与 Hub 完成 OAuth 后设置内含 OAuth 访问令牌/user/usernamejupyterhub-session-id随机字符串Hub 与单用户服务器唯一共享的 Cookie用于协调多个 OAuth Cookie 的登出/jupyterhub-user-username-oauth-state短暂存在的 OAuth 状态校验 Cookie仅存在于 OAuth 处理过程中/user/username重置 Hub 的 Cookie 密钥会同时使jupyterhub-hub-login与jupyterhub-user-username失效。定制 JupyterHubAuthenticator 与 Spawner 两大扩展点JupyterHub 提供两个基础扩展点分别对应谁可以登录与如何为用户启动服务器两个问题Authenticator认证器控制用户如何被认证参考 Authenticators 文档Spawner启动器控制用户的单用户服务器进程如何被启动参考 Spawners 文档。两者都对应一个可定制类JupyterHub 为每个都内置了基础默认实现。默认 Spawner 会在同一台机器上以用户的系统用户名启动 Notebook 服务器另一种常见做法是用 Docker 等方案把每个服务器启动在独立容器中。编写自定义认证器与启动器启用自定义认证与启动的方式是继承Authenticator或Spawner并重写相关方法。以认证器为例核心可重写方法包括authenticate()校验登录数据并返回用户名与check_allowed()判断用户是否被允许登录完整的接口方法可以在 jupyterhub/auth.py 中看到例如PAMAuthenticator的authenticate、system_user_exists、add_system_user等实现以及与allowed_users、allow_all、check_allow_config相关的允许/阻止逻辑。以启动器为例需要重写的核心方法是start()启动服务器并返回其实际地址与poll()检查服务器是否存活、stop()停止服务器这些定义在 jupyterhub/spawner.py 中。仓库还提供了完整的测试参考例如 jupyterhub/tests/test_spawner.py 中的test_spawner、test_spawner_poll、test_single_user_spawner等用例以及 jupyterhub/tests/test_auth.py 中对 PAM 认证行为的验证。配置方式JupyterHub 使用 Python 配置文件jupyterhub_config.py可通过jupyterhub --generate-config生成所有定制都是对c.Authenticator.*与c.Spawner.*命名空间下的 traitlet 属性赋值。例如c.JupyterHub.authenticator_class myauth.MyAuthenticator # 或直接指定类对象 c.JupyterHub.spawner_class mydocker.MyDockerSpawner # Authenticator 示例配置 c.MyAuthenticator.allowed_users {alice, bob} # Spawner 示例配置 c.MySpawner.default_url /lab关键配置与源码对照表为了便于排查与二次开发下表汇总了本文涉及的默认行为与对应的源码位置默认行为 / 配置项默认值源码位置Proxy 监听端口port8000jupyterhub/app.py对外绑定地址bind_urlhttp://:8000jupyterhub/app.pyHub 前缀hub_prefixbase_url /hub/jupyterhub/app.pyHub 路由规格hub_routespec应用base_url未设置 subdomain 时jupyterhub/app.py数据库db_urlsqlite:///jupyterhub.sqlitejupyterhub/app.pyCookie 密钥文件cookie_secret_filejupyterhub_cookie_secretjupyterhub/app.pyCookie 密钥可从环境变量读取32 字节随机数jupyterhub/app.py动态路由注册add_user/add_route等jupyterhub/proxy.py总结JupyterHub 的架构核心在于一个公共代理 一个中枢 Hub 若干按需启动的单用户服务器这一分工Proxy 对外统一收口Hub 负责认证与编排单用户服务器为用户提供隔离的专属环境。理解这套子系统协作机制与默认行为是正确部署、排障以及自定义扩展认证器、启动器的前提。若需进一步深入建议继续阅读 Spawners 参考文档、Authenticators 参考文档、安全设置教程以及 Proxy 配置指南 与 独立部署 Proxy 指南。赞分享后端微服务【免费下载链接】jupyterhubMulti-user server for Jupyter notebooks项目地址https://gitcode.com/gh_mirrors/ju/jupyterhub点击查看免费下载相关推荐TogetherJS架构深度剖析客户端与Hub服务器的完美协作TogetherJS是一个令人惊喜的实时协作服务它通过客户端与Hub服务器的高效协作让网站轻松实现多用户实时交互。TogetherJS的核心架构由两个主要组即时通讯前端后端JupyterHub 架构概念全解Authenticator、Spawner、Proxy、Services 与单用户服务器/内核的分层解析JupyterHub 架构概念全解Authenticator、Spawner、Proxy、Services 与单用户服务器/内核的分层解析 JupyterHu后端微服务JupyterHub 单用户服务器jupyterhub-singleuser 命令与 OAuth 认证实现原理JupyterHub 单用户服务器jupyterhub singleuser 命令与 OAuth 认证实现原理 本文基于 JupyterHub 仓库中的官方说后端微服务上一篇ThingsBoard实战上手Docker十分钟部署从MQTT设备接入到实时告警仪表盘下一篇PSReadLine终极故障排除指南10个常见问题快速解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【Jetpack Compose娓娓道来】 第22课:Kotlin Multiplatform深入实践——从“共享UI“到“共享一切“ 2026/9/26 11:08:50

【Jetpack Compose娓娓道来】 第22课:Kotlin Multiplatform深入实践——从“共享UI“到“共享一切“

一、先讲一个真实的故事 我见过一个团队,用Compose Multiplatform把Android应用移植到了iOS。移植完成后,他们发现一个尴尬的事实:共享的代码只有UI层。 网络请求用的是平台各自的库——Android用Retrofit,iOS用Alamofire。数据库…

阅读更多 →
LeetCode:合并两个有序链表 2026/9/26 11:08:44

LeetCode:合并两个有序链表

题目:解题思路:1.建立一个虚拟头结点ListNode dummy,声明cur 是我们用来拼接链表的“指针尾巴”,并取空节点的指针地址赋值给cur;2.通过判断两个链表不为空,进行循环比较;3.通过循环比较两链表的值&#xf…

阅读更多 →
AUTOSAR CP通信栈基础:ComStack_Types核心类型解析与工程实践 2026/9/26 11:08:44

AUTOSAR CP通信栈基础:ComStack_Types核心类型解析与工程实践

1. 从一次编译报错说起:ComStack_Types到底管什么第一次接触AUTOSAR CP通信栈的人,十有八九会在某个时刻被一个看似莫名其妙的编译错误拦住。我印象很深的一次,是在集成一个CAN通信模块时,代码里引用了PduInfoType,头文…

阅读更多 →
代码直接变论文!MSRA同款Agent库开源,读Repo一键生成初稿:TaoToken统一Key接入配置与验证 2026/9/26 11:08:44

代码直接变论文!MSRA同款Agent库开源,读Repo一键生成初稿:TaoToken统一Key接入配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
AI-Agent科研全链路实战营:用TaoToken统一Key打通LLM+NotebookLM+N8N+Claude Code+Codex自动化编程与文献管理 2026/9/26 11:08:44

AI-Agent科研全链路实战营:用TaoToken统一Key打通LLM+NotebookLM+N8N+Claude Code+Codex自动化编程与文献管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
FDE工程师:AI落地最后一公里,收藏这份小白程序员进阶指南 2026/9/26 11:08:37

FDE工程师:AI落地最后一公里,收藏这份小白程序员进阶指南

FDE(前沿部署工程师)是AI落地的关键角色,负责将AI技术嵌入客户现场并确保其有效运行。文章从FDE的概念、起源、市场空间、竞争格局、产业链和相关龙头等多个维度进行解析,强调FDE在AI产业中的重要性,并展望了FDE的未来…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉