
AWSを駆使したクラウドデータサイエンティストになるための教科書:EC2インスタンスでJupyter notebookを使えるようにする
これまで、AWSのEC2インスタンスにSSHで接続する方法をご紹介してきました。今回は接続したEC2インスタンス上でJupyter notebookを利用していよいよデータ分析環境を構築していきます。
EC2の起動とSSH接続
まずは、前回の「AWSを駆使したクラウドデータサイエンティストになるための教科書:EC2インスタンスを立ち上げてSSH接続する」で説明した方法でEC2の起動とSSH接続を行います。
まずはAWSのEC2サービスコンソールから該当のEC2インスタンスが停止中であれば、再起動します。
再起動したら、パブリックIPv4 DNS名をメモし、Tera TermからSSH接続を行います。
必要なパッケージのインストール
EC2インスタンスにSSH接続出来たら、EC2インスタンスに必要なパッケージをインストールしていきます。なお、下記はEC2インスタンスのAMIとしてAmazon Linuxを利用していることを想定しています。
Pythonとpipをインストール
以下のコマンドをEC2インスタンス上で実行します。
sudo yum update
sudo yum install python3 python3-pip -y
上記のコマンドの詳細は次の通りです。
■ sudo yum update
目的: システムのパッケージリストを更新します。これにより、最新バージョンのソフトウェアやセキュリティアップデートがインストールできるようになります。実際のパッケージのインストールやアップグレードは行いません。
詳細:
sudo: 管理者権限でコマンドを実行します。これがないとシステムの重要な操作ができません。
yum: UbuntuなどのRed Hat系Linuxディストリビューションで使われるパッケージ管理ツールです。よくPythonでライブラリを更新する際に「pip hogehoge」というコマンドを実行すると思いますが、pipじゃなくyumというものでやるという風にイメージしてもらえればわかりやすいと思います。
update: 現在インストール可能なソフトウェアのリスト(パッケージリスト)を最新状態に更新します。
■ sudo yum install python3 python3-pip -y
目的: python3とpython3-pipをインストールします。
詳細:
sudo: 管理者権限でコマンドを実行します。sudo は "superuser do" の略です。"superuser": システム管理者(root ユーザー)のことを指します。Linux や UNIX 系のシステムでは、通常のユーザーとは異なり、システム全体の管理操作を行う権限を持っています。通常のユーザーは、セキュリティ上の理由からシステムの重要な部分にアクセスしたり変更したりする権限が制限されています。
sudo を使うことで、一時的にスーパーユーザー(root)として権限を昇格し、管理操作を行えるようになります。
sudoをつけない場合、例えばEC2インスタンスのAmazon LinuxのAMIはデフォルトだとec2-userがユーザーになりますので、このec2-userの通常権限でコマンドを実行するという意味になります。つまりsudoはec2-userがrootユーザーの権限レベルで実行するということを指します。なぜrootユーザーとしてそもそも実行しないのか?という点についてはセキュリティの観点から上位権限をもつRootユーザーはなるべく使用すべきではないと考えられるからです。yum install: 指定されたソフトウェアパッケージをインストールします。
python3: Pythonの3系バージョンをインストールします。インストールされる Python 3 のバージョンは、使用している Linux ディストリビューション(例: Ubuntu)の リポジトリが提供するデフォルトバージョン に依存します。インストール後に「python3 --version」を実行することでインストールされたらPython3のバージョンを確認できます。
python3-pip: Pythonの3系用のパッケージ管理ツールpipをインストールします。
-y: インストール確認のプロンプト(yes/no)をスキップし、自動的にyesとして進めます。
Jupyter notebookをインストール
以下のコマンドをEC2インスタンス上で実行します。
pip install notebook
Jupyter Notebookの設定
Jupyterの構成ファイルを作成:
Jupyter notebookがインストール出来たら、Jupyterの構成ファイルを作成します。
jupyter notebook --generate-config
このコマンドで作成される構成ファイルは、Jupyter Notebook サーバーの動作を設定するための 構成ファイル(jupyter_notebook_config.py) です。
普段、あまりJupyter notebookを利用している際に意識していませんが、Jupyter notebookの挙動を簡単に理解しておくとこの構成ファイルの意味を理解しやすいです。
Jupyter notebookはインストールしたそのデバイスの中でJupyter notebookサーバーを構築します。そして同じデバイスのWebブラウザをクライアントとして同じ端末内でHTTPリクエストとレスポンスを行っているのです。もちろん、クライアントが同じデバイスである必要はありません。そのため、別のデバイスのWebブラウザをクライアントとして、そのJupyter notebookサーバーにHTTPリクエストを送る形でJupyter notebookを利用することもできます。今回はこれを行います。つまりEC2インスタンスにJupyter notebookサーバーを立ち上げ、自分のローカル端末のWebブラウザをクライアントとして通信を行うということです。そしてこれらの通信に関連する設定を行うのが構成ファイルです。
通常、この構成ファイルは~/.jupyter/jupyter_notebook_config.py に作成されます。各設定項目は Python のコメントとして記載されており、必要に応じてコメントを外し、設定を変更できます。以下は、この構成ファイルで設定できる主な内容の例です。
ファイルの中身は次のコマンドで確認できます。
cat ~/.jupyter/jupyter_notebook_config.py
または
less ~/.jupyter/jupyter_notebook_config.py
表示しているファイルで文言を検索する場合は「/(検索文言)」で検索できます。表示を終了する場合は「q」を押します。
ファイルを編集したい場合は、インストールされている編集エディタを使って行います。Amazon LinuxならVi(またはVim)またはnanoがデフォルトでインストールされている編集エディタです。ここではnanoを利用します。どれが使えるかは「which vi」や「which nano」を実行することで確認できます。
nano ~/.jupyter/jupyter_notebook_config.py
nanoでキーワード検索する場合はCtrl+wで検索モードに入り、検索したい文言を入力してEnterを押すと検索できます。
1. ポート番号の指定:デフォルトでは Jupyter Notebook はポート 8888 で動作しますが、これを変更することができます。つまり、Jupyter notebookサーバーがクライアントに対して解放しているポートが8888であるということです。もし8888がすでに使用されている場合は別のポートを利用してください。
# デフォルトのポート番号を指定
c.ServerApp.port = 8888
2. IP アドレスの指定:Jupyter notebookサーバーを特定の IP アドレスでのみバインドするように指定できます(例: ローカルホスト、0.0.0.0など)。つまり、ここでJupyter notebookサーバーと通信をするクライアントを制御することができます。c.ServerApp.ip = 'localhost'または c.ServerApp.ip = '127.0.0.1' に設定することで、Jupyter Notebookサーバーは自分自身であるデバイスのみからのアクセスを許可することになります。一方でc.ServerApp.ip = '0.0.0.0'はインターネットからのアクセスを受け付ける設定です。0.0.0.0 は、"任意のIPアドレス" を意味します。サーバーが 0.0.0.0 でバインドされている場合、ローカルホスト(127.0.0.1)だけでなく、外部のネットワークインターフェース(ローカルネットワークのIPやインターネットに接続されている場合など)からもアクセス可能になります。
# 全てのIPアドレスから接続を許可
c.ServerApp.ip = '0.0.0.0'
3. パスワードの設定:Jupyter Notebook サーバーにパスワードを設定して、不正なアクセスを防ぐことができます。
# ハッシュ化されたパスワードを設定
c.PasswordIdentityProvider.hashed_password = 'sha1:your_hash_here'
4. 自動起動ブラウザの無効化:サーバー起動時に自動で(そのサーバー自身であるローカルマシンの)ブラウザが開く動作を無効化します。
# 自動でブラウザを開かない
c.ServerApp.open_browser = False
5. Notebook ファイルのルートディレクトリ:Jupyter Notebook サーバーがアクセスするディレクトリを指定できます。きちんと整理すると、Jupyter notebookサーバーを介して操作する.pyや.ipynbはサーバー側にファイルとして保管されていて、それらのファイルを操作していくことになります。つまりここで設定するルートディレクトリはサーバー側の設定になります。
# Notebookのルートディレクトリを設定
c.ServerApp.notebook_dir = '/path/to/your/notebooks'
6. HTTPS(SSL/TLS)の設定:Jupyter Notebook サーバーをセキュアな HTTPS 接続で動作させるように設定できます。通信を公開鍵と秘密鍵によって暗号化したい場合に利用します。ここで利用する鍵は別途生成する必要があります。
# SSL証明書と秘密鍵のパスを指定
c.ServerApp.certfile = '/path/to/ssl_cert.pem'
c.ServerApp.keyfile = '/path/to/ssl_key.pem'
パスワードの設定:
Pythonシェルを起動し、シェル上から下記のコードを実行してパスワードを作成します。
python3
from jupyter_server.auth import passwd
passwd()
表示されるハッシュをコピーし、Pythonシェルは終了します。なお、Linux画面でコピーを行うにはコピーする部分を選択し、右クリックからコピーできます。ペーストする場合も右クリックから行います。
構成ファイルを編集し、先ほどコピーしたハッシュを追加します。
nano ~/.jupyter/jupyter_notebook_config.py
c.ServerApp.ip = '0.0.0.0'
c.ServerApp.port = 8888
c.ServerApp.open_browser = False
c.PasswordIdentityProvider.hashed_password = '<コピーしたハッシュ>'
上記を追加出来たら、Ctrl+Oで上書きし、Ctrl+XでNanoを閉じます。
セキュリティグループの設定
これまでこのEC2インスタンスへのリクエストはSSH通信のみを許可しており、SSH用にはPort番号22のみを開放していました。今回EC2インスタンスはJupyter notebookサーバーとしても利用することになるため、別途このサーバーとしてのポートをセキュリティグループで開放してあげる必要があります。AWS管理コンソールでインスタンスのセキュリティグループを確認し、ポート8888を許可します。
セキュリティグループを編集
「インバウンドルール」を編集。
「カスタムTCPルール」を追加し、ポート8888を開放。
ソースを「自分のIP(My IP)」に制限。
Jupyter Notebookの起動
以下のコマンドからJupyter notebookを起動します。
jupyter notebook
出力されるURL(例: http://0.0.0.0:8888/)をコピーします。
接続しているEC2インスタンス上ではなく、クライアントPCのWebブラウザに先ほどコピーしたURLを、EC2インスタンスのパブリックIPに変更して貼り付け実行します。これでローカルPCのWebブラウザからJupyter notebookを起動することができるようになります。
http://<EC2パブリックIP>:8888
これにより、次のようなPassword付きのログイン画面が出てくればOKです。

起動したJupyter notebookサーバーは「Cntr+Z」で停止することができます。
インストールしたPythonについて
Amazon LinuxをAMIとしたEC2インスタンスにPythonをインストールした場合、Pythonのインストール先、ライブラリ保存先などは以下のようになります。
Pythonのインストール先
通常、Python(Python 3.xの場合)は/usr/bin/python3 または /usr/local/bin/python3 にインストールされます。python コマンドが python3 に対応している場合もありますが、通常は python と python3 は別々に存在します。インストール先は以下のコマンドで確認できます。
which python3 # Python 3.xのインストール場所を確認
ライブラリのインストールパス
ライブラリ(パッケージ)は通常、以下の場所にインストールされます。
システム全体のライブラリ(sudo 権限でインストールした場合など):
/usr/lib/python3.x/site-packages(Python 3.x)
ユーザーごとのインストール(--user フラグを使用した場合など):
~/.local/lib/python3.x/site-packages(Python 3.x)
また、virtualenv を使用して仮想環境を作成した場合、ライブラリはその仮想環境の lib/pythonX.Y/site-packages 内にインストールされます。
環境変数の設定
通常、Pythonをインストールした後、インストールされたパス(例えば、/usr/bin や /usr/local/bin)は既に $PATH 環境変数に含まれているため、追加の設定は必要ありません。
また、仮想環境を使用している場合、virtualenv で作成した環境が有効になっているときは、その環境内でインストールしたパッケージや実行ファイルが優先されます。また、特定のディレクトリにPythonをインストールした場合やカスタム環境を使用する場合は、PYTHONPATH 環境変数を設定して、Pythonがライブラリを探すディレクトリを指定することもできます。
export PYTHONPATH="/path/to/custom/python/lib:$PYTHONPATH"