AzureでJupyter Notebook立ち上げてsshでつなぐ

2018/07/09に書いた記事なので、Azureの管理画面は現在の仕様とは異なる可能性があります。

# やること
* Azureにインスタンスを立ち上げる．
* Azureにsshでログインできるようにする．
* AzureでJupyter Notebookを立ち上げて自分のPCのブラウザから操作できるようにする．←メイン

# おことわり
* OSはWindows7，sshの接続にはRLoginつかってます．sshの設定とかはWindows以外だとかなり勝手が違うと思います．適宜ググって補完してもらえれば…
* 「AzureでJupyter Notebookを立ち上げて自分のPCのブラウザから操作できるようにする」をメインに説明します．

# Azureにインスタンスを立ち上げる
* https://azure.microsoft.com/ja-jp/ にアクセス．右上の「ポータル」をクリックしてログイン．
* 左上の「リソースの作成」（＋のマーク）クリック．
* 今回はUbuntu Server 16.04 LTSをつかいます．（~~Ubuntu Server 18.04 LTSでやったら`pyenv install`がうまくいかなかった~~←いろいろちゃんとインストールすればいけそう）．Ubuntu Server 16.04 LTSを選択して「作成」クリック．


##「基本設定の構成」
* 名前，ユーザ名などを入力．
* 認証の種類を「SSH 公開キー」にしてSSH公開鍵を登録．
    * 秘密鍵と公開鍵のセットは，WindowsならPuTTygenなどでつくれる ．
    * 設定したければ秘密鍵にはパスフレーズを設定しておく．

##「仮想マシンのサイズの選択」
* 性能がいろいろちがうが，とりあえずStandard D2s_v3かStandard D4s_v3あたりが安くて性能もいいんじゃないだろうか．
* 表示されてる選択肢が少ないときは「基本設定の構成」に戻って場所を東南アジアなどに変えるとよい．

## 「オプション機能の構成」
* 適当に．自動シャットダウンを設定しておくと切り忘れの被害が減らせてよい．

ここまでやると確認画面になるので問題なければ作成．デプロイにはちょっと時間がかかる．

# Azureにsshでログインできるようにする
* 設定の「ネットワーク」クリック．
* 「受信ポートの規則を追加する」クリック．
    * ソース: Any
    * ソースポート範囲: *
    * 宛先: Any
    * 宛先ポート範囲: 11111など適当に．22はdefault-allow-sshで使ってるので避けたほうがよさそう．
        * この値はあとでJupyterの接続でつかいます．
    * プロトコル: TCP
    * アクション: 許可
    * 優先度: 1100あたりの値で．
    * 名前: 適当に．AllowJupyterとか．
* DNS名ラベルを設定．
    * プロパティ→構成．
    * 割り当てを「静的」にする．
    * DNS名ラベルを適当な名前で設定．
        * あとでsshログインでつかいます．
* 手元のPCから入ってみる．（Windows + RLoginの場合）
    * RLoginで新規接続の作成．
    * プロトコル: ssh
    * Server Address: 概要の「DNS名」の値．
        * 自分で入力した値.地域.cloudapp.azure.comとかになってるかと．
    * Socket Port: 22
    * User Name: インスタンス作成時に設定したユーザ名．
    * Password/phrase: 秘密鍵のパスフレーズ．
    * SSH Identity Key: 秘密鍵を参照．
    * ポートフォワードの設定はJupyter Notebookの設定のときにまとめてやります．

# AzureでJupyter Notebookを立ち上げて自分のPCのブラウザから操作できるようにする
## Python入れる
* pyenvインストール

```bash

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

* bash_profile編集

```bash

$ vi ~/.bash_profile
```

以下を追記:

```bash

export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
```

* 設定を読み込みなおす

```bash

$ source ~/.bash_profile
```

* Pythonをインストール

```bash

$ pyenv install 3.6.5
```

ここで，

```bash

