AWS EC2(Ubuntu 16.04)にJupyterHub+R実行環境を構築する
ブラウザ上で稼働する対話型実行環境『Python Notebook』(※参考)をリモートサーバー上で公開出来るサービスに『JupyterHub』というものがあります。当エントリでは、その環境をUbuntu16.04にインストールし、併せてJupyterHub上でR実行環境を整える手順についてもまとめてみたいと思います。
- jupyterhub/jupyterhub: Multi-user server for Jupyter notebooks
- JupyterHub — JupyterHub 0.7.0.dev documentation
目次
下準備
今回導入を行うEC2環境はUbuntuとなります。バージョンは16.04。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
下記エントリで導入を行った環境をそのまま活用してみました。
まず始めに、ログイン後の各種パッケージを最新のものに更新、次いで必要なパッケージを追加でインストールしておきます。
$ ssh -i rstudio_and_jupyterhub_key.pem ubuntu@xx.xxx.xx.xxx The authenticity of host 'xx.xxx.xx.xxx (xx.xxx.xx.xxx)' can't be established. RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'xx.xxx.xx.xxx' (RSA) to the list of known hosts. Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-22-generic x86_64) * Documentation: https://help.ubuntu.com/ Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. $ $ sudo apt-get -y update $ sudo apt-get -y upgrade $ sudo apt-get -y install git gcc g++ make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev python-dev libmysqlclient-dev
Python3系環境のインストール
PythonHubを利用するにはPython3系の環境が必要となるので、PythonHub導入前にそちらの環境を整備します。今回の対象OSでは、導入されているバージョンは以下の様に2.7系でした。
$ python --version Python 2.7.11+
Python実行環境の整備にはpyenvを活用します。以下コマンド実行で導入。
$ git --version git version 2.7.4 $ git clone https://github.com/yyuu/pyenv.git ~/.pyenv Cloning into '/home/ubuntu/.pyenv'... remote: Counting objects: 13279, done. remote: Total 13279 (delta 0), reused 0 (delta 0), pack-reused 13279 Receiving objects: 100% (13279/13279), 2.35 MiB | 0 bytes/s, done. Resolving deltas: 100% (9243/9243), done. Checking connectivity... done.
~/.bashrcファイルを開き、ファイル末尾に以下の内容を追記。保存後、再読み込みを行います。
$ vi ~/.bashrc ---- # 2016/07/11 Added export PYENV_ROOT="${HOME}/.pyenv" if [ -d "${PYENV_ROOT}" ]; then export PATH=${PYENV_ROOT}/bin:$PATH eval "$(pyenv init -)" fi $ $ source ~/.bashrc
pyenv install --listコマンドでインストール可能なPythonのバージョンを確認してみます。Python3系で利用可能な正式リリースバージョンは現時点では3.5.2となるようです。
$ pyenv install --list Available versions: 2.1.3 2.2.3 2.3.7 2.4 2.4.1 : 3.4.5 3.5.0 3.5-dev 3.5.1 3.5.2 3.6.0a1 3.6.0a2 3.6-dev anaconda-1.4.0 anaconda-1.5.0 : stackless-3.3-dev stackless-3.3.5 stackless-3.4.1 $
pyenv installコマンドでバージョンを指定してインストール実施。
$ pyenv install 3.5.2 Downloading Python-3.5.2.tar.xz... -> https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz Installing Python-3.5.2... Installed Python-3.5.2 to /home/ubuntu/.pyenv/versions/3.5.2
pyenv versionsコマンドで切り替え可能なPythonのバージョン一覧を出してみます。3.5.2も一覧表示はされていますが、現在の環境とはなっていない模様。
$ pyenv versions * system (set by /home/ubuntu/.pyenv/version) 3.5.2
バージョンをpyenv globalで指定して切り替え、情報を反映させます。
$ pyenv global 3.5.2 $ pyenv rehash
改めてバージョンを確認。3.5.2が指定・設定されている事を確認出来ました。
$ python --version Python 3.5.2 $ pyenv versions system * 3.5.2 (set by /home/ubuntu/.pyenv/version)
nvm/npm周りの環境整備
JupyterHub導入にはNode.jsが必要となるらしいのでこの辺りの環境についても最新版で整えたいと思います。nvm最新版を以下の形で導入。ターミナルの再ログインを行う旨促されるので、
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 7766 100 7766 0 0 22104 0 --:--:-- --:--:-- --:--:-- 22125 => Downloading nvm from git to '/home/ubuntu/.nvm' => Cloning into '/home/ubuntu/.nvm'... remote: Counting objects: 4888, done. remote: Total 4888 (delta 0), reused 0 (delta 0), pack-reused 4887 Receiving objects: 100% (4888/4888), 1.34 MiB | 0 bytes/s, done. Resolving deltas: 100% (2925/2925), done. Checking connectivity... done. * (HEAD detached at v0.31.2) master => Appending source string to /home/ubuntu/.bashrc => You currently have modules installed globally with `npm`. These will no => longer be linked to the active version of Node when you install a new node => with `nvm`; and they may (depending on how you construct your `$PATH`) => override the binaries of modules installed with `nvm`: /usr/local/lib └── configurable-http-proxy@1.2.0 => If you wish to uninstall them at a later point (or re-install them under your => `nvm` Nodes), you can remove them from the system Node as follows: $ nvm use system $ npm uninstall -g a_module => Close and reopen your terminal to start using nvm
再ログインを行い、nvm --versionで最新バージョンが導入されている事を確認します。
$ exit logout Connection to xxx.xx.xxx.xx closed. $ ssh -i rstudio_and_jupyterhub_key.pem ubuntu@xxx.xx.xxx.xx Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-22-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 7 packages can be updated. 7 updates are security updates. *** System restart required *** Last login: Fri Jul 8 xx:xx:xx:xx 2016 from xxx.xx.xxx.xx $ nvm --version 0.31.2 $
nvm installコマンドで最新バージョンをインストールし、バージョンが更新されている事を確認。
$ nvm --version 0.31.2 $ node -v v4.2.6 $ npm -v 3.5.2 $ nvm install v6.2.2 Downloading https://nodejs.org/dist/v6.2.2/node-v6.2.2-linux-x64.tar.xz... ######################################################################## 100.0% Now using node v6.2.2 (npm v3.9.5) Creating default alias: default -> v6.2.2 $ node -v v6.2.2 $ npm -v 3.9.5
JupyterHub環境のインストール
JupyterHub環境のインストールにはpip/pip3を用います。
$ pip --version pip 8.1.1 from /home/ubuntu/.pyenv/versions/3.5.2/lib/python3.5/site-packages (python 3.5) $ pip3 --version pip 8.1.1 from /home/ubuntu/.pyenv/versions/3.5.2/lib/python3.5/site-packages (python 3.5)
以下のパッケージをそれぞれインストール。
$ npm install -g configurable-http-proxy $ pip3 install jupyterhub $ pip install ipython[notebook] jupyterhub $ jupyterhub --version 0.6.1
JupyterHubはPAMを認証方式として用いています。一番手っ取り早い認証の確認方法としてubuntuユーザーにパスワード設定を行って確認して見たいと思います。
- How JupyterHub works — JupyterHub 0.7.0.dev documentation
- Linuxの各アプリケーションが共通して利用する「PAM認証」について | OXY NOTES
- (Linux)ログイン時にActiveDirectoryのユーザ名・パスワードで認証できるようにする : 3流プログラマのメモ書き
$ sudo passwd ubuntu Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
ひとまずオプション無しで起動してみます。色々怒られました...上から1つずつ見て行きましょう。
$ jupyterhub [I 2016-07-11 08:01:33.309 JupyterHub app:643] Writing cookie_secret to /home/ubuntu/jupyterhub_cookie_secret [W 2016-07-11 08:01:33.373 JupyterHub app:304] Generating CONFIGPROXY_AUTH_TOKEN. Restarting the Hub will require restarting the proxy. Set CONFIGPROXY_AUTH_TOKEN env or JupyterHub.proxy_auth_token config to avoid this message. [W 2016-07-11 08:01:33.382 JupyterHub app:757] No admin users, admin interface will be unavailable. [W 2016-07-11 08:01:33.382 JupyterHub app:758] Add any administrative users to `c.Authenticator.admin_users` in config. [I 2016-07-11 08:01:33.382 JupyterHub app:785] Not using whitelist. Any authenticated user will be allowed. [E 2016-07-11 08:01:33.392 JupyterHub app:1228] Failed to bind hub to http://127.0.0.1:8081/hub/ [E 2016-07-11 08:01:33.392 JupyterHub app:1296] Traceback (most recent call last): File "/home/ubuntu/.pyenv/versions/3.5.2/lib/python3.5/site-packages/jupyterhub/app.py", line 1294, in launch_instance_async yield self.start() File "/home/ubuntu/.pyenv/versions/3.5.2/lib/python3.5/site-packages/jupyterhub/app.py", line 1226, in start self.http_server.listen(self.hub_port, address=self.hub_ip) File "/home/ubuntu/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tornado/tcpserver.py", line 126, in listen sockets = bind_sockets(port, address=address) File "/home/ubuntu/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tornado/netutil.py", line 196, in bind_sockets sock.bind(sockaddr) OSError: [Errno 98] Address already in use
CONFIGPROXY_AUTH_TOKENのくだりはプロキシー認証トークンを設定する必要があるとの事。まずは設定ファイルを作成する必要がありますので以下コマンドで設定ファイルを作成し、
$ jupyterhub --generate-config Writing default config to: jupyterhub_config.py
認証トークン文字列をドキュメントに倣って作成。
$ export CONFIGPROXY_AUTH_TOKEN=`openssl rand -hex 32` $ echo $CONFIGPROXY_AUTH_TOKEN 05f5(以下略)c730
設定ファイルを編集し、該当箇所にトークン文字列を設定します。
$ vi jupyterhub_config.py ---- # The Proxy Auth token. # # Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default. # c.JupyterHub.proxy_auth_token = '' c.JupyterHub.proxy_auth_token = '05f5(中略)c730'
admin user〜のくだりについても設定ファイルに必要な情報を追記する事で対応出来ます。以下2箇所に利用するユーザーの情報を追記。
$ vi jupyterhub_config.py ---- # DEPRECATED, use Authenticator.admin_users instead. # c.JupyterHub.admin_users = set() c.JupyterHub.admin_users = { 'ubuntu' } ---- # Use this to restrict which users can login. If empty, allow any user to # attempt login. # c.Authenticator.whitelist = set() c.Authenticator.whitelist = { 'ubuntu' }
ポート8081に関する問題については、このポートをどのプロセスが掴んでいるかを確認してみたいと思います。Python3が掴んでいるようです。
$ sudo netstat -anp | grep 8081 tcp 0 0 127.0.0.1:8081 0.0.0.0:* LISTEN 1248/python3
ひとまずはこのポートを掴んでいるプロセスをkillしてみます。
$ sudo kill 1248
killした後、改めてjupyterhubを起動してみます。エラーメッセージはだいぶ減りましたが新たなメッセージが表示されました。こちらはJupyterHubがSSL接続をデフォルト且つ推奨している為、証明書を設定しましょうね、使わない場合は--no-sslオプションを使って起動しましょう、という旨が表示されています。
$ jupyterhub [I 2016-07-11 08:14:47.375 JupyterHub app:622] Loading cookie_secret from /home/ubuntu/jupyterhub_cookie_secret [W 2016-07-11 08:14:47.405 JupyterHub app:743] JupyterHub.admin_users is deprecated. Use Authenticator.admin_users instead. [I 2016-07-11 08:14:47.421 JupyterHub app:1231] Hub API listening on http://127.0.0.1:8081/hub/ [E 2016-07-11 08:14:47.424 JupyterHub app:963] Refusing to run JuptyterHub without SSL. If you are terminating SSL in another layer, pass --no-ssl to tell JupyterHub to allow the proxy to listen on HTTP.
ここはひとまず--no-sslオプションで起動させて見ることにします。サーバーの起動自体は上手く行った様です。
$ jupyterhub --no-ssl [I 2016-07-11 09:38:18.457 JupyterHub app:622] Loading cookie_secret from /home/ubuntu/jupyterhub_cookie_secret [W 2016-07-11 09:38:18.484 JupyterHub app:743] JupyterHub.admin_users is deprecated. Use Authenticator.admin_users instead. [I 2016-07-11 09:38:18.499 JupyterHub app:1231] Hub API listening on http://127.0.0.1:8081/hub/ [W 2016-07-11 09:38:18.502 JupyterHub app:959] Running JupyterHub without SSL. There better be SSL termination happening somewhere else... [I 2016-07-11 09:38:18.502 JupyterHub app:968] Starting proxy @ http://*:8000/ 09:38:18.619 - info: [ConfigProxy] Proxying http://*:8000 to http://127.0.0.1:8081 09:38:18.623 - info: [ConfigProxy] Proxy API at http://127.0.0.1:8001/api/routes [I 2016-07-11 09:38:18.706 JupyterHub app:1254] JupyterHub is now running at http://127.0.0.1:8000/
先述の手順で設定したユーザー名とパスワードでログインを試みますが...
暫く応答が無かった後、エラーとなってしまいました。
吐かれた実行ログを確認してみると幾つか権限が足りない旨のエラーメッセージが表示されている事を確認出来ます。一旦JupyterHubを停止させて該当箇所の解決を図ってみます。(※サーバー停止はCrtl+Cで行えます。)
[I 2016-07-11 08:32:45.872 JupyterHub log:100] 200 GET /hub/login?next= (@::ffff:36.12.52.51) 21.30ms sh: 1: cannot create /run/motd.dynamic.new: Permission denied Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-22-generic x86_64) : PermissionError: [Errno 13] Permission denied: '/home/ubuntu/.local/share' : TimeoutError: Server at http://127.0.0.1:32964/user/ubuntu didn't respond in 30 seconds
該当箇所を確認してみるとrootユーザーの所有となっています。ここは実行ユーザーのubuntuに所有者を変更。
$ ls -lta /home/ubuntu/ total 52488 drwxr-xr-x 9 ubuntu ubuntu 4096 Jul 11 08:38 . -rw-r--r-- 1 ubuntu ubuntu 8192 Jul 11 08:38 jupyterhub.sqlite -rw-rw-r-- 1 ubuntu ubuntu 14901 Jul 11 08:10 jupyterhub_config.py : drwx------ 3 root root 4096 May 8 22:36 .local : -rw-r--r-- 1 ubuntu ubuntu 675 Aug 31 2015 .profile $ sudo chown -R ubuntu.ubuntu .local/ $ ls -lta /home/ubuntu/ total 52488 drwxr-xr-x 9 ubuntu ubuntu 4096 Jul 11 08:38 . -rw-r--r-- 1 ubuntu ubuntu 8192 Jul 11 08:38 jupyterhub.sqlite -rw-rw-r-- 1 ubuntu ubuntu 14901 Jul 11 08:10 jupyterhub_config.py : drwx------ 3 ubuntu ubuntu 4096 May 8 22:36 .local : -rw-r--r-- 1 ubuntu ubuntu 675 Aug 31 2015 .profile
改めてJupyterHubを起動させ、ブラウザアクセス&ログインを実施。今度はちゃんと表示されました!
メニューからPython3を選び、
試しに簡単なコードを打ってみます。ちゃんと結果も返って来る様です。
R実行環境をJupyterHubと連動させる
ここまでの手順でだいぶ長くなってしまいましたが、『もうちょっとだけ続くんじゃ』的な感じでもう少しお付き合い頂ければと思います。ここからの手順ではJupyterHubからRを利用出来るような設定を行います。
まずは事前に必要となるライブラリをapt-getコマンドでインストール。
$ sudo apt-get -y install libzmq3 $ sudo apt-get -y install libzmq3-dev
そしてRを起動。Rはこのタイミングで既に下記バージョンのものが導入されていますのでこれをそのまま使います。
$ R --version R version 3.3.0 (2016-05-03) -- "Supposedly Educational" Copyright (C) 2016 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under the terms of the GNU General Public License versions 2 or 3. For more information about these matters see http://www.gnu.org/licenses/. $ R R version 3.3.0 (2016-05-03) -- "Supposedly Educational" Copyright (C) 2016 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. Natural language support but running in an English locale R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. >
R環境上で以下パッケージインストールのコマンドを実行。CRAN mirrorサイトの選択を促される場合もありますので、その際は任意のサイトを選択する事でインストール作業が進みます。
> install.packages(c('rzmq','repr','IRkernel','IRdisplay'), repos = c('http://irkernel.github.io/', getOption('repos'))) Installing packages into ‘/usr/local/lib/R/site-library’ (as ‘lib’ is unspecified) Warning in install.packages(c("rzmq", "repr", "IRkernel", "IRdisplay"), : 'lib = "/usr/local/lib/R/site-library"' is not writable Would you like to use a personal library instead? (y/n) y Would you like to create a personal library ~/R/x86_64-pc-linux-gnu-library/3.3 to install packages into? (y/n) y : : ** R ** inst ** preparing package for lazy loading ** help *** installing help indices ** building package indices ** testing if installed package can be loaded * DONE (IRkernel) The downloaded source packages are in ‘/tmp/RtmpF8P4HY/downloaded_packages’ >
R環境上でもう1つコマンドを実行。これで環境が整いました。
> IRkernel::installspec() [InstallKernelSpec] Installed kernelspec ir in /home/ubuntu/.local/share/jupyter/kernels/ir
Rの環境はここで一旦抜けます。
> q() Save workspace image? [y/n/c]: y $
JupyterHubを再起動&再ログイン。JupyterHubのメニューにRが追加されている事を確認出来ました!
まとめ
だいぶ長くなってしまいましたが、Ubuntu16.04環境にJupyterHub及びR実行環境を整える手順についてのご紹介でした。今回の環境構築にあたってはだいぶ試行錯誤を重ねた形でしたが、調査結果としてある程度の形にまとめる事が出来たのでひと安心と言ったところです。つうかPythonHub、かなり便利な環境ですね。PythonやRの勉強でも色々と活用してみたいと思います。こちらからは以上です。