概要
全体概要は,AWSでJupyterHub (概要) にあるので,参照してください.
今回は,前回インストールしたAnacondaを使ってJupyterHubを組み立てていきます.
また,JupyterHub自体にWebサーバの機能を持っていますが,今回はnginxをWebサーバにおいて,その後ろにJupyterHubを置くような構成にしていきます.
おしながき
- JupyterHub用ユーザの作成
- JupyterHubのインストール
- JupyterHubの設定
- jupyterhub-config.pyの中身
- JupyterHubの起動
- nginxとの接続
前回同様,今回も基本的にec2-user
で操作していきます.
細かい説明を入れていくので,記事としては長めになっていますのでご了承ください <(_ _)>
JupyterHub用ユーザの作成
インストールしただけでは,複数ユーザで利用することが出来ないです.また,目的に合わせて権限周りは設定していくべきです.
なので今回は,「jupyterhubグループに属するユーザが利用できる」ように設定しておきます.
次のように設定していきます.
- jupyterhubグループの追加
-
ec2-user
にjupyterhubを追加 -
/opt/anaconda3
配下のグループをjupyterhubに変更 - anacondaの確認
ec2-user
へのグループ追加は便宜上,設定しておくものです.きちんと作業用ユーザを用意している場合は,そのユーザに対して追加するほうがよいでしょう.
groupadd
を使ってjupyterhub
グループを作成して,gpasswd
を使ってec2-user
にグループ追加していきます.
以下の画像のような流れになってます.
グループが付いているか確認するには,id {username}
で確認できます.
※グループ追加したての時は,その接続では有効になっていないので,設定が終わったら再ログインして設定を反映させたほうが良いです
/opt/anaconda3
のグループを変更していきます.
変更は以下のコマンドになります.
権限もotherに与えないように770
にしておきます.
chgrp -R jupyterhub /opt/anaconda3
chmod 770 -R /opt/anaconda3
JupyterHub実行ユーザの追加
ec2-user
でJupyterHubを動かしてもいいのですが,せっかくなので専用ユーザで実行するようにします.
グループは先ほど作ったので,それを割り当てるようにします.
JupyterHubだけ動かすアプリユーザということで,ログインできないようにnologin
をつけておきます.
sudo useradd -s /sbin/nologin jupyterhub -g jupyterhub
id jupyterhub
と入力すれば,jupyterhubユーザの情報が出力されて作成されたことを確認できます.
Anacondaの確認
ec2-user
で/opt/anaconda3/bin/conda
とオプションなしで打ち込むと,「( ゚Д゚)<指定しろや!」ってヘルプ情報をずらーっと出してきます.出てくれば,権限や設定周りがうまくいってそうだということで次に進みます.
パスを通す
今回は特に気にしないのですが,普段からconda
コマンドを利用する場合は,/opt/anaconda3/bin
にパスを通しておくと何かと便利です.
ホームディレクトリに移動して,.bashrc
を編集ツールを使って,最後に以下を追記して保存します.
export PATH=/opt/anaconda3/bin:$PATH
追加出来たら,再ログインするか source .bashrc
で設定を反映させます.
JupyterHubのインストール
さっそく,JupyterHubをインストールしていきます.
インストールは以下のコマンドを使います.
/opt/anaconda3/bin/conda install -c conda-forge jupyterhub
# パスを通していれば,こちらでもOK
conda install -c conda-forge jupyterhub
実行すると,リポジトリから探してきて,インストールが必要なパッケージをリストアップしてくれます.
「インストールしてよいか?」と聞かれるので,インストールさせてあげましょう.
しばらく作業していますが,そのうち終わります.
インストール完了したら,以下のコマンドで確認します.
/opt/anaconda3/bin/conda list
このコマンドはAnacondaにインストールされたパッケージを出力してくれます.
このなかに「jupyterhub」のパッケージがあれば,成功しています.
numpyやscikit-learnなど機械学習でよく使われるパッケージはあらかじめインストールされていますが,リストになくて必要なものがあれば,同様にパッケージをインストールしていけば良いのですが,Anacondaは環境ごとにパッケージ管理できるので,この方法でないほうが良いこともあります.(バージョン固定させたいときなど)
JupyterHubの設定
JupyterHubのインストールが終われば,次は設定を行っていきます.
最初は設定ファイルがないので,設定ファイルを作るところから始めていきます.
まず次のコマンドを実行して,設定ファイルを置く場所を作ります.
sudo mkdir /etc/jupyterhub
sudo chmod 770 /etc/jupyterhub
sudo chown jupyterhub:jupyterhub /etc/jupyterhub
次に,以下のコマンドで,設定ファイルを作ります.
cd /etc/jupyterhub/
sudo -u jupyterhub /opt/anaconda3/bin/jupyterhub --generate-config
実行すると,Writing default config to: jupyterhub_config.py
と出力されればカレントディレクトリに設定ファイルが出力されています.
もしディレクトリにwrite権限がないと,エラーログが出力されます.
今,出力されたファイルはバックアップも兼ねてデフォルトファイルとしておきます.(しなくてもいいのですが念のため)
sudo -u jupyterhub mv /etc/jupyterhub/jupyterhub_config.py /etc/jupyterhub/jupyterhub_config.py.default
バックアップ用ファイルが出来たらさっそく,jupyterhub-config.py
の作成に取り掛かります.
認証方式は,いろいろあるのですが,今回はLinuxユーザがJupyterHubユーザとして利用するようにしていきます.(ほんとはLDAP認証したかったけどね...)
jupyterhub-config.pyの中身
以下のような設定にします.ファイルはPythonなので,Pythonの文法であればどんな書き方でも大丈夫です.
不要な行は#
を使ってコメントアウトすることが出来ます.
c.JupyterHub.bind_url = 'http://127.0.0.1:8080'
c.Spawner.notebook_dir = '~/notebook'
# c.Spawner.notebook_dir = '/mnt/jupyterhub/{username}/notebook'
# c.Spawner.default_url = '/lab'
c.Authenticator.admin_users = {
'ec2-user'
}
c.Authenticator.whitelist = {
'ec2-user',
'testuser'
}
項目 | 型 | 概要 | 設定例 |
---|---|---|---|
c.JupyterHub.bind_url | str | JupyterHubがリクエストを受け取るためのURLです.ポート番号もここで指定します. | http://127.0.0.:8080 |
c.Spawner.notebook_dir | str |
JupyterHub が利用するnotebookデータのディレクトリを指定します.これはユーザごとに管理されます.~ はユーザのホームディレクトリを表していて,{username} とするとユーザ名に置き換わるようになります.(プレスホルダー機能) |
~/notebook |
c.Spawner.default_url | str |
c.JupyterHub.bind_url の後ろにつけるURLです.上記のコードではhttp://127.0.0.1:8080/lab というようになります.この項目を利用することで,既存システムに追加できるようになっています.lab とするとnotebook からJupyterLab に変わります. |
/lab |
c.Authenticator.admin_users | set | 管理者権限を持つユーザの一覧です.空にすると,管理者がいない状態になります. | |
c.Authenticator.whitelist | set | この一覧にあるユーザだけログインすることが出来るようになります. |
設定ファイルが出来たら,ec2-user
のホームディレクトリにnotebook
というディレクトリを作っておきましょう.
mkdir ~/notebook
不足しているものをインストール
設定ファイルを作るだけではなく,JupyterHubを起動する際にnpm
とconfigurable-http-proxy
が必要なので,追加でインストールしていきます.
npmのインストール
# リポジトリの取得
curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -
# nodejsのインストール
sudo yum install -y nodejs
# 確認
npm -v
configurable-http-proxyのインストール
sudo npm install -g configurable-http-proxy
JupyterHubに接続してみる
ということで,JupyterHubを起動してみます.
起動コマンドは以下のような感じになります.
cd /etc/jupyterhub
/opt/anaconda3/bin/jupyterhub
起動すると起動ログと一緒にエラーが出てきます.
エラーの内容が Error adding user testuser already in db
というものであれば,「testuser
ってユーザがシステムにないよ?」といっているので,ひとまず無視して問題ないです.(後で足していくので)
nginxとつなげるので,Ctrl + C
で止めておきます.
#nginxとの接続
AWSでJupyterHub (nginx) で後回しにしていたnginxの設定ファイルに手を加えていきます.
/etc/nginx/nginx.conf
にある設定を以下のようにlistenの部分をコメントアウトします.
...(省略)...
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
# ★★ 以下2行のlistenをコメントアウトする ★★
# listen 80 default_server;
# listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
...(省略)...
次に,/etc/nginx/conf.d/
に移動します.このディレクトリは初めは空っぽで,/etc/nginx.conf
が参照するようになっています.
ここに,以下の設定情報を書いたjupyterhub.conf
というファイルを作ります.
通常のproxyの設定に合わせて,JupyterHubがwebsocketを利用していることから,それに合わせた設定も追加しておきます.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
server_name xxx.yyy.zzz; # ←ここにJupyterHubに接続するためのドメインを指定する
root /usr/share/nginx/html;
access_log /var/log/nginx/jupyterhub.log main;
client_max_body_size 4M; # 413 Request Entity Too Large
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# websocket headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 86400;
proxy_set_header Origin "http://localhost:8080";
}
}
nginxが80ポートで受け取って,8080番ポートに受け流す設定になってます.
JupyterHubはファイルのアップロード機能もついているので,アップロード可能のファイルサイズもclient_max_body_size
で指定しておきます.
この設定によって捌かれたリクエストは/var/log/nginx/jupyterhub.log
に記録されるようになっています.出力フォーマットは/etc/nginx.conf
に定義されてます.
動作確認
JupyterHubとnginxの設定が出来たら,両方とも起動して動作確認してみます.
nginxの起動
まず,sudo systemctl start nginx
で起動させます.
Job for nginx.service failed because the control process exited with error code.
のような情報が出力されてしまったら設定ファイルに不備がある可能性があるのでsystemctl status nginx
と入力して,原因を確認して修正していきます.
先ほど追加した/etc/nginx/conf.d/jupyterhub.conf
にEC2インスタンスのパブリックDNS名を指定した場合,ドメイン名が長すぎて怒られてしまいます.
そのため,以下のようにserver_names_hash_bucket_size
の項目を追加しておきます.
設定値は64
だと小さいようなので128
にしてあります.
... 省略 ...
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 128; # ★★ これ ★★
include /etc/nginx/mime.types;
default_type application/octet-stream;
... 省略 ...
JupyterHubの起動
nginxが起動したら,先ほどと同様にJupyterHubを起動します.
http://{nginxで指定したサーバー名}/hub
とブラウザに打ち込んでアクセスしてみます.
以下のように表示されれば,設定完了です.
/var/log/nginx/jupyterhub.log
にもアクセスログが出力されています.
入力フォームに出ているワーニングは,「HTTP接続してんじゃねーよ」って言ってるだけです.あとで,ACMとALBを使ってHTTPS接続できるようにするので放置しておきます.
まとめ
今回は,JupyterHubのインストールと設定,nginxとの接続の3つをやりました.
そして,JupyterHubのログイン画面を表示するところまで進めました.
今回の設定では,ホワイトリストに設定されているLinuxユーザであれば,ログインできるPAM認証というものを使っています.
今のままでは正しくユーザ名・パスワードを入力してもログインが失敗してしまいます.
次回,この失敗を解消させて,JupyterHubにログインできるようにしてきます.