Visual Studio で Linux で Python コードをリモートデバッグする
この記事では、リモート Linux コンピューターでの Python コードのデバッグをサポートするように Visual Studio のインストールを構成する方法について説明します。 このチュートリアルは、Visual Studio 2019 バージョン 16.6 に基づいています。
Visual Studio では、Windows コンピューター上でローカルおよびリモートで Python アプリケーションを起動およびデバッグできます。 Visual Studio では、debugpy ライブラリを使用して、CPython 以外の別のオペレーティング システム、デバイス、または Python 実装でのリモート デバッグもサポートしています。
Visual Studio 2019 バージョン 16.4 以前では、ptvsd ライブラリを使用しています。 Visual Studio 2019 バージョン 16.5 以降では、debugpy ライブラリによって ptvsd が置き換えられます。 debugpy を使用すると、デバッグ対象の Python コードによって、Visual Studio がアタッチできるデバッグ サーバーがホストされます。 このホスティングでは、サーバーをインポートして有効にするために、コードを少し変更する必要があります。 また、TCP 接続を許可するために、リモート コンピューターのネットワークまたはファイアウォールの構成を調整する必要がある場合もあります。
前提 条件
Python ワークロードをサポートしてインストールされた Visual Studio。 詳細については、「Visual Studioでの Python サポートのインストール」を参照してください。
macOS や Linux などのオペレーティング システムで Python を実行しているリモート コンピューター。
リモート コンピューターのファイアウォールでポート 5678 (受信) が開きます。これは、リモート デバッグの既定値です。
Linux コンピューターを設定する
簡単に Linux 仮想マシンを Azure 上に作成して Windows からリモート デスクトップを使用してアクセスすることができます。 仮想マシンの Ubuntu は、Python が既定でインストールされているため便利です。 別の構成がある場合は、「Python インタープリター 他の Python のダウンロード場所をインストールする」を参照してください。
ファイアウォールを構成する
リモート デバッグをサポートするには、リモート コンピューターのファイアウォールで受信ポート 5678 を開く必要があります。
Azure 仮想マシンのファイアウォール規則を作成する方法の詳細については、次の記事を参照してください。
- Azure portal を使用してネットワーク セキュリティ グループでネットワーク トラフィックをフィルター処理する
- Azure portal を使用してルート テーブルを使用してネットワーク トラフィックをルーティングする
- Azure portal を使用して Azure Firewall をデプロイして構成する
デバッグ用のスクリプトを準備する
Linux で Python コードをデバッグするためのスクリプトを準備するには、次の手順に従います。
リモート コンピューターで、次のコードを使用して guessing-game.py という名前の Python ファイルを作成します。
import random guesses_made = 0 name = input('Hello! What is your name?\n') number = random.randint(1, 20) print('Well, {0}, I am thinking of a number between 1 and 20.'.format(name)) while guesses_made < 6: guess = int(input('Take a guess: ')) guesses_made += 1 if guess < number: print('Your guess is too low.') if guess > number: print('Your guess is too high.') if guess == number: break if guess == number: print('Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made)) else: print('Nope. The number I was thinking of was {0}'.format(number))
pip3 install debugpy
コマンドを使用して、debugpy
パッケージを環境にインストールします。手記
トラブルシューティングに必要な場合に備えて、インストールされている debugpy のバージョンを記録することをお勧めします。 debugpy の一覧 には、使用可能なバージョンも表示されます。
他のコードの前に、guessing-game.py ファイルの先頭に次のコードを追加して、リモート デバッグを有効にします。 (厳密な要件ではありませんが、
listen
関数が呼び出される前に生成されたバックグラウンド スレッドをデバッグすることはできません)。import debugpy debugpy.listen(('0.0.0.0', 5678))
ファイルを保存し、プログラムを実行します。
python3 guessing-game.py
listen
関数の呼び出しはバックグラウンドで実行され、プログラムと対話するときに着信接続を待機します。 必要に応じて、デバッガーがアタッチされるまでプログラムをブロックするlisten
関数を呼び出した後、wait_for_client
関数を呼び出すことができます。
ヒント
listen
関数と wait_for_client
関数に加えて、debugpy にはヘルパー関数 breakpoint
も用意されています。 デバッガーがアタッチされている場合、この関数はプログラムによるブレークポイントとして機能します。 デバッガーがアタッチされている場合、別の関数 is_client_connected1
は True
を返します。 他の debugpy
関数を呼び出す前に、この結果を確認する必要はありません。
Python ツールからリモートでアタッチする
次の手順では、ブレークポイントを設定してリモート プロセスを停止する方法を示します。
ローカル コンピューター上にリモート ファイルのコピーを作成し、Visual Studio で開きます。 ファイルの場所は関係ありませんが、その名前はリモート コンピューター上のスクリプトの名前と一致する必要があります。
(省略可能)ローカル コンピューターで debugpy 用の IntelliSense を使用するには、debugpy パッケージを Python 環境にインストールします。
[デバッグ]>[プロセスにアタッチ] を選択します。
[プロセスにアタッチ] ダイアログで、[接続の種類] を [Python リモート (debugpy)] に設定します。
接続ターゲット フィールドに、コマンド
tcp://<ip_address>:5678
を入力します。tcp://
は、接続の種類を伝送制御プロトコル (TCP) として指定します。<ip_address>
はリモート コンピューターの IP アドレスであり、明示的なアドレスや myvm.cloudapp.netなどの名前を指定できます。:5678
は、リモート デバッグポート番号です。
を入力 選択して、そのコンピューターで使用可能な debugpy プロセスの一覧を設定します。
このリストを更新した後、リモートコンピューターで別のプログラムを起動した場合は、[更新] ボタンを [ 選択] します。
デバッグするプロセスを選択し、「アタッチ 」を選択するか、プロセスをダブルクリックします。
スクリプトがリモート コンピューターで実行され続けている間、Visual Studio はデバッグ モードに切り替わり、通常のすべての デバッグ 機能が提供されます。
if guess < number:
行にブレークポイントを設定し、リモート コンピューターに切り替えて、別の推測を入力できます。 ローカル コンピューター上の Visual Studio がブレークポイントで停止し、ローカル変数が表示されます。デバッグを停止すると、Visual Studio はプログラムからデタッチします。 プログラムはリモート コンピューターで引き続き実行されます。 debugpy はデバッガーをアタッチするために待機し続けるので、いつでもプロセスに再アタッチすることができます。
接続のトラブルシューティング
接続に関する問題のトラブルシューティングに役立つ次の点を確認します。
[接続の種類] には必ず [Python リモート (debugpy)] を選択してください。
[接続先] のシークレットがリモート コードのシークレットと完全に一致することを確認します。
接続ターゲットの IP アドレス リモート コンピューターの IP アドレスと一致することを確認します。
リモート コンピューターのリモート デバッグ ポートが開き、接続ターゲットにポート サフィックス (
:5678
など) が含まれていることを確認します。別のポートを使用するには、
debugpy.listen((host, port))
のように、listen
関数の呼び出しでポート番号を指定します。 この場合は、ファイアウォールで特定のポートを開いてください。リモート コンピューターにインストールされている debugpy バージョン (
pip3 list
コマンドによって返される) が Visual Studio Python Tools (PTVS) のバージョンと一致したことを確認します。次の表に、有効なバージョン ペアを示します。 必要に応じて、リモート コンピューターの debugpy のバージョンを更新します。
Visual Studio Python ツール debugpy 2019 16.6 1.0.0b5 1.0.0b5 2019 16.5 1.0.0b1 1.0.0b1
手記
Visual Studio 2019 バージョン 16.0-16.4 は、debugpy ではなく ptvsd を利用しました。 これらのバージョンに対するこのチュートリアルのプロセスは似ていますが、関数名は異なります。 Visual Studio 2019 バージョン 16.5 では debugpy が使用されますが、関数名は ptvsd の関数名と同じでした。 listen
の代わりに、enable_attach
を使用します。 wait_for_client
の代わりに、wait_for_attach
を使用します。 breakpoint
の代わりに、break_into_debugger
を使用します。
レガシ デバッグに ptvsd 3.x を使用する
ptvsd 3.x レガシ デバッガーは、Visual Studio 2017 バージョン 15.7 以前の既定です。
Visual Studio の構成によっては、リモート デバッグに ptvsd 3.x を使用する必要がある場合があります。
- Python 2.6、3.1 から 3.4、または IronPython を使用した Visual Studio 2017 バージョン 15.7 以前
- Python 2.6、3.1 から 3.4、または IronPython を使用した Visual Studio 2019 バージョン 16.5 以降
- 4.x の初期バージョン
構成で古いバージョンのシナリオが実装されている場合、Visual Studio にエラーが表示 、デバッガーはこの Python 環境をサポートしていません。
リモート デバッグのセットアップ
ptvsd 3.x を使用してリモート デバッグを準備するには、次の手順を実行します。
実行中のスクリプトへのアクセスを制限するために使用するシークレットを設定します。
ptvsd 3.x では、
enable_attach
関数では、最初の引数として "secret" を渡す必要があります。- リモート デバッガーをアタッチするときに、
enable_attach(secret="<secret>")
コマンドを使用してシークレットを入力します。
enable_attach(secret=None)
コマンドを使用して誰でも接続できますが、このオプションはお勧めしません。- リモート デバッガーをアタッチするときに、
tcp://<secret>@<ip_address>:5678
形式で接続ターゲット URL を作成します。tcp://
接続の種類を TCP として指定します。<secret>
は、Python コードでenable_attach
関数と共に渡される文字列です。<ip_address>
はリモート コンピューターの IP アドレスであり、明示的なアドレスや myvm.cloudapp.netなどの名前を指定できます。:5678
は、リモート デバッグポート番号です。
TCPS プロトコルを使用したセキュリティで保護された接続
既定では、ptvsd 3.x リモート デバッグ サーバーへの接続はシークレットによってのみ保護され、すべてのデータはプレーン テキストで渡されます。 より安全な接続を実現するために、ptvsd 3.x では、TCP プロトコルのセキュリティで保護された形式を使用するか、TCPS をして SSL をサポートしています。
TCPS プロトコルを使用するように ptvsd 3.x を構成するには、次の手順に従います。
リモート コンピューターで、
openssl
コマンドを使用して、キーと自己署名証明書用の個別のファイルを生成します。openssl req -new -x509 -days 365 -nodes -out cert.cer -keyout cert.key
openssl
プロンプトで、共通名の接続に使用するホスト名または IP アドレスを入力します。
詳細については、Python
ssl
モジュールのドキュメントで 自己署名証明書の を参照してください。 Python ドキュメントで説明されているコマンドでは、結合されたファイルが 1 つだけ生成されることに注意してください。コードで、ファイル名を値として使用して、
certfile
引数とkeyfile
引数を含むようにenable_attach
関数の呼び出しを変更します。 これらの引数は、標準のssl.wrap_socket
Python 関数の場合と同じ意味を持ちます。ptvsd.enable_attach(secret='my_secret', certfile='cert.cer', keyfile='cert.key')
ローカル コンピューターのコード ファイルでも同じ変更を行うことができます。 このコードは実際には実行されないため、厳密には必要ありません。
デバッグの準備ができたら、リモート コンピューターで Python プログラムを再起動します。
Visual Studio を使用して Windows コンピューターの信頼されたルート CA に証明書を追加して、チャネルをセキュリティで保護します。
リモート コンピューターからローカル コンピューターに証明書ファイルをコピーします。
[コントロール パネル] 開き、[ Windows ツール]>[コンピューター証明書の管理] に移動します。
certlm [証明書 - ローカル コンピューター] ダイアログで、[信頼されたルート証明機関] ノードを展開し、[証明書]を右クリックして[すべてのタスク]>[インポート] を選択します。
リモート コンピューターからコピーした .cer ファイルを参照して選択します。
ダイアログ プロンプトに進み、インポート プロセスを完了します。
「Python Toolsからリモートでアタッチする」で前述したように、Visual Studio でアタッチ プロセスを繰り返します。
この例では、接続ターゲット (または 修飾子) のプロトコルとして
tcps://
を定義します。
接続の問題に対処する
接続の試行中に、Visual Studio で問題が発生する可能性があります。 次のシナリオを確認し、必要に応じて適切なアクションを実行します。
VISUAL Studio では、SSL 経由で接続するときの潜在的な証明書の問題に関する警告が表示されます。
アクション: メッセージを無視して続行できます。
注意
チャネルは引き続き傍受に対して暗号化されていますが、中間者攻撃に対して開かれている可能性があることに注意してください。
Visual Studio では、リモート証明書が信頼されていない 警告が表示されます。
問題の: 証明書が信頼されたルート CA に正しく追加されていません。
アクション: Windows コンピューター の信頼されたルート CA に証明書を追加手順を再確認し、もう一度接続を試します。
Visual Studio では、リモート証明書名がホスト名 警告と一致しない が表示されます。
問題の: 証明書の 共通名 に適切なホスト名または IP アドレスが指定されていません。
アクション: TCPS を使用して接続をセキュリティで保護するの手順を再確認します。 証明書を作成するときは、必ず正しい 共通名 を使用し、接続を再試行してください。