リモートとホストマシンを区別しやすくするため、PS1をそれぞれ

  • リモートマシン:[vagrant]>
  • ホストマシン:[host]$

としました。

仮想マシン上でjupyter qtconsoleやipython kernelを起動する

[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に接続するには

[host]$ 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/{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/{user id}/jupyter/などして調べましょう。

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

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

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

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

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

[host]$ ssh 192.168.22.33
[host]$ vagrant ssh

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

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

~/.ssh/config
[host]$ 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とかも使えるようになります。

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

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

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

[host]$ 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を呼びましょう。

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

...

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

core.dumpエラー

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

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

といった書き込みを入れたスクリプトを入れていたので立ち上がりかけたconsoleが落ちる現象がありました。
立ち上がったのを見てからget_ipython().magic('matplotlib inline')(マジックコマンドを使うなら%matplotlib inline)を入力したほうが良いのでしょう。

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

[host]$ 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

まとめ

  • リモートマシンでipython kernelなどを起動する

[vagrant]> ipython kernel

  • 作られたjsonファイルをホストマシンにコピーする

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

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

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

[host]$ jupyter qtconsole --existing ./kernel-[kernel PID].json --ssh [ホスト名] # qtconsole立ち上げ
[host]$ jupyter console --existing ./kernel-[kernel PID].json --ssh [ホスト名] # ipython(jupyter console)立ち上げ

参考