如何用Visual Studio 2017调试已运行的Docker Linux .NET Core容器及远程实例?
Visual Studio调试Docker中.NET Core应用的原理及手动调试步骤
一、Visual Studio 2017自动调试Docker容器的原理
其实VS在背后帮你做了一堆“保姆级”的自动化操作,才让调试这么顺畅:
- 自动构建带调试环境的镜像:它会把.NET Core专用的调试器
vsdbg打包进镜像,同时把项目的pdb调试符号文件也复制到容器里——没有这些东西,调试根本无从谈起。 - 自动配置容器启动参数:启动容器时,它会偷偷设置
ASPNETCORE_ENVIRONMENT=Development环境变量,还会把容器内的调试端口(默认是4022这类)映射到本地,同时自动启动vsdbg并处于等待连接的状态。 - 自动附加调试器:最后VS会直接连接到容器里的
vsdbg进程,帮你完成断点设置、进程附加这些操作,全程不用你手动敲命令。
二、手动调试已运行的Docker Linux .NET Core容器(本地)
如果是你自己用docker run启动的Release镜像,默认是不带调试组件和符号的,所以咱们得手动补上这些步骤,才能让VS连上调试:
步骤1:给容器装上vsdbg调试器
先进入运行中的容器,手动安装调试器:
# 替换成你的容器ID或者名称,进入容器的bash环境 docker exec -it <container-id/name> bash # 一键安装最新版vsdbg(适配Linux x64,使用微软官方安装脚本) curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l /vsdbg
步骤2:把调试符号文件复制到容器里
本地项目的pdb文件是调试的关键,得把它复制到容器内和应用程序集同一个目录(比如你的应用在容器里的路径是/app,就复制到这里):
# 假设本地pdb在bin/Release/netcoreapp3.1/目录下,容器内路径是/app docker cp ./bin/Release/netcoreapp3.1/YourApp.pdb <container-id/name>:/app/
步骤3:让容器里的vsdbg等待调试连接
在容器的bash里执行下面的命令,vsdbg就会监听默认端口4022,等着VS来连接:
/vsdbg/vsdbg --interpreter=vscode
步骤4:在VS 2017里附加到容器进程
两种方式都可以:
- Docker容器直接附加:
- 打开VS 2017,点击顶部菜单 调试 > 附加到进程
- 连接类型选 Docker (Linux Container),连接目标选你的本地Docker主机
- 列表里找到你的.NET Core进程(比如
dotnet YourApp.dll),选中后点击“附加”就能调试了
- 远程调试方式附加:
- 如果上面的方式看不到进程,就选连接类型为 远程(无身份验证)
- 连接目标填
localhost:4022(如果之前改了端口就填对应端口) - 选中目标进程,点击附加即可
三、调试远程Linux机器上运行的Docker容器
如果容器跑在远程Linux服务器上,核心思路是把远程容器的调试端口转发到本地,或者让VS直接连接远程Docker主机,具体步骤如下:
步骤1:打通本地和远程的调试通道(推荐用SSH隧道,更安全)
直接开放Docker远程端口不安全,所以优先用SSH隧道把远程容器的调试端口映射到本地:
# 替换成你的远程Linux用户名、服务器IP,这里把远程的4022端口转发到本地4022端口 ssh -L 4022:localhost:4022 <remote-user>@<remote-ip>
这条命令执行后,本地访问localhost:4022就相当于访问远程机器的4022端口了。
步骤2:给远程容器装调试器、传pdb文件
和本地容器一样,得先给远程容器装上vsdbg,并把pdb传进去:
# 远程执行容器内的安装命令(替换远程用户、IP、容器ID) ssh <remote-user>@<remote-ip> "docker exec -it <container-id> bash -c 'curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l /vsdbg'" # 把本地pdb复制到远程容器里(如果之前配置了远程Docker连接,也可以直接用docker cp) docker -H tcp://<remote-ip>:2375 cp ./bin/Release/netcoreapp3.1/YourApp.pdb <container-id>:/app/
步骤3:启动远程容器的vsdbg等待连接
在远程容器内启动调试器:
ssh <remote-user>@<remote-ip> "docker exec -it <container-id> /vsdbg/vsdbg --interpreter=vscode"
步骤4:VS 2017附加调试
如果用了SSH隧道,直接按照本地调试的第二种方式,连接localhost:4022即可;如果是配置了远程Docker连接,就在“附加到进程”里选连接类型为Docker (Linux Container),连接目标填tcp://<remote-ip>:2375,然后选中对应的进程附加。
一些要注意的坑
- Release版本的代码默认会有编译优化,可能导致调试时变量看不到、断点不命中的情况,如果要调试,建议要么用Debug镜像,要么在Release构建时关闭优化(在项目文件里加
<Optimize>false</Optimize>)。 vsdbg的版本最好和你的.NET Core版本匹配,不然可能出现兼容性问题。- 生产环境绝对不要开放Docker的远程端口,用SSH隧道是更安全的选择。
内容的提问来源于stack exchange,提问作者ankush




