銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Visual Studio Code からdocker 上で走るASP.NET Core アプリにリモートデバッグする

NOTES: clrdbgはvsdbgに置き換えられました。次の記事を参照してください。

tech.tanaka733.net

Visual Studio Code Advent Calendarの18日目です。

qiita.com

今回の記事は先日のこの記事のVisual Studio Code版になります。

tech.tanaka733.net

リモートデバッグでつなぐ先には、同様にMIEngineをセットアップしておき、ほぼ同じ仕組みで接続し、接続元がVisual Studio Codeになるところだけが異なります。また、Visual Studio Codeが動いているOSはWindowsだけでなくLinuxでも動きます。Macも動くはずですが確認はしていません。

前提条件

これも同じになります。

  • docker exec コマンドなどでVS Codeを動かしているマシンからリモートでコンテナ上のコマンドを実行できる
  • docker上で動いているASP.NET Core のバイナリはデバッグビルドである

今回もOpenShift Container Platform 上でテストしています。

手順

前提条件を満たしたdockerが動ている前提からスタートします。ビルドしたコードをgit cloneなどで持って来てもいいですが、OpenShiftで動ている場合、oc rsyncコマンドでソースコード一式をコンテナとローカルのファイルを同期できます。これをVisual Studioの時に紹介しなかったのは、Windowsだとrsyncが使えないとか、パス長制限にひっかかるといった理由でうまくできないことがおおいからです…

$ POD_NAME=<pod_name>
$oc rsync $POD_NAME:. .

プロジェクトをVS Codeで開くとアセットのダウンロードとNuGet restoreの確認を聞かれますが、リモートデバッグでは必須ではないのでどちらもお好きな方で。

f:id:tanaka733:20161212134856p:plain

docker内にclrdbgをインストールします。ここの手順も同じです。

$ oc exec $POD_NAME -- curl -sSL https://raw.githubusercontent.com/Microsoft/MIEngine/getclrdbg-release/scripts/GetClrDbg.sh -o GetClrDbg.sh
$ oc exec $POD_NAME -- bash ./GetClrDbg.sh latest ./clrdbg
Info: Using clrdbg version '15.0.25904-preview-3404276'
Info: Creating install directory
Info: Determinig Runtime ID
Info: Using Runtime ID 'rhel.7.2-x64'
Info: Generating project.json
Info: Generating NuGet.config
Info: Executing dotnet restore
Info: Executing dotnet publish
Successfully installed clrdbg at './clrdbg'

同様に、プロセスにアタッチするので、コンテナ上で動いているASP.NET Core のPIDを確認します。OpenShiftの場合はこんな結果になりますが、PIDは62になります。

$ oc exec $POD_NAME -- ps aux 
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
default       1  0.5  0.4 3048552 37016 ?       SLsl 22:08   0:05 dotnet run
default      62  1.0  1.9 12134016 153332 ?     SLl  22:08   0:09 /opt/rh/rh-dotnetcore10/root/usr/lib64/dotnetcore/dotnet exec --additionalprobingpath /opt/app-root/src/.nuget/packages /opt/app-root/src/bin/Debug/netcoreapp1.0/src.dll
default     381  0.0  0.0  13352  1868 ?        Ss+  22:16   0:00 /bin/sh
default     676  0.0  0.0  48996  1692 ?        Rs   22:23   0:00 ps aux

ここからの設定ファイルの書式とデバッグのやり方が違ってきます。プロジェクトのルート直下に.vscode/launch.jsonというファイルを作成し、次のように記述します。既に存在している場合は、configurations要素の中に追加してください。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Docker Remote Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "<PID>",
            "pipeTransport": {
                "pipeProgram": "oc",
                "pipeArgs": [ "exec", "-it", "<POD_NAME>", "--"],
                "debuggerPath": "/opt/app-root/src/clrdbg/clrdbg",
                "pipeCwd": "${workspaceRoot}"
            },
            "sourceFileMap": {
                "/opt/app-root/src": "${workspaceRoot}"
            }
        }
    ]
}

docker コマンドで接続する場合は--が不要です。この当たりはVisual Studio Codeの時と同じです。

        "pipeProgram": "docker",
        "pipeArgs": [ "exec", "-it", "<container_name>"],

あとは、Visual Studio Codeのデバッグメニューに追加されるので、追加した名前を選択してデバッグ実行すると、リモートデバッグが開始されます。

f:id:tanaka733:20161212134905p:plain

Visual Studioの時と同様、コンテナ名とかPIDとかの書き換えが面倒なのでその辺りを自動化できるプラグインでも作れるといい感じに使えそうです。