Chapter 10

リモート開発

からあげ
からあげ
2024.02.25に更新

VS CodeのRemote Development拡張

VS Codeで他のPC(特に非力なRaspberry Pi等)上のファイルやクラウド(GCP等)上のファイルを編集したくなるケースがあると思います。

そんなときは、Remote Development拡張を使いましょう。

Remote Developmentの概要は以下の図の通りです。


VS Code Remote Developmentより引用

Remote Development拡張には以下の様な特徴・利点があります

  • SSHのパスワード認証方式・公開鍵認証方式の両方に対応(推奨はセキュアな公開鍵認証方式)
  • ターゲット(上図のRemote OS)はラズパイ等のデバイスの他、クラウドやDockerコンテナ(WindowsのWLSも)に対しても同様にリモート開発できる
  • ローカルPC(上図のLocal OS)上のVS Codeからターゲット(Remote OS)のターミナル操作・デバッグも可能

つまり、いいことだらけですね。開発内容によっては、VS Codeで開発が完結できちゃいそうです。VS Codeでのリモート開発環境の構築方法に関して順に解説していきます。

VS Codeでのリモート開発環境構築の流れ

基本的な流れは、ターゲット(Remote OS)に関わらず以下となります。

  • ターゲット(Remote OS)の設定
  • SSHの設定(パスワード認証 / 公開鍵認証)
  • ローカルPC(Local OS)のVS Code設定

この記事では、ターゲットとしてRaspberry Pi(ラズパイ)・クラウド(GCPを例として説明)、ローカルPCとしてMac/Linuxを想定してリモート開発の方法を解説します。

それぞれの具体的な手順を記載していきます。DockerコンテナやWindowsに関してはこの記事では対象外となります(すみません)。Windowsでも基本的な流れは同じなので、何かしら参考になるところはあるかとは思います。

ターゲット(Remote OS)の設定

ラズパイとクラウドの設定に関して説明します。ラズパイに関しては、代わりにLinux OSのPCを使う場合も同じ様な流れで実施できます。クラウドはGoogle Cloud Platform(GCP)を例として説明します。

ラズパイの設定

以下記事を参考に、ラズパイが起動できるところまで設定ください(ディープラーニングの設定までは不要です)。

https://karaage.hatenadiary.jp/entry/rpi4-dl-setup

Raspberry Piの設定でSSHを有効にするのを忘れない様にしましょう。

ホスト名はraspberrypiの前提で進めます。

GCPの設定

以下記事を参考に、GCP(Google Cloud Platform)のAI Platformで適当なインスタンスを立てましょう。

https://qiita.com/karaage0703/items/77d6d75db9105a5e8983

インスタンスが作成できたらOKです。

SSHの設定

SSHの認証方式の基礎知識

最初にSSHの設定において重要となるSSHの認証方式に関して、簡単に記載します。SSHの認証方式は、代表的なものとして大きく「パスワード認証方式」「公開鍵認証方式の」2つの方式があります。

パスワード認証は、通常のパスワードを登録・認証する方式です。公開鍵認証はやや複雑で、秘密鍵と公開鍵という仕組みを使ってアクセスする方式です。詳細は割愛しますが、要は秘密鍵と公開鍵という2つの鍵のペアを勘合札のように使って認証を行う仕組みです。今回の場合は、公開鍵をターゲット側(Remote OS)において、秘密鍵を使ってアクセスする形になります。

以下のサイトがGCPへの接続まで書かれていてわかりやすいです。

https://sleepless-se.net/2018/09/15/gcp-ssh/

この記事では以下3つの組み合わせを解説します。

SSH認証方式 ターゲット
パスワード認証 ラズパイ
公開鍵認証 ラズパイ
公開鍵認証 クラウド(GCP)

セキュアな公開鍵認証が推奨なのですが、手元のラズパイのファイルをパッと編集したいときを想定して、パスワード認証方式に関しても記載しています(クラウドはセキュリティの関係上、公開鍵認証方式のみとなります)。公開鍵認証方式は、ターゲットがラズパイ(Linux PC)かクラウド(GCP)かで若干お作法が変わってくるので、それぞれ説明します。

パスワード認証方式でラズパイにアクセスする設定

まずは、ラズパイにパスワード認証方式でssh接続できるか確認しましょう。ラズパイのユーザーがpiホスト名がraspberrypiの場合は以下となります。

$ ssh pi@raspberrypi.local

ラズパイのユーザーパスワードを入力して、ログインできればOKです。

続いて、~/.ssh/configに以下のような設定を追記します。

Host rpi
	HostName raspberrypi.local
	User pi
	port 22

これにより、以下コマンドでラズパイにsshでアクセスできるようになります。

$ ssh rpi

