JupyterHub

提供: ArchWiki
2023年8月20日 (日) 18:35時点におけるKusanaginoturugi (トーク | 投稿記録)による版 (→‎ルートユーザーとしての実行: リンクを修正)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

JupyterHubは、Jupyterノートブックのためのマルチユーザーウェブサーバーです。4つのサブシステムから構成されています。

  1. メインハブプロセス
  2. Authenticators はユーザーを認証します。
  3. Spawners は接続された各ユーザーのシングルユーザーサーバーを起動し、監視します。
  4. HTTP プロキシ 受信したリクエストをハブまたは適切なシングルユーザーサーバーにルーティングします。

詳しくは JupyterHub ドキュメントの technical overview を参照してください。

インストール

jupyterhubAUR パッケージをインストールします。ほとんどの場合、jupyter-notebook パッケージもインストールする必要があります(より高度な spawners は必要ない場合もあります)。また、jupyterlab パッケージをインストールすると、JupyterLab インターフェイスを利用できるようになります。

起動

jupyterhub.service開始/有効化します。デフォルトの設定では、ブラウザで 127.0.0.1:8000 にアクセスしてハブにアクセスできます。

設定

JupyterHub の設定ファイルは /etc/jupyterhub/jupyterhub_config.py に置かれています。これは、設定オブジェクト c を変更する Python スクリプトです。パッケージが提供する設定ファイルには、利用可能な設定オプションとそのデフォルト値が表示されます。

設定中の相対パスは、ハブが実行される作業ディレクトリから解決されます。パッケージが提供する systemd サービスは作業ディレクトリとして /etc/jupyterhub を使用します。これは、例えばデフォルトのデータベース URL c.JupyterHub.db_url = 'sqlite:///jupyterhub.sqlite' がファイル /etc/jupyterhub/jupyterhub.sqlite に対応することを意味しています。

全ての設定オプションはコマンドライン上で上書きすることができます。例えば、設定ファイルの設定 c.Application.show_config = True は、代わりにコマンドラインフラグ --Application.show_config=True で設定することが可能です。提供される systemd サービスはコマンドラインを使用して c.JupyterHub.pid_filec.ConfigurableHTTPProxy.pid_file をランタイムのディレクトリに明示的に設定するので、設定ファイルにそれらの値があっても無視されることに注意しましょう。

Authenticators

Authenticators はハブと単一ユーザーサーバへのアクセスを制御します。Authenticators セクションのドキュメントには、Authenticators の動作方法やカスタム Authenticator の作成方法についての詳細が含まれています。Authenticators のwikiページには、Authenticators のリストがあり、その中にはAURパッケージを持つものもあり、以下で説明されています。

ユーザーのステータスは、cookie secretによって暗号化されたクッキーに保存されていることに注意してください。異なる Authenticator に切り替える場合、または選択した Authenticator の設定を変更して許可されるユーザーのリストが変更される可能性がある場合は、cookie secretを変更する必要があります。これにより、現在のすべてのユーザーがログアウトされ、新しい設定で再認証を行う必要があります。これは、cookie secretファイルを削除してハブを再起動することで実行でき、新しいシークレットが自動的に生成されます。デフォルトの設定では、cookie secretは/etc/jupyterhub/jupyterhub_cookie_secretに保存されています。

PAM Authenticator

PAM Authenticator は、PAM を使用してローカルユーザーがハブにログインできるようにします。これは JupyterHub に含まれており、デフォルトの Authenticator です。これを使用するには、ハブがユーザーパスワードのハッシュバージョンを含む /etc/shadow の読み取り権限を持っている必要があります。デフォルトでは、/etc/shadow は root が所有し、ファイル権限-rw------ ですので、root としてハブを実行するとこの要件が満たされます。一部の情報源は、/etc/shadow からすべての権限を削除して、侵害されたデーモンによって読み取られないようにし、アクセスが必要なプロセスに DAC_OVERRIDE ケイパビリティを付与することを推奨しています。もしあなたの /etc/shadow がこのように設定されている場合、この機能を JupyterHub に付与するためのドロップインファイルを作成してください:

/etc/systemd/system/jupyterhub.service.d/override.conf
[Service]
CapabilityBoundingSet=CAP_DAC_OVERRIDE

PAM Authenticator は Python パッケージ pamela に依存しています。基本的なトラブルシューティングはコマンドラインでテストすることができます。ユーザー testuser として認証を試みるには、次のコマンドを実行してください:

# python -m pamela -a testuser

(JupyterHub を非 root ユーザーとして実行する場合は、root の代わりにそのユーザーとしてコマンドを実行してください)。認証が成功すると、出力は表示されません。失敗するとエラーメッセージが表示されます。

非 root ユーザーとしての PAM 認証

JupyterHub を非 root ユーザーとして実行する場合、そのユーザーに shadow ファイルの読み取り権限を付与する必要があります。JupyterHub のドキュメントで推奨されている方法は、shadow グループを作成し、このグループに shadow ファイルを読み取り可能にし、JupyterHub ユーザーをこのグループに追加することです。

警告: これにより、/etc/shadow 内のハッシュ化されたパスワードへの読み取り専用アクセスが JupyterHub ユーザーとしてコードを実行する全てのユーザーに許可されます。各単一ユーザーサーバーは自分のアカウントで実行されるため、それらのサーバーで実行されるコードはアクセス権を持っていないことに注意してください。また、JupyterHub のセキュリティエクスプロイトが root として JupyterHub を実行していた場合、同じハッシュ化されたパスワードへのアクセスが許可されることも注意してください。

グループを作成し、shadow ファイルの権限を変更し、ユーザー jupyterhub をグループに追加することは、次の4つのコマンドで実行できます:

# groupadd shadow
# chgrp shadow /etc/shadow
# chmod g+r /etc/shadow
# usermod -aG shadow jupyterhub

Spawners(スポーナー)

スポーナーは、各ユーザーのノートブックサーバーを起動し、監視する責任があります。documentation には、スポーナーの動作やカスタムスポーナーの作成方法についての詳しい情報が含まれています。wiki page には、いくつかの Spawners のリストがあり、その中には AUR パッケージがあるものも含まれ、以下で説明されています。

LocalProcessSpawner

これは JupyterHub に含まれるデフォルトのスポーナーです。各シングルユーザーサーバーを、それぞれのユーザーアカウントでローカルプロセスとして実行します(これは、各 JupyterHub ユーザーがローカルのユーザーアカウントに対応している必要があることを意味します)。また、異なるユーザーアカウントでプロセスを起動できるように、JupyterHub を root として実行する必要があります。このスポーナーを動作させるためには、jupyter-notebook パッケージがインストールされている必要があります。

SudoSpawner

SudoSpawner は、sudo で作成された中間プロセスを使用して、シングルユーザーサーバーを起動します。これにより、JupyterHub プロセスを 非 root ユーザーとして実行 することができます。使用するには、jupyterhub-sudospawnerAUR パッケージをインストールしてください。

それを使用するために、システムユーザーアカウントを作成 してください(以下では、アカウントが jupyterhub という名前であると仮定しています)と、ハブにアクセスできるユーザーを定義するグループを作成します(ここでは、jupyterhub-users と呼ばれると仮定しています)。まず、jupyterhub ユーザーがパスワードなしでサーバーを起動できるように、sudo を設定する必要があります。drop-in sudo 設定ファイルvisudo で作成します。

# visudo -f /etc/sudoers.d/jupyterhub-sudospawner
# The command the hub is allowed to run.
Cmnd_Alias SUDOSPAWNER_CMD = /usr/bin/sudospawner

# Allow the jupyterhub user to run this command on behalf of anybody
# in the jupyterhub-users group.
jupyterhub ALL=(%jupyterhub-users) NOPASSWD:SUDOSPAWNER_CMD

デフォルトのサービスファイルは、ハブを root として実行します。また、サービスの機能を制限するためのさまざまな強化オプションを適用します。この強化により、sudo が動作しなくなります。これを許可するためには、NoNewPrivileges サービスオプション(およびそれを暗黙的に設定する他のオプション、サービスオプションのリストについては systemd.exec(5) を参照)をオフにする必要があります。jupyterhub ユーザーを使用してハブを実行するためのドロップインファイルを作成してください。

/etc/systemd/system/jupyterhub.service.d/override.conf
[Service]
User=jupyterhub
Group=jupyterhub

# Required for sudo.
NoNewPrivileges=false

# Setting the following would implicitly set NoNewPrivileges.
PrivateDevices=false
ProtectKernelTunables=false
ProtectKernelModules=false
LockPersonality=false
RestrictRealtime=false
RestrictSUIDGID=false
SystemCallFilter=
SystemCallArchitectures=

以前、ハブを root ユーザーとして実行していた場合、ユーザーデータベースと cookie secret ファイルの所有者を変更する必要があります:

# chown jupyterhub:jupyterhub /etc/jupyterhub/{jupyterhub_cookie_secret,jupyterhub.sqlite}

PAMAuthenticator を使用している場合、非 root ユーザーとして動作するようにシステムを設定する必要があります。

最後に、JupyterHub の設定を編集し、spawner クラスを SudoSpawner に変更します:

/etc/jupyterhub/jupyterhub_config.py
c.JupyterHub.spawner_class='sudospawner.SudoSpawner'

ユーザーにハブへのアクセス権を与えるには、そのユーザーを jupyterhub-users グループに追加します:

# usermod -aG jupyterhub-users <username>

systemdspawner

systemdspawnersystemd を使用して、各ユーザーのノートブックを管理します。これにより、リソースの制限の設定、より良いプロセスの分離とサンドボックス化、動的に割り当てられたユーザーなどが可能になります。使用するには、jupyterhub-systemdspawnerAUR パッケージをインストールし、設定ファイルで spawner クラスを設定します:

/etc/jupyterhub/jupyterhub_config.py
c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner'

systemdspawner の readme によれば、現在、それを使用するには JupyterHub を root として実行する必要があります。

サービス

JupyterHub サービス は、API を通じて Hub と対話するプロセスとして定義されています。サービスは、hub によって実行されるか、スタンドアロンのプロセスとして実行することができます。

Idle culler(アイドルカラー)

idle culler サービスは、アイドル状態のシングルユーザーサーバーを自動的にシャットダウンするために使用できます。使用するには、jupyterhub-idle-cullerAUR パッケージをインストールしてください。hub を通じてサービスを実行するには、c.JupyterHub.services 設定変数にサービスの説明を追加してください:

/etc/jupyterhub/jupyterhub_config.py
import sys
c.JupyterHub.services = [
    {
        'name': 'idle-culler',
        'admin': True,
        'command': [
            sys.executable,
            '-m', 'jupyterhub_idle_culler',
            '--timeout=3600'
        ],
    }
]

コマンドラインオプションの説明や、サービスをスタンドアロンのプロセスとして実行する方法の詳細については、サービスのドキュメントまたは python -m jupyterhub_idle_culler --help の出力を参照してください。

ヒントとコツ

ルートユーザーとしての実行

デフォルトでは、メインの hub プロセスはルートユーザーとして実行されます(個々のユーザーサーバーは、spawner によって設定された対応するローカルユーザーとして実行されます)。非ルートユーザーとして実行するには、SudoSpawner を使用する必要があります(上記の他の spawners はルートとしての実行が必要です)。PAM 認証を使用している場合は、非ルートユーザー用にそれを設定する必要もあります。

リバースプロキシの使用

リバースプロキシは、外部のリクエストを JupyterHub インスタンスにリダイレクトするために使用できます。これは、1台のマシンから複数のサイトを提供したい場合や、既存のサーバーを使用してSSL を処理したい場合に便利です。JupyterHub のドキュメントの リバースプロキシの使用 セクションには、リバースプロキシとしてnginx またはApache を使用するためのサンプル設定があります。

ノート: これは JupyterHub のプロキシコンポーネントを置き換えるものではありません。これは、メインの hub またはシングルユーザーサーバーのどちらかにリクエストをルーティングするためのものです。むしろ、リバースプロキシは外部のリクエストを JupyterHub のプロキシに渡します。

他のウェブサービスをプロキシする

Jupyter Server Proxy 拡張機能を使用すると、Code Server や RStudio などの他のウェブサービスを JupyterHub の隣に実行し、それらに対して認証付きのウェブアクセスを提供できます。使用するには、python-jupyter-server-proxyAUR をインストールし、/etc/jupyter/jupyter_notebook_config.py ファイルで設定します。例えば、code-serverAUR をプロキシする場合:

/etc/jupyter/jupyter_notebook_config.py
c.ServerProxy.servers = {
  'code-server': {
    'command': [
      'code-server',
        '--auth=none',
        '--disable-telemetry',
        '--disable-update-check',
        '--bind-addr=localhost:{port}',
        '--user-data-dir=.config/Code - OSS/',
        '--extensions-dir=.vscode-oss/extensions/'
    ],
    'timeout': 20,
    'launcher_entry': {
      'title': 'VS Code'
    }
  }
}

Jupyter Server Proxy の設定に関する詳細は、ドキュメントを参照してください。