9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vagrant上のipython kernelに接続してjupyter を使う

Last updated at Posted at 2017-12-29

まえがき

サーバー上で動作するipython kernel(またはjupyter notebook)にクライアントマシン上のターミナル(またはブラウザ)から接続するためのハウツー記事です。

前提

  • Virtualboxインストール済み
  • vagrantインストール済み
  • python動作可能なOSイメージ取得済み
  • 仮想マシン上でpython, ipython, jupyter notebook関連インストール済み

環境

()内は本記事で実際に使用したOS, アプリケーション名です。

種別 構成 ipythonに接続するとき使うもの jupyter notebookに接続するとき使うもの
サーバー 仮想マシン(Virtualbox+vagrant) ipython kernel jupyter notebook
クライアント 実マシン(Ubuntu 16.04) ターミナル(Gnome Terminal) ブラウザ(Firefox57.0.4 64bit)

表記の注意

サーバー上の操作とクライアント上の操作を区別しやすくするため、PS1の表記をそれぞれ

  • サーバー:[vagrant]%
  • クライアント:[cliant]$

としました。

ssh接続してjupyter console(ipython)を立ち上げる

vagrant sshしたり仮想マシンを表示したウィンドウ上でターミナル立ち上げるなどしてipython kernelを実行します。
ipython kernelipython --helpに書いてあるように

kernel
    Start a kernel without an attached frontend.
  フロントエンドアプリケーションなしにipythonカーネルを実行するコマンドです。
[vagrant]% ipython kernel  # ipython起動

NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work.

To exit, you will have to explicitly quit this process, by either sending
"quit" from a client, or using Ctrl-\ in UNIX-like environments.

To read more about this, see https://github.com/ipython/ipython/issues/2049


To connect another client to this kernel, use:
    --existing kernel-4232.json

一番下の行が重要です。「kernelに接続するには --existing kernel-4232.jsonを使って下さい」とあります。
リモート上のipython kernelに接続するには

[cliant]$ jupyter console --existing [kernel情報の書かれたJSONファイルパス] --ssh <ホスト名>

と打ち込みますが、まず、"kernel情報の書かれたJSONファイル"が必要です。

JSONファイルの確認

jupyter --runtime-dirというコマンド表示されるパスにJSONファイルが作成されていることを確認して下さい。

[vagrant]%  jupyter --runtime-dir
/run/user/998/jupyter

こうするとipython kernelを立ち上げたサーバー上の"/run/user/{UID}/jupyter/ "というパスにJSONファイルが作成されます。({user uid}は特別に指定していなければ1000とか9百番台くらいの数字だと思います。)
JSONファイルにはポート番号やipアドレスなど、リモートのkernelへ接続するのに必要な情報が含まれています。

ipython_kernel起動した時にできるJSONのパス
[vagrant]%  ls /run/user/998/jupyter/                 
kernel-4232.json
JSONファイルの中身
[vagrant]%  cat /run/user/998/jupyter/kernel-4232.json
{
  "shell_port": 37393,
  "iopub_port": 34411,
  "stdin_port": 44867,
  "control_port": 42805,
  "hb_port": 37427,
  "ip": "127.0.0.1",
  "key": "132a7ffd-2f3f9cb12201448d4358b5df",
  "transport": "tcp",
  "signature_scheme": "hmac-sha256",
  "kernel_name": ""
}

なお、kernel-****.jsonの数字は起動したipython kernelのPIDが充てられます。

リモート上でqtcconsoleを立ち上げると、ホスト・リモート共用のqtconsoleが立ち上がります。
名前空間が共有されるので、意図しない変数の書き換えや操作に気をつけましょう。

[vagrant]% jupyter qtconsole  # qtconsole起動

qtconsoleを立ち上げた時はJSONファイル名は表示されずにリモート上にqtconsoleが現れます。JSONファイル名はPIDを調べる[vagrant]% ps aux | grep ipythonか、[vagrant]% ls /run/user/{UID}/jupyter/などして調べましょう。

sshを使って仮想マシンに接続できるようにする

続いてクライアント上でリモートの仮想マシンにsshコマンドでssh接続を行ったり、scpでセキュアコピーを行ったりする設定をします。

バーチャルマシンを動かしているディレクトリ上で、vagrant ssh-configコマンドを打つと、vagrant sshコマンドでssh接続するための情報を見ることができます。そこで

[cliant]$ vagrant ssh-config --host 192.168.22.33 >> ~/.ssh/config     

としてconfigファイルにssh設定を保存します。
これで

[cliant]$ ssh 192.168.22.33
[cliant]$ vagrant ssh

が同じ意味になりました。

sshするときはこの情報が使われます。

~/.ssh/config
[cliant]$ cat ~/.ssh/config
Host 192.168.22.33
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking xxxxxx
  PasswordAuthentication xxxxxx
  IdentityFile /home/u1and0/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

適当なIPアドレス192.168.22.33を与えましたが、適当なホストネーム(たとえばvagrantとする)を与えればconfigファイルの1行目がHost vagrantとなって$ ssh vagrant$ vagrant sshが同じ意味になります。(むしろややこしい)

ややこしいけれども仮想マシンを立ち上げているディレクトリ以外の場所でもssh vagrantとかssh 192.168.22.33で接続できるのでメリットはあります。