この設定はVS Codeでアクセスするためにも必要な設定なので、必ず設定するようにしてください。パスワード認証方式でアクセスできれば良いという人は、この後の公開鍵認証方式の設定は飛ばして、VS Codeの設定に進みましょう。

公開鍵認証方式でラズパイにアクセスする設定

公開鍵認証方式の場合は、まずローカルPC(Linux or Mac)で秘密鍵と公開鍵を作ります。以下のコマンドを実行してください。-Cオプションに記載するコメントの記載は任意です(空白でもOKです)。

$ mkdir ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa -C ''

作成するとき、以下のように鍵の名前の入力を促すメッセージが出てくるので、好きな名前を記載して保存します(ここではrpiとします)

Enter file in which to save the key (/Users/<user name>/.ssh/id_rsa): rpi

続いて、パスワードを入力・確認と2回要求されるので、自分の好きなパスワードを入力してください(これ以降、これを鍵のパスワードと呼びます)。rpirpi.pubという2つのファイルが生成されます。それぞれが、秘密鍵と公開鍵になります。公開鍵をRemote OS側に置いて、秘密鍵を使ってLocal OS側からRemote OSにアクセスすることに注意してください。

公開鍵をRemote OSに設定します。設定はssh-copy-idコマンドを使うと楽です。

$ ssh-copy-id -i rpi.pub pi@raspberrypi.local

このときパスワードには、パスワード認証のパスワードを入力します。これにより、ラズパイ側の ~/.ssh以下にauthorized_keysとして公開鍵が置かれます。

続いて、sshで秘密鍵を使ってアクセスします。

$ ssh pi@raspberrypi.local -i ~/.ssh/rpi

パスワードには、鍵のパスワードを入力してください。

ここで、ローカルからは秘密鍵を使ってアクセスするので、使用する鍵のファイルはrpi.pubでなくrpiである点に注意してください。これを間違えると bad permissionsだったり、パーミッション無理やり変更してもinvalid formatというエラーが出てアクセスできません。鍵認証の仕組みを覚えていれば間違えませんね。私は、恥ずかしながら最初ハマりました。sshでアクセスできれば鍵認証はOKです。

続いて、パスワード認証のときと同様に~/.ssh/configに設定を追記します。公開鍵認証方式の場合はIdentityFileで鍵の場所を指定する必要があります。

Host rpi
	HostName raspberrypi.local
	User pi
	port 22
	IdentityFile ~/.ssh/rpi

これにより、以下コマンドでラズパイにsshでアクセスできるようになります。

$ ssh rpi

この設定はVS Codeでアクセスするためにも必要な設定なので、必ず設定するようにしてください。

公開鍵認証方式でクラウド(GCP)の設定

公開鍵認証方式の場合は、まずローカルPCで秘密鍵と公開鍵を作ります。ラズパイにアクセスするときと同様ですが、コメントにはGCPで使用しているメールアドレスを使用する必要があるので注意してください。ここではxxxx@gmail.comとします。

$ mkdir ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa -C 'xxxx@gmail.com'

以下のように鍵の名前の入力を促すメッセージが出てくるので、好きな名前で保存します(ここでは gcpとします)

Enter file in which to save the key (/Users/<user name>/.ssh/id_rsa): gcp

続いて、パスワードを入力・確認と2回要求されるので、自分の好きなパスワードを入力してください。gcpgcp.pubという2つのファイルが生成されますが、それぞれ秘密鍵と公開鍵になります。

公開鍵の方をGCPに設定します。まずは公開鍵 gcp.pub の中身をコピーします。中身はエディタで開いても、以下のとおりcatコマンドでもOKです。

$ cat gcp.pub

Mac限定ですが、以下のコマンドでクリップボードに直接コピーすることも可能です。

$ pbcopy < gcp.pub

続いて、GCPのインスタンスに鍵を設定しましょう。インスタンスの詳細画面を開きます。AI Platform(GCEでも可)の以下画面で、インスタンス名をクリックします。

インスタンスの詳細情報が出てきます。ここで画面の中ほどに「外部 IP」という表示があります。これがインスタンスのIPアドレスとなります。

そのあと、画面上の「編集」ボタンをクリックするとインスタンスの編集が可能となります。下の方に「SSH認証鍵が0個あります」という表示があるので、「表示して編集」「項目を追加」をクリックして表示されるテキストボックスに、先ほどコピーした公開鍵の情報をペーストして保存しましょう。もし入力できない場合は、最初に画面上の「編集」ボタンがクリックしたか確認してください。

これで設定は完了です。あとは、以下コマンドでsshでアクセスします。<user name>はgmailのアカウント名、<ip address>はインスタンスのIPアドレスです(インスタンスの詳細画面に出てきたものです)。

$ ssh <user name>@<ip address> -i ~/.ssh/gcp

