Alibaba Cloud で どこでもJupyter notebook(Jupyterhub認証＆Kernel変更機能付き) その2


# Alibaba Cloud で どこでもJupyter notebook(Jupyterhub認証＆Kernel変更機能付き) その2
## この記事は その1 の続きです
### 前の記事  
[Alibaba Cloud で どこでもJupyter notebook(Jupyterhub認証＆Kernel変更機能付き) その1](https://qiita.com/tagucchan/items/aa34fe49a119373f77f1)  
  
### 以降の作業
仮想環境を作成し、jupyter notebook のWeb画面から利用する仮想環境(Kernel)を選択できるように設定します。
仮想環境は各自の環境に合わせて下さい。

## 構成
* Alibaba Cloud上のECSを採用しました。
    * OS CentOS
    * Anaconda3 2019.03
    * Jupyterhub + jupyter_environment_kernels(kernel切替用)

## 接続例 iPhoneから
画像の例では利用していませんが、SSL証明書とhttpsの利用を当然推奨します。
<img width="414" alt="4A0532B7-EB39-4357-88DE-75DE5BE90B66.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/08689fe5-d914-a5b5-4186-14e3fdc7243e.jpeg">

## 仮想環境切替例 iPadから
<img width="966" alt="ED63FB1C-2973-4701-BEB9-BC3DA193ECC6.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/4aa9ca76-218b-a660-6591-67cad3bc4a5f.jpeg">

## 仮想環境の作成
### 仮想環境 tf の作成
私は仮想環境 base は使わないようにしているので、新しい仮想環境 tf （この例だとtensorflow用の環境）を作ります。
注意点としては出来る限りAnaconda環境ではcondaコマンドを使い、pipとの併用を避けることだと思います。
何度も環境を壊した（実際はcondaとpipでバージョン管理が不整合を起こした）ことがあるので、定期的なバックアップや仮想環境を分けるようにしている。したい。  
結局、後悔してやり直していることも多いですね。。。  
ECSだとスナップショットが便利なので、今は環境を作成する前やバージョンアップ前には必ず取得するようにしたいです。
  
```
$ conda create -n tf python=3.6
```

仮想環境tfで行う作業は、(tf)がコマンドプロンプトの先頭に表示されることを確認し、実行して下さい。

**仮想環境 起動と停止の方法**

```
#仮想環境 tf を起動する  
$ conda activate tf 
#プロンプトの先頭に(tf)と表示されていることを確認 

#仮想環境 tf を停止する  
$ conda deactivate  
#プロンプトの先頭に(tf)と表示されていないことを確認 
```

### Tensorflowの導入
仮想環境 tf にJupyterとnotebookとTensorflowとKerasを導入しておく

```
# プロンプトの先頭が(tf)なのを確認した後に
$ conda install jupyter notebook tensorflow keras
```

**Tensorflowが動作するかを確認**
printの後にバージョンの数字が出てくればOK。

```
$ python
Python 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> print(tf.__version__)
1.13.1
>>> exit()
```

## JupyterHub環境の構築
### JupyterHubのインストール
```
$ conda install -c conda-forge jupyterhub  
```

必要なものをインストールしておきます。

```
$ npm install -g configurable-http-proxy
$ sudo yum install git
$ pip install git+https://github.com/jupyter/sudospawner
```

### JupyterHubの設定
JupyterHubの起動に必要なConfigファイルを作成します。
Configの置き場所は/opt配下に置く場合も多いようですが、私の場合は仮想環境 tf を base 扱いにしていますので以下のような場所に置いています。

```
$ cd /opt/Anaconda3/2019.03/envs/tf/etc
$ mkdir jupyterhub
$ cd jupyterhub
$ jupyterhub --generate-config
```

Configファイルの設定
一応、編集前にバックアップを取っておきましょう。

```
$ cp jupyterhub_config.py jupyterhub_config.py.org
$ vi jupyterhub_config.py
```

jupyterhub_config.py の変更箇所は以下のようになります。
利用環境に合わせて設定してください。
Jupyter notebookのディレクトリはユーザのホームディレクトリ(~)配下、notebook。
c.Authenticator.whitelistには利用するユーザidを、c.Authenticator.admin_usersには管理するユーザidを記載します。
ユーザidは ' と ' で囲い、 , で列記していきます。

```
#変更前 c.Spawner.notebook_dir = ''
c.Spawner.notebook_dir = '~/notebook'
  
#変更前 c.Authenticator.whitelist = set()
c.Authenticator.whitelist = {'user01', 'user02'}
  
#変更前 c.Authenticator.admin_users = set()
c.Authenticator.admin_users = {'admin_user'}
```

### JupyterHubをサービス化
サーバ起動したらJupyterHubが立ち上がるように（サービス化）設定ファイルを作成します。

```
$ sudo vi /etc/systemd/system/jupyterhub.service
```

jupyterhub.serviceに以下を記載します。
インストールする場所やファイルのパスを変更した場合は、各自の環境に合わせて作成して下さい。

```
[Unit]
Description=Jupyterhub
After=syslog.target network.target

[Service]
User=root
Environment="PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/Anaconda3/2019.03/envs/tf/bin"
ExecStart=/opt/Anaconda3/2019.03/envs/tf/bin/jupyterhub -f /opt/Anaconda3/2019.03/envs/tf/etc/jupyterhub/jupyterhub_config.py

[Install]
WantedBy=multi-user.target
```

正しく設定できているか、動作を確認します。

```
$ sudo systemctl daemon-reload
$ sudo systemctl start jupyterhub
$ sudo systemctl status jupyterhub
$ sudo systemctl stop jupyterhub
```

サービス登録
問題なく動作しているようなら、サービスに登録します。

```
$ sudo systemctl enable jupyterhub
```

サーバ再起動

```
$ sudo reboot
```

### 動作確認
サーバ起動後、Webブラウザで以下にアクセスし、Jupyterhubの認証画面からログイン出来ることを確認します。
接続できない際は、ECSのセキュリティグループ設定が接続元のIP、Port 8000（デフォルトの場合）に対して、正しく許可されているか確認してください。

```
http://ServerIP（ECSのインターネット側IP）:8000/
```

<img width="414" alt="AE288BF3-174D-4ECC-82EF-19B024730806.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/bb14f906-b193-e12a-4c38-6d5f2d6eb130.jpeg">

**（参考）ECSのセキュリティグループ設定例**
黒塗りの場所に接続元のIP※を設定すると接続できると思います。
※端末設定されているIPではなく、ECSサーバに接続するIPアドレスです。
このようなサイト[cman.jp 使用中IP確認](https://www.cman.jp/network/support/go_access.cgi)でグローバルIPを確認し、設定する必要があります。
<img width="821" alt="41F61AAE-6C4F-48A2-A007-4A8B3055CBB0.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/8d094bc8-54cc-7843-deb8-df1902f858ab.jpeg">

## Jupyter Notebookから実行するAnaconda仮想環境を選択できるようにする
### Anacondaの仮想環境を追加
私はpipコマンドが必要なものは、都度、新しい仮想環境を構築するようにしています。
前述の通り、pip/conda間の依存関係等の問題で、環境が壊れる経験を何度もしているので。
仮想環境の作成は例ですので、各自の環境に合わせて下さい。

例）Fbprophet用

```
$ conda create -n fbprophet python=3.6
$ conda activate fbprophet
$ conda install jupyter notebook
```

例）Spm用

```
$ conda create -n spm python=3.6
$ conda activate spm
$ conda install jupyter notebook
```

### jupyter_environment_kernelsのインストール

jupyter用のKernels（仮想環境）切り替えツール（environment_kernels）をインストールします。

```
$ pip install environment_kernels
```

### JupyterHubのConfigファイルへ設定追加

作成したJupyterHubのConfigファイルにKernels切り替えツールを利用するための設定を追加します。

```
$ vi /opt/Anaconda3/2019.03/envs/tf/etc/jupyterhub/jupyterhub_config.py
```

jupyterhub_config.py の変更箇所は以下です。
2行を最後に追加します。

```
#最後に追加
c.NotebookApp.kernel_spec_manager_class = 'environment_kernels.EnvironmentKernelSpecManager'
c.EnvironmentKernelSpecManager.conda_env_dirs = [ '/Users/username/anaconda/envs/' ] 
```

# kernelをインストール（仮想環境の登録作業）を行います
ipython kernel installのコマンドは仮想環境に入った（activateした状態）で必ず実行します。

```
$ conda activate tf
$ ipython kernel install --user --name=tf --display-name=tf
$ conda deactivate
$ conda activate fbprophet
$ ipython kernel install --user --name=fbprophet --display-name=fbprophet
$ conda deactivate
$ conda activate spm
$ ipython kernel install --user --name=spm --display-name=spm
$ conda deactivate
```

## その他、最低限欲しいツールのインストール
~/notebookのファイルを移行しようと作業したところ、zip,unzipコマンドが入っていなかったので、インストールしました。
私はECSサーバにはsftpで定期的にnotebookディレクトリをアップロードするようにしています。

```
$ sudo yum install zip unzip
```

## 動作確認
### 再起動
```
$ sudo reboot
```

### 動作確認
Webブラウザで以下にアクセスし、Jupyterhubの認証画面からログイン出来ることを確認します。
また、ノートを開いた画面、上部のメニューから Kernel > Change kernelで利用するkernelが変更できることを確認してください

```
http://ServerIP（ECSのインターネット側IP）:8000/
```

ここまでの作業が上手く行くと、jupyter notebookのメニュー Kernel > Change kernel > 仮想環境名 が選択できるようになります。
<img width="966" alt="42A75FD4-440F-409D-8477-5E906E747FB4.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/eb107991-5b3e-aeaa-e9df-05c4b264ad77.jpeg">

問題なく切り替わり、実行できるかを試してみてください。
どのKernalを利用する設定になっているかどうかは、メニュー右端の表示で確認できます。
デフォルトだとPython3と表示されているかと思います。

以上です。