服务#

JupyterHub 服务(不要与 Kubernetes 服务对象混淆)是与 JupyterHub API 交互的进程。 nbgrader清理空闲笔记本 是生产服务的例子,在 Jupyterhub 示例仓库 中有“hello world”服务的最小示例。

服务可以从 Hub 外部运行,这意味着它们独立于 Hub 启动和停止,并且必须自行了解 Hub 身份验证令牌等信息。或者,服务可以是 Hub 管理的,在这种情况下,Hub 会启动和停止进程,并通过环境变量将关键信息传递给服务。

z2jh 中的 Hub 管理服务#

Hub 管理的服务将在与 Hub 本身相同的容器/Pod 中运行。首先,您需要将服务的相关文件安装或复制到您的 Hub 镜像中,方法是创建从 jupyterhub/k8s-hub 派生的自定义镜像,或者使用 hub.extraFiles 配置。请记住,您的 Hub 容器可能需要安装依赖库,例如 flask 或 fastapi,具体取决于服务。在这些情况下,您需要一个自定义镜像。

除了服务代码之外,您还需要修改 Hub Kubernetes 服务对象以包含 多个端口,并更新 Hub 网络策略。如果您想允许来自所有来源的访问,可以使用 hub.networkPolicy.allowedIngressPorts。否则,如果您想更精确地控制访问,可以使用 hub.networkPolicy.ingress.

示例服务#

在以下代码片段中,我使用了一个自定义镜像,它复制了应用程序代码并安装了 fastapi 服务示例 中列出的依赖项。

# Dockerfile
# 3.1.0 is latest stable release at the time of this writing
# Find all tags in https://quay.io/repository/jupyterhub/k8s-hub?tab=tags
FROM quay.io/jupyterhub/k8s-hub:3.1.0

# Depending on version, the k8s-hub image may have installed
# pip packages as root, forcing you to install as root as well
USER root
COPY ./service-fastapi /usr/src/fastapi
RUN python3 -m pip install -r /usr/src/fastapi/requirements.txt

USER ${NB_USER}
# config.yaml

hub:
  image:
    name: myregistry/my-custom-hub-image
    tag: latest

  services:
    fastapi:
      url: http://hub:8181
      command:
        - /home/jovyan/.local/bin/uvicorn
        - app:app
        - --port
        - "8181"
        - --host
        - "0.0.0.0"
        - --app-dir
        - /usr/src/fastapi
      oauth_redirect_uri: https://jupyterhub.mycloud.com/services/fastapi/oauth_callback
      environment:
        PUBLIC_HOST: https://jupyterhub.mycloud.com

  networkPolicy:
    ingress:
      - ports:
          - port: 8181
        from:
          - podSelector:
              matchLabels:
                hub.jupyter.org/network-access-hub: "true"

  service:
    extraPorts:
      - port: 8181
        targetPort: 8181
        name: fastapi

# The proxy.chp.networkPolicy.egress configuration below is required if the
# service should be accessible for users. If it shouldn't be, you should instead
# set the chart configuration services.fastapi.display to false as otherwise
# JupyterHub will provide a broken link in the Services menu for users to go to
# /services/fastapi/.
proxy:
  chp:
    networkPolicy:
      egress:
        - to:
            - podSelector:
                matchLabels:
                  app: jupyterhub
                  component: hub
          ports:
            - port: 8181