JupyterHub 生成的 Jupyter Notebook 容器没有外部网络访问

No outside network access for Jupyter Notebook container spawned by JupyterHub

所以,这就是我想要实现的目标:

除最后一部分外,我或多或少做到了这一点。我正在启动一个笔记本服务器,但它无法访问外部世界。它只能访问 Jupyter Hub(这就是它工作的原因!),没有别的。

这是我的与 DockerSpawner 相关的 Jupyter Hub 配置(我省略了 OAuth 设置,因为它们按预期工作。

# Tell JupyterHub that we want Docker Spawner to be used.
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'

# And what image should be used by the Docker Spawner
c.DockerSpawner.image = 'jupyter/scipy-notebook:7a0c7325e470'

# The Hub must listen on all interfaces.
c.JupyterHub.hub_ip = '0.0.0.0'

# And this should be the address of the Hub API
c.JupyterHub.hub_connect_ip = 'jupyterhub'

# Ask containers to connect to this network so that they can
# communicate with the Hub.
c.DockerSpawner.network_name = 'djangodockerjupyterdemo_default'

# And let's not make a mess, remove user containers when done.
c.DockerSpawner.remove = True

# We need to set the Notebook Directory
notebook_dir = '/home/jovyan/work'
c.DockerSpawner.notebook_dir = notebook_dir

# Need to tell where to mount the volumes.
c.DockerSpawner.volumes = { 'jupyterhub-user-{username}': notebook_dir }

请注意,djangodockerjupyterdemo_default 是由 docker-compose 创建的,这要归功于项目目录的名称。 (我知道这不是最好的做法,但现在我只是希望有一个最简单的例子。)

这是我的 docker-撰写:

version: "2"

services:
  database:
      image: "mysql:5.6"
      volumes:
      - ./data:/var/lib/mysql
      environment:
      - MYSQL_ROOT_PASSWORD=test123
      - MYSQL_DATABASE=oauthserver
      - MYSQL_USER=oauthadmin
      - MYSQL_PASSWORD=test123
  webapp:
    image: auth_server:latest
    volumes:
      - ./:/app
    links:
      - database:database
    environment:
      - PYTHONUNBUFFERED=1
      - ENV=DEV
      - DATABASE_HOST=database
      - DATABASE_USER=oauthadmin
      - DATABASE_DBNAME=oauthserver
      - DATABASE_PASSWORD=test123
    hostname: oauthserver.ddi.in
  jupyterhub:
    image: "jupyterhub:test"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:rw"
      - "./jupyterhub:/srv/jupyterhub"
    environment:
      - OAUTH2_AUTHORIZE_URL=http://oauthserver.ddi.in:8000/o/authorize
      - OAUTH2_TOKEN_URL=http://oauthserver.ddi.in:8000/o/token/
    hostname: jhtest.ddi.in
    links:
      - webapp:oauthserver.ddi.in

我用 https://hub.docker.com/r/defreitas/dns-proxy-server to access the JupyterHub server by saying "http://jhtest.ddi.in:8000"。

现在,一旦容器启动,我可以确认以下内容:

如何让生成的笔记本访问外界?这对我的用例至关重要(我确信这是一个合理的期望)。

PS:我注意到几乎没有任何示例涉及使用自定义 Django 应用程序设置 OAuth JupyterHub。我希望公开发布我的示例,并希望它可以构成 Jupyter Hub 文档中的资源。

您可能想在 Jupyter Discourse Forum 的 'JupyterHub' 类别下做一个非常简短的 post,突出显示此 post 以获得更多专家的关注。

所以我找到了解决方案。我总结如下。

docker-compose.yml 的调整包括向所有服务添加 network_mode: bridge。这允许容器实质上访问外部世界。然而,这样做的代价是容器无法通过简单的服务名称引用自动相互对话。但这可以使用 links.

轻松解决

下一个调整是配置 DockerSpawner 以创建使用默认桥接网络而不是其他网络的容器。对此有帮助的设置包括:

c.DockerSpawner.network_name = 'bridge'
c.DockerSpawner.use_internal_ip = True
c.DockerSpawner.extra_host_config = {'network_mode': 'bridge'}

此外,由于笔记本无法使用服务名称发现主要的 JupyterHub,因此我将 c.JupyterHub.hub_connect_ip 调整为 JupyterHub 服务的主机名。请注意,使用我的问题中提到的 dns-proxy-server 有助于将主机名解析为容器 IP。

希望这对外面的人有所帮助。我很快就会 post 在我的博客上使用整个 Django-OAuth-JupyterHub 示例。

编辑:如上所述,我写了一篇博客 post 描述如何使用 Django 和 OAuth 使 JupyterHub 对用户进行身份验证。这是link:https://vkaustubh.github.io/blog/geek/2020-02-08-integrating-jupytethub-with-django.html