configファイルに設定を保存することでsshだけでなくscpとかも使えるようになります。

[cliant]$ scp 192.168.22.33:/run/user/998/jupyter/kernel-3701.json ./

上のコマンドでは仮想マシン上のjupyterカーネルの設定ファイルkernel-3701.jsonをクライアント上の現在ディレクトリにコピーをします。

ssh接続してjupyter console(ipythonの親戚)立ち上げる

[cliant]$ jupyter console --existing ./kernel-3701.json --ssh 192.168.22.33 

でipython shellのような見た目のjupyter consoleがクライアント上のshellで立ち上がります。

Screenshot from 2017-12-29 22-47-35.png

ipythonを呼ぼうとするとエラーが出るので、代わりにjupyter consoleを呼びましょう。

[cliant]$ ipython --existing ./kernel-7149.json --ssh 192.168.22.33

...

[TerminalIPythonApp] CRITICAL | Bad config encountered during initialization: 
[TerminalIPythonApp] CRITICAL | Unrecognized flag: '--existing'     

2018年9月、anaconda環境をアップデートしたら?ssh接続のリモートホスト上でjupyter consoleが立ち上がりませんでした。代わりにipythonを起動するとipythonが立ち上がりました。アプデでjupyter consoleとipythonが統合されたのでしょうか。(未確認)

core.dumpエラー

~/.ipython/profile_default/startup/スクリプトに

get_ipython().magic('matplotlib inline')
get_ipython().magic('matplotlib auto')

といった書き込みを入れたスクリプトを入れていたので立ち上がりかけたconsoleが落ちる現象がありました。
ssh接続したシェルでipythonjupyter consoleを打ち込まず、kernel-.jsonをコピーして、jupyter console --ssh 192.168.22.33 --existing kernel-<PID>.jsonを打ち込みましょう。
立ち上がったのを見てからget_ipython().magic('matplotlib inline')(マジックコマンドを使うなら%matplotlib inline)を入力したほうが良いのでしょう。

ssh接続してjupyter qtconsole立ち上げる

[cliant]$ jupyter qtconsole --existing ./kernel-4640.json --ssh 192.168.22.33

でクライアント上でjupyter qtconsoleが立ち上がります。

Screenshot from 2017-12-29 23-38-51.png
ホスト上のshellに現れるメッセージ

プロットもできますし、!whoamiと打ち込んでホスト名を聞くとちゃんとvagrant上で実行されているjupyterであることがわかります。

Screenshot from 2017-12-29 23-34-28.png

jupyter notebook立ち上げてssh接続する

ホスト側の作業1

ポートを開く

Vagrantfileを編集してjupyter notebook用のポートを開きます。

[cliant]$ vi Vagrantfile
Vagrantfile
Vagrant.configure("2") do |config|
 config.vm.network "forwarded_port", guest: 8887, host: 8887
end

ゲスト側の作業1

コンフィグファイルの作成

jupyter notebookの設定をいじるための設定ファイルを作成します。

[vagrant]% jupyter notebook --generate-config

デフォルトでは~/.jupyterというディレクトリ下にファイルが生成されます。

jupyter_notebook_config.pyの設定

~/.jupyter/jupyter_notebook_config.py
c.NotebookApp.ip = '*'  # いずれのipアドレスからでも接続可能
c.NotebookApp.open_browser = False  # jupyter notebook開いたと同時にブラウザを開かない
c.NotebookApp.port = 8887  # デフォルト値は8888

パスワード作成(設定しなくても開けるがセキュリティ的に危険)

jsonファイルにパスワードのキーが書き込まれる

[vagrant]% jupyter notebook password
Enter password:  ****
Verify password: ****
[NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json

ホスト側の作業2

ホストのブラウザのアドレス欄にhttp://localhost:8887とうちこむとパスワード打ち込めと現れるので、さっき設定したパスワードを打ち込みます。

まとめ

  • サーバーでipython kernelなどを起動する

[vagrant]% ipython kernel

  • 作られたjsonファイルをクライアントにコピーする

    • scp使う、またはコピペでクライアントの適当な場所にファイル作って貼り付ける

    [cliant]$ scp [ホスト名]:/run/user/[user_id]/jupyter/kernel-[kernel PID].json [コピー先]

  • ホスト上でjupyterなどを立ち上げる際にオプションでjsonファイルの指定とssh接続先ホスト名を入力する

    • [cliant]$ jupyter console --existing ./kernel-[kernel PID].json --ssh [ホスト名]
      • # サーバーマシン上のカーネルを使用してjupyter console(ipython的な奴)立ち上げ
    • [cliant]$ jupyter qtconsole --existing ./kernel-[kernel PID].json --ssh [ホスト名]
      • # サーバーマシン上のカーネルを使用してqtconsole立ち上げ
    • クライアントのブラウザのアドレス欄にhttp://localhost:8887
      • # サーバーマシン上のjupyter notebookに接続
        • http://は省略可能です。
        • ローカルホスト上に立ち上げたサーバーでないならば、localhostの代わりにIPアドレスを打ち込む(http://192.168.15.10:8887)と、実サーバーマシンに立ち上げたjupyter notebookにつなぐことができます。

参考

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?