Azureマシンのjupyterをローカルから開けるようにする

Azureで仮想マシンを起動すると毎回パブリックIPアドレスが変わるのでsshするときとても面倒です。

さらに、Azureマシン上でjupyter notebookを立ち上げたときも毎回tokenの値が違うのでこれをコピペでブラウザに貼り付け、localhostの部分を自分のIPアドレスDNS名に置き換えるという作業がとてもとても面倒です。

あぁもう面倒すぎる...

ということで、重い腰を上げてAzure CLIを使ってIPアドレスを意識せずにsshログインしたり、jupyterのtokenつきURLをローカルマシン上で開けるようにできるシェルスクリプトを作りました。

github.com

準備

https://github.com/tanakatsu/azure-cli-wrapper-scripts のファイルをダウンロードしておきます

  1. Azureのマシン名やsshキーのパスなどを設定

    azure-env.shを編集して自分の設定に置き換えます

    export vmName=YourVmName
    export resourceGroup=YourResourceName
    export privateKeyPath=PathToPrivateKey # ~/.ssh/your_azure_private_key
    export jupyterRootDir=. # relative path from home directory
    
  2. Azure CLIのインストール

    公式ページに方法が書いてありますが Macの場合は brew update && brew install azure-cli で一発でインストールできます

  3. az loginでログインしておく

     To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code GDGSSH8M3 to authenticate. 
    

    のようなレスポンスが返ってくるので指示通り、https://aka.ms/deviceloginを開いて コードを入力します。「デバイスMicrosoft Azure Cross-platform Command Line Interface アプリケーションにサインインしました。...」という画面が表示されればokです

使い方の例

# 環境変数とエイリアスのセットアップ
source azure-env.sh
source azure-alias.sh

# VMを起動する
azure-start

# リモートマシンのjupyter notebookをローカルマシンから立ち上げる
azure-start-jupyter

起動したjupyter notebookをローカルマシンのブラウザで開くときは別のターミナルを使います。

## in another terminal

# 環境変数とエイリアスのセットアップ
source azure-env.sh
source azure-alias.sh

# IPアドレスを取得
azure-ip

# jupyter notebookをブラウザで開く
./azure-open-jupyter.sh

これで毎回変わるIPアドレスを意識することなくローカルマシン上での操作だけでjupyter notebookを使えるようになります (◍•ᴗ•◍)

シャットダウンは

# 終了し割り当てを解除する
azure-stop

Azure CLIaz vm stopだとマシン停止だけで割り当て解除まではされないようで az vm deallocateも同時に行っています。 管理画面で停止ボタンを押すと割り当ての解除までやってくれるのでCLIでも割り当て解除までやってほしいです。。(stopだけだと課金が続いちゃいます ><)

シェルスクリプトの中でやっていること

jupyter notebookをリモートで起動する

今まで知らなかったのですが sshコマンドでは ssh接続時に直接コマンドを実行することもできるようです。

例えば、ssh ユーザー名@ipアドレス ls とすればリモートマシンのホームディレクトリのファイルのリストが返ってきます。

これを利用してjupyter notebookを起動します。

具体的なコードはこちら

alias azure-start-jupyter='ssh -i ${privateKeyPath} -o "StrictHostKeyChecking no" ubuntu@${instanceId} "export PATH=~/anaconda3/bin:$PATH;source activate fastai;cd ${jupyterRootDir};jupyter notebook"'

sshを使ってリモートのコマンドを実行したとき.bashrcは実行されないようでその中でやっているPATHの設定等などは明示的にやってあげる必要があります。

リモートで起動したjupyter notebookのtokenを取得する

jupyter notebook listコマンドで tokenつきのURLが出力されるのでこれを sshコマンドを使ってリモートマシン上で実行します。 あとは sed やら awk やらでローカルのブラウザで開くためのURLを構築します。

具体的なコードはこちら

list=`ssh -i ${privateKeyPath} ubuntu@${instanceId} 'export PATH=~/anaconda3/bin:$PATH;source activate fastai;jupyter notebook list'`
url=`echo $list | grep http | sed -e "s/localhost/${instanceId}/g" | awk '{print $4}'`
echo $url
open $url


sshコマンドのいろいろな使い方に関しては以下の記事が大変参考になりました。 orebibou.com