🐡

WSL2環境からVSCode remote SSHでColabに接続したい

2022/03/05に公開

要約

具体的な解決策はまとめにまとめました。

経緯

私は個人用PCとしてGPUを搭載したWindowsマシンを所有しており、これを趣味のプログラミング、機械学習、ゲーム等に利用しています。

このマシンでモデルの学習を行うこともできるのですが、せっかくなら無料開放されているGoogle Colaboratoryのリソースも併用することで、学習の効率を上げたい。
とはいえ、エディタとしてjupyter notebookを使うのは実装効率の観点から避けたい。

そんなことを思いながらいい感じの解決手段を探していたところ、cloudflaredcolab-sshというPythonライブラリを用いることで、ローカルPCのVSCodeからColabインスタンスにSSH接続する方法を知りました[1][2]

しかし、これを普段使いのWSL2上から試そうとしたところ意外に手間取ったので、試行錯誤の過程で得られた気づきをここに整理しておこうと思います。

各ツールに対する大雑把な理解

cloudflaredは、安全性を担保しつつポートを公開してくれるサービスのようです。
これを次のように用いることで、ローカルPCとColabインスタンスのSSH通信が可能になります。

  1. Colabインスタンス上でsshdを起動+cloudflaredでSSH接続受付用のURLを払い出し
  2. ローカルPCからcloudflaredを用いて1.で払い出されたURLにSSH接続

colab-sshは、この手順1.をいい感じに実施してくれるライブラリのようです。

実行環境

今回ColabへのRemote SSH接続を試した環境は次のとおりです。

  • Host OS: windows 11 Pro
    • VSCodeインストール済
  • WSL2: Ubuntu-18.04
    • codeコマンドでVSCodeが利用できるように設定済
    • cloudflaredインストール済
    • ~/.ssh/configにcloudflaredの接続設定済

先んじて述べておくと、以降で述べる問題はcloudflaredのインストール、及び~/.ssh/configの設定をWindows HostOS上で行うことで回避できます
私は開発以外の用途でPCを利用することもあり、HostOSの環境にできるだけ変更を加えたくなかったのでWSL2上にcloudflaredを入れましたが、気にならない方はHostOSに入れてしまう方が無難だと思います。

問題

上記のような環境においては、WSL2上の設定&cloudflaredが利用できず、Colabに接続できない問題が確認されています[3]
諸々の動作を確認した限りでは、これは以下の仕様によって引き起こされているように見えました。

  • VSCodeをhostOS上にインストールした場合、remoteSSH extensionの所在地もHostOS上になり[4]、WSL上でVSCodeを起動した場合でも、HostOS上のextensionが利用される。
  • HostOSに紐付いたremote SSH extensionは、SSHクライアントを呼び出す際にcmd.exeを利用している(変更オプションは確認した限り存在しない[5])。
  • cmd.exeから呼び出されるSSHクライアントは、デフォルト設定だとhostOS上のもの(ssh.exe)になっている。

cmd.exeから呼ばれるSSHクライアントのパスはremote.SSH.pathオプションで変更できますが、受理されるのはコマンドプロンプトで実行可能なファイルのパスに限られているようです。
つまり、WSL上に存在しているsshクライアントを指定したり、「内部でWSL上のsshを実行するような、コマンドプロンプトで実行可能なコマンド」を直接記載することはできません。
問題の概観
問題の概観

取りうる解決策

この問題に対して取りうる解決策としては、次の3つが考えられます。

パターン1. SSH接続に必要な設定をHostOSに寄せる

