wsl2環境下で作るjupyterHub dockerspawnerに他のPCからアクセスする
初めに
jupyterlab(jupyter notebook)は便利ですね。
特にJupyterHubではマルチユーザ環境が構築できてだいぶ便利です。
さらにDockerspawnerを使えばユーザ単位で環境分離できて非常に便利です。
ワークショップや社内研修で助かること間違いなしです。
非常に便利なのですがwsl2でdockerを用いたjupyterhubを作成するとlocalhostではアクセスできても別のPCからdocker内に入れないなんてことが起きます。
何とか解決できたのでもしこれからどうしてもwslでjupyterHubを立てたい!となったときの参考になればと思い共有させていただきます。
ざっくりとですが最終的には以下のような状況を目指します
要点
上の状態を達成するために重要な内容は以下の2つです。
ここ以外は基本的なdockerspawnerのjupyterhubの構築ですので特にハードルなく達成可能かと思います。
- jupyterhubのIPアドレスをlocalhostではなく明示的にwslのIPアドレスで指定する
- 指定したIPアドレスにポートフォワーディングでwindowからwslに横流しするようにする
本記事でわかること
- wsl2でdockerspawnerを用いたjupyterhubを作成する方法
- 作成したjupyterhubに同一ネットワーク内の別PCからアクセスする方法
本記事で説明しないこと
- シェルスクリプト・コマンド操作
- wsl2の導入方法
- dockerの概念・操作方法
- docker desktopでの環境構築(宗教上の理由でdocker engineを使います)
- anacondaを用いたjupyterhub環境構築(宗教上の理由もありすべてpipで行います)
- jupyterhub dockerspawnerクラスの詳細
- pipやpythonの概念・操作方法
- wsl1(区別するために明示的に1と記載してます)でのjupyterhub dockerspawner環境構築
- セキュアな通信環境(サイトのSSL化など)
- 同一ネットワーク外からのアクセス方法
- Jupyterhubのスタートアップ時自動起動設定
一般的なLinux環境での環境構築などは下記サイト様が参考になります。
JupyterHubのDockerSpawnerで起動するイメージを替える
Python初心者講習のためのJupyterHub
JupyterHubの構築
環境
今回の構築環境は以下です
- OS:Windows11
- wslイメージ: Ubuntu-20.04
- Python3.8.10
- dockerイメージ: python:3.8.13-buster
- proxyは特にない前提
各種インストール
jupyterhubのインストール
wslで構築したubuntu環境にjupyterhubをインストールしていきます。
$ sudo apt update -y
$ sudo apt upgrade -y
$ curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
$ sudo apt install nodejs -y
$ sudo python3 -m pip install jupyterhub notebook
$ sudo python3 -m pip install dockerspawner jupyterhub-nativeauthenticator
これでひとまずjupyterhubに入れるようになるはずです
$ sudo jupyterhub
Jupyterhub is now running at ~以下をブラウザでコピペして入れることを確認しましょう
次はdockerspawnerでユーザ事に空間を分離できるようにDockerを導入します
dockerのインストール
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
$ sudo add-apt-repository "deb[arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt update -y
$ sudo apt install -y docker-ce docker-ce-cli containerd.io
インストールできたらコマンドを打って確認してみましょう
$ sudo docker version
Client: Docker Engine - Community
Version: 20.10.17
API version: 1.41
Go version: go1.17.11
Git commit: 100c701
Built: Mon Jun 6 23:02:57 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
環境構築
フォルダの作成
dockerfileとjupyterの設定ファイルを保存するためのフォルダを用意し、その中にそれぞれDockerfileとjupyterhub_config.pyを作成します
ここらへんのディレクトリ構造はお好みで大丈夫です
$ mkdir ~/jupyter
$ mkdir ~/docker
$ touch ~/jupyter/jupyterhub_config.py
$ touch ~/docker/Dockerfile
Dockerイメージの作成
各ユーザー毎に割り当てるためのdockerイメージを作成していきます。
Dockerfileの作成
先ほど作ったDockerfileを書き換えてください
ソースコード
FROM python:3.8.13-buster
# rootユーザでないとノートブックが新規作成できないらしい
USER root
# お好みでワークスペースを作成
WORKDIR /root/workspace
RUN apt update
# timezoneの設定
RUN apt install -y tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV TZ=Asia/Tokyo
# 無駄なキャッシュを削除してなるべくイメージ容量を小さくする
RUN apt autoremove
RUN apt clean
RUN rm -r /var/lib/apt/lists/*
# 計算機関連のライブラリをインストールする
RUN pip install --no-cache-dir numpy pandas scipy opencv-python matplotlib Pillow scikit-learn optuna keras
# jupyterlabの拡張関係をインストールする
RUN pip install --no-cache-dir jupyterhub jupyterlab_code_formatter jupyterlab-git lckr-jupyterlab-variableinspector jupyterlab_widgets ipywidgets import-ipynb jupyterlab-language-pack-ja-JP
# 必要に応じてサンプルコードなどをgitから落とすなど
RUN git clone https//github.com/username/python_samplcode.git /root/workspace
# jupyterhubの起動時設定 dockerspawnerを使うときは原則これ
CMD ["jupyterhub-singleuser", "--allow-root"]
docker build
作成したDockerfileをbuildします
イメージ名は好きな名前で
$ sudo service docker start
* Starting Docker: docker
$ cd ~/docker
$ sudo docker build . -t jupyterhub
作成が終わったらちゃんとイメージができているか確認しましょう
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jupyterhub latest 827e63b3b9ce 2 minutes ago 1.84GB
jupyterhubの起動
いよいよJupyterhubを起動していきます。
ここで上手に設定しておかないと外部からアクセスした際にdockerコンテナにアクセスする際にRedirect loopが発生してログイン画面まではいけるけどノートブックにアクセスできない問題が発生してしまいました
Jupyterhub の実行IPをlocalhostではなく、明示的にwslのIPアドレスを指定してあげることで解決します
なぜlocalhostだとだめなのかは下記サイト様が参考になりました
jupyterhub_config.pyの編集
jupyterhub_config.py
を編集します。
詳細は割愛しますがc.JupyterHub.ip
およびc.JupyterHub.hub_ip
をwslのIPアドレスと合わせてあげると上手くいきます。
# wslのIPアドレスを取得する ≠ WindowsのIPアドレス
ip = public_ips()[0]
# jupyterのhubへのルート
c.JupyterHub.hub_ip = ip
c.JupyterHub.hub_port = 8111 #好きなポート
# JupyterhubにアクセスするためのIP
c.JupyterHub.ip= ip
c.JupyterHub.port = 8888 #好きなポート
jupyterhub_config.pyのソースは以下を確認してください
ソースコード
ここまで出来たら一回jupyterhubを起動してみましょう。
$ cd ~/jupyterhub
$ sudo jupyterhub
Jupyterhub is now running at ~以下が最初に起動したときと異なりwslのIPアドレスになっていることに注目してください
Adminユーザの作成
WebブラウザでIPアドレス手打ちでログイン画面に映ります
Adminユーザを作成するためにSignup!
をクリックします
ユーザー名にjupyterhub_config.py
のc.Authentivator.admin_users
に指定した名称、パスワードは好きなパスワードを入力します
もう一回ログイン画面に戻り設定したユーザーネームとパスワードを入力することでNotebookが立ち上がります。
Windowsのファイアウォール・ポートフォワーディング設定
WSLの入ったパソコンからのアクセスができるようになりましたが、他のPCからアクセスすることはできません。
なのでWindowsのファイアウォールとポートフォワーディングを設定してWindowsに来たアクセスをWSLに横流しすることでアクセスできるようにします。
PowerShellを管理者権限で開いて以下を実行します
- ファイアウォールを設定してポートを有効にする
- ポートフォワーディングを設定する
今回は仮にWindowsのポート8880に来たアクセスをwslに流すことにします
$ netsh advfirewall firewall add rule name="port forwarding from 8880 to wsl" dir=in action=allo protocol=TCP localport=8880
$ netsh interface portproxy add v4tov4 listenport=8880 connectaddress=$wslのIPアドレス connectport=$c.JupyterHub.portで設定したポート
他のパソコンからアクセス
最後に他のパソコンのブラウザからhttp://windowsのIPアドレス:8880
でアクセスをしてみましょう。
ログインをしてみてノートブックのが開けたら成功です。
補足
wslのIPアドレスは起動ごとに変わってしまうため非常に面倒です。
下記サイト様のようにスタートアップ時にwslを起動してwslのIPアドレスを同定、ポートフォワーディングするように設定すると便利です。またjupyterhubをサービス化して同時に起動するようにしましょう。
まとめ
外部環境からwsl内のjupyterhubサーバ・dockerコンテナにアクセスする方法を説明しました。
下記二つの要点に気を付けることで達成が可能です
- jupyterhubのIPアドレスをlocalhostではなく明示的にwslのIPアドレスで指定する
- 指定したIPアドレスにポートフォワーディングでwindowからwslに横流しするようにする
サーバPCのlocalhostからはアクセスできるのに外部からサーバPCのIPを叩いてもアクセスできなかったり、とくに指定なくjupyterhubを起動するとアドレスがlocalhostになってしまったり、構築するまでにかなりの時間を費やしてしまいました…
Discussion