続いて、おなじみの~/.ssh/configに設定を追記します。記載する内容は以下です。ターゲットが複数の場合は、同様のフォーマットで複数書くことも可能なので、ラズパイの設定が既にあっても、気にせず下に追記すればOKです。

Host gcp
	HostName <ip address>
	User <user name>
	port 22
	IdentityFile ~/.ssh/gcp

これにより、以下コマンドでラズパイにsshでアクセスできるようになります。

$ ssh gcp

しつこいですが、この設定はVS Codeでアクセスするためにも必要な設定なので、必ず設定するようにしてください。

ローカルPC(Local OS)のVS Codeの設定

いよいよVS Codeの設定です。VS Codeはすでにインストールされている前提です。以下コマンドでVS CodeのRemote Development拡張をインストールします。

$ code --install-extension ms-vscode-remote.vscode-remote-extensionpack

すると、左側にPCのアイコンを選択して、REMOTE EXPLORERのメニューから「SSH Targets」を選択すると、以下の様に~/.ssh/configで設定した項目rpi, gcpが表示されます。

ここで、項目を選択すると右側に+のついたアイコンが表示されるので、アクセスしたい方をクリックしましょう。

すると、新しいウィンドウが表示され、真ん中上にパスワードを求める画面が表示されます。

パスワード認証で接続するときは、ラズパイのユーザーのパスワードを。公開鍵認証方式で接続する場合は、鍵のパスワードを入力してください(どちらかわからない場合は、パスワード入力ウィンドウのメッセージの末尾を確認してください。for ssh keyと書いてあれば公開鍵認証方式で、for <user name>@<host name>となっていればパスワード認証です)。

認証が完了すると、Remote OSでVS Codeのリモートアクセスのためのセットアップが始まります。初回は多少時間がかかります。

セットアップ完了したら、左上のファイルのアイコンをクリックしましょう。以下の様に表示されます。

ここで、Connected to remoteの下にある「Open Folder」アイコンをクリックします。

すると、以下のようにRemote OSのディレクトリが表示されます。開発したいディレクトリ(リポジトリ)を選択しましょう。

ここまでラズパイの例で実践しましたが、GCPでも流れは全く同じです。以下の様にGCPのディレクトリ(リポジトリ)にVS Codeでアクセスできます。

あとは、自由にリモートのファイルをVS Codeでエディットしてリモート開発をしましょう。

VS Codeのリモート開発Tips

VS Codeのリモート開発時のTipsです。

Remote OSのターミナル操作

リモート接続した状態で View -> Teminal と実行すると、VS Codeの右下にRemote OSのターミナル画面が表示されます。ターゲットのターミナル操作をVS Codeで完結することができるので便利ですね。

sshのパスワードを省略

公開鍵認証をしている場合は、以下の通りコマンドを実行することでパスワード入力を省略できます。

$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa

注: ~/.ssh/id_rsaの部分は自分で作成した秘密鍵の名前を指定してください。

サーバの接続を切れないようにする

クライアントPCの~/.ssh/configに以下のように追記することで1時間接続切れなくなります。

Host <host name>
     Hostname <ip address>
     User <user name>
     IdentityFile ~/.ssh/id_rsa
     ServerAliveInterval 60
     ServerAliveCountMax 10

クライアントだけ設定しても接続が切れる場合は、サーバ側の /etc/ssh/sshd_configにも設定しましょう。サーバーに以下設定追記しましょう(デフォルトだとコメントアウトされているケースが多いので、有効にしましょう)。

ClientAliveInterval 60
ClientAliveCountMax 60

参考:SSHコマンドがだるすぎる、、、公開鍵認証&ssh configで楽にしましょう

サーバーの負荷を減らす方法

VS Codeを使ってサーバにSSH接続するとCPUリソースを使いつぶすことがあるようです。特にチームで複数人同一のサーバにアクセスするようなときは、以下のような対応をしておくのがベターです。

https://blog.masuyoshi.com/【vscode使用者注意】サーバーリソース食い散らかす/

https://narwhale.net/post-584/

複数人でVS Codeで同一のリモートサーバを使って開発しているときにログインしている人を知る方法

複数の人で同じリモートサーバにVS Code経由でログインしているケースです。

普通にコンソールからsshでログインしたらwhoコマンドでログインしている人が分かるのですが、VS Codeでログインするとwhoだとみえません。

誰もいないなーと思って、サーバの再起動したら、作業中の人に恨まれちゃいますね。そんなときはwhoコマンドの代わりに以下のコマンドを使いましょう。

$ ps aux | grep sshd 

これでばっちりですね!

参考リンク

VS Code Remote Development

買ったらまず実施!RaspberryPiのセキュリティ対策

[秘密鍵/公開鍵]GCPにSSHで接続する方法

Visual Studio Codeで使えるリモート環境のdevcontainerが意外と便利そうだったのでまとめ