これは 実行環境の節でも述べたとおりですが、以下2点を修正する方法です。

  • cloudflaredをHostOS上にインストールする
  • cloudflared用のssh設定をHostOS上(C://Users/yourname/.ssh/config)で行う

remote SSH extensionの現状の仕様を正とする場合、HostOSに設定を寄せてしまうこの方法が一番まっとうではないかと思います。

パターン2. remote SSH extensionをWSLに寄せる

これはパターン1と真逆の発想で、具体的には次のことを行います。

  • VSCode本体をWSLにインストールする
  • WSL上で起動したVSCodeのGUIをWindows側に転送する手段を用意する(具体的にはX11 forwardingの仕組みを整えることになりそう)

この方法でもいけるという報告は確認出来ますが、特に後者の設定がややこしそう(wsl側に適当なライブラリを入れるだけでなく、HostOS側にも何らかのソフトウェアを入れる必要がありそう)です。また、WSL側にVSCodeを入れること自体あまり推奨されていないようにも見受けられます

私の場合、Windows上にすでにインストールされているVSCodeの処遇を考えるのも面倒だったので、この方法は見送りました。

パターン3. なんとかして現状の環境を維持する

現状の環境に可能な限り手を加えずに問題を解決する方法としては、次があります。

  • wsl上のsshクライアントを呼び出す.batファイルを作成する
  • 上記ファイルの所在地をremote.SSH.pathオプションに設定する

.batファイルはcmd.exeで実行可能なので、そのパスをremote.SSH.pathオプションに設定できます。このファイル内部でWSL上のsshを呼び出すことで、やや迂遠ではあるものの、「Windows上に存在するRemoteSSH extensionからWSL上のSSHクライアントを呼び出す」ことが可能になります。

解決イメージ
解決イメージ

あまりスマートなやり方ではないようにも思えますが、今回はHostOSに加える変更が一番少ないこの方法を採用することにしました。
作成した環境をどれくらい真面目に使うかもまだわからない状況なので、仮にやっぱり微妙かも・・・となったときの切り戻しが簡単という点でもこの方法に利があるかなと感じています。

注意点

ただし、この方法を採る場合には2つほど注意点があります。

まず第一に、.batファイルでWSLのsshを呼び出す場合、VSCode上でSSHのパスワードを入力するためのダイアログが立ち上がってくれず、timeoutになってしまう問題を確認しています。
ダイアログを立ち上げることなしに認証を行えればこの問題は回避できるのですが、丁度
linus-colab-sshというライブラリにパスワード不使用(ssh鍵利用)の認証が実装されています。
実際colab-sshの代わりにこちらを用いてみたところ、問題なく認証を通すことが出来ました。

第二に、remote.SSH.localServerDownloadオプションを常に有効(always)にしている場合、接続段階でエラーが出てしまうようです。
このオプションが有効になっていると、VSCode Server(リモート開発環境でVSCodeを動かすための諸々)をwebからダウンロードする代わりに、HostOSからSCPで転送します。リモート開発環境とHostOSが同一のローカルネットワークに存在している場合[6]、この仕組みでリモート環境のセットアップが高速化できる利点があります[7]
RemoteSSHでは ssh.exescp.exeが同じディレクトリに存在することを前提としているようなので、今回の回避策においては、作成した.batファイルと同じディレクトリにscp.exeが存在しない場合、scpが利用できずにエラーになってしまうようです。
では.batファイルをscp.exeと同じ場所に置けばエラーが解消されるかというと、おそらくそう単純な話ではなさそうな気がしています[8]autoに変更するとwebからのダウンロードにfailoverしてくれるようなので、適当に変更しておくのが良さそうです。

まとめ

WSLにインストールしたcloudflared&ssh設定を用いてVSCode RemoteSSHでColabインスタンスに接続したい場合、次の方法が有効でした。

  • wsl上のsshクライアントを実行する.batファイルを作成し、そのパスをremote.SSH.pathオプションに設定する
  • colab notebook上ではcolab-sshの代わりにlinus-colab-sshを用い、SSH認証鍵による接続受付を行うことで、パスワード入力を回避する

cloudflaredのインストール~実際にColabのインスタンスに接続するまでに必要な具体的な設定やコマンドについてはこちらにまとめました。

余談

今回colab-sshの代わりに利用したlinus-colab-sshですが、Colab側で最低限必要とされる設定に加え、リポジトリ作成者の方が個人的に利用するための設定も含まれているようで、colab-sshに比べると少し設定に時間がかかってしまいます。
単にsshdとcloudflaredの設定を行うだけなら自分でもできそうな気がする上、cloudflaredをもう少しちゃんと理解するきっかけにもなりそうなので、暇を見つけてやってみようかなと思います。

脚注
  1. https://atmarkit.itmedia.co.jp/ait/articles/2109/03/news030.html ↩︎

  2. https://qiita.com/ezoalbus/items/f75ffb910d9ee9202baf ↩︎

  3. https://qiita.com/tksmatsubara/items/0b2d675cd663fbfc0cad ↩︎

  4. https://code.visualstudio.com/docs/remote/faq#_how-do-the-remote-development-extensions-work ↩︎

  5. terminal.integrated.defaultProfile.windows等のoptionでwsl.exeを利用するように変更しても変わらないようです。 ↩︎

  6. リモート開発環境としてlocalPCのDocker Containerを利用する場合などが該当します ↩︎

  7. 自分がこのオプションを有効にしたのは随分前になるので、間違っていたらすいません ↩︎

  8. おそらくSCPのプロトコルを使うためにもcloudflaredを用いる必要があるが、HostOS上のscp.exessh.exeと同様の理由でcloudflaredを参照できないので、いずれにせよエラーになるのでは・・・というような意味です(きちんと動作確認をしたわけではないので想像の域を出ませんが) ↩︎

Discussion