configure: error: no acceptable C compiler found in $PATH
```
といったエラーがおきたら

```bash

$ sudo apt install gcc
```
してから再度試す．

その他もろもろつっかえて入れたものたち：

```bash

$ sudo apt-get update
$ sudo apt-get install build-essential zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev libssl-dev
```

* つかうPythonのVer.を指定

```bash

$ pyenv global 3.6.5
```

バージョン確認

```bash

$ python --version
Python 3.6.5
```
となればおｋ．

* Jupyterいれる．

```bash

$ pip install jupyter
```

* そのたもろもろ，すきなように．

```bash

$ pip install numpy pandas sklearn matplotlib
```

## Jupyter Notebookの設定（sshなど）
* 先にJupyter Notebookのパスワードを設定しておく．

```bash

$ python
>>> from notebook.auth import passwd
>>> passwd()
Enter password: 【パスワード入力】
Verify password: 【パスワード確認で入力】
【ここの文字列(sha1: から始まるやつ)をコピーしておく】
>>> exit()
```

* 設定ファイルつくる．

```bash

$ jupyter notebook --generate-config
```

configがつくられた場所に移動して設定を編集する

```bash

$ vi .jupyter/jupyter_notebook_config.py
```

以下の部分を編集する．

Before:

```python
## The IP address the notebook server will listen on.
#c.NotebookApp.ip = 'localhost'

...

## Whether to open in a browser after starting. The specific browser used is
#  platform dependent and determined by the python standard library `webbrowser`
#  module, unless it is overridden using the --browser (NotebookApp.browser)
#  configuration option.
#c.NotebookApp.open_browser = True

## Hashed password to use for web authentication.
#  
#  To generate, type in a python/IPython shell:
#  
#    from notebook.auth import passwd; passwd()
#  
#  The string should be of the form type:salt:hashed-password.
#c.NotebookApp.password = ''

...

## The port the notebook server will listen on.
#c.NotebookApp.port = 8888
```

After:

```python
## The IP address the notebook server will listen on.
c.NotebookApp.ip = '0.0.0.0' #20190307: '*'だとエラーが起きたので修正

...

## Whether to open in a browser after starting. The specific browser used is
#  platform dependent and determined by the python standard library `webbrowser`
#  module, unless it is overridden using the --browser (NotebookApp.browser)
#  configuration option.
c.NotebookApp.open_browser = False

## Hashed password to use for web authentication.
#  
#  To generate, type in a python/IPython shell:
#  
#    from notebook.auth import passwd; passwd()
#  
#  The string should be of the form type:salt:hashed-password.
c.NotebookApp.password = 'さっきのpasswd()で設定したやつ'

...

## The port the notebook server will listen on.
c.NotebookApp.port = 「受信ポートの規則を追加する」で宛先ポート範囲に指定したやつ
```
それぞれ，筆者の環境では174, 220, 228, 240行目にあった．

* sshの設定
※Windows + RLoginの場合です．
    * サーバー→プロトコル→ポートフォワード
    * 新規→Local
        * Listened
            * Host Name: localhost
            * Port: 5桁の適当な数．ブラウザから接続するときに入力する値になる．
        * Connect
            * Host Name: 接続設定のServer Name（概要の「DNS名」の値）
    * つくったらチェック入れとく．

* Jupyter Notebookをブラウザから開く

```bash

$ jupyter notebook
```
で立ち上げてブラウザに`localhost:【sshのポートフォワードのListenedのport番号】`と入力，パスワード入れて入れたらおしまい．お疲れさまでした．
．

# 参考にしたサイト
https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b
https://openbook4.me/projects/83/sections/463
https://qiita.com/shinochin/items/23e78499bc78b90fbc62
https://qiita.com/banaoh/items/00aea13fe045fab7e8ba
https://github.com/squillace/staging/blob/master/articles/virtual-machines/virtual-machines-linux-jupyter-notebook.md