将 Visual Studio 调试器与在 Kubernetes 中运行的 ASP.NET Core Web 应用程序一起使用?

Tho*_*sen 12 c# visual-studio visual-studio-debugging kubernetes

我们的团队希望能够针对已部署到我们内部 Kubernetes 集群的 ASP.NET 应用程序实例运行 Visual Studio 调试器。我需要弄清楚如何完成拼图,但我对 Visual Studio 2019 不是很熟悉。

  • Docker 映像使用官方 .NET Core 映像编译,并且 /vsdbg 填充了最新版本(不支持 --attach)。
  • Visual Studio 适用于我的 Docker 桌面。
  • Kubectl 已正确配置。我可以使用 Docker Desktop 附带的 kubernetes 集群或我们内部的 kubernetes 集群进行测试。
  • Azure 目前不是一个选项。我从文档中了解到,这是微软更喜欢我做的。

我应该如何配置 Visual Studio 才能做到这一点?

dev*_*ass 9

好的。让我们开始吧。首先确保您已在调试模式下发布您的应用程序!我更喜欢使用新的 Docker 功能多阶段构建来构建我的图像,所以我会在 Dockerfile 的构建阶段结束时编写如下内容:

RUN dotnet publish -c Debug -o ./results
Run Code Online (Sandbox Code Playgroud)

要将图像推送到 Minikube,我确实使用了此处所述的本地容器注册表。但是你可以像往常一样做。当你的容器启动并运行时,我们就可以开始攻击它了。为此,我将使用 Powershell,但同样可以轻松地用任何其他终端语言重写。您可以按照教程一步一步地在终端中执行命令,并在必要时使用 echo 命令检查 var 的值。在您的 *.yml 文件中,您应该有一个描述如下的选择器:

selector:
  matchLabels:
    app: mywebapp
Run Code Online (Sandbox Code Playgroud)

抓住它并使用它在你的 Powershell 终端中定义一个 $Selector var:

$Selector = 'app=mywebapp'
Run Code Online (Sandbox Code Playgroud)

您需要通过其选择器找到运行容器化应用程序的 pod:

$pod = kubectl get pods --selector=$Selector -o jsonpath='{.items[0].metadata.name}';
Run Code Online (Sandbox Code Playgroud)

假设您现在在 pod 上只有一个容器,您可以在该容器上执行命令。默认情况下,容器没有安装 vsdbg,所以继续安装它:

kubectl exec $pod -i -- apt-get update;
kubectl exec $pod -i -- apt-get install -y unzip;
kubectl exec $pod -i -- curl -sSL https://aka.ms/getvsdbgsh -o '/root/getvsdbg.sh';
kubectl exec $pod -i -- bash /root/getvsdbg.sh -v latest -l /vsdbg;
Run Code Online (Sandbox Code Playgroud)

接下来,您需要在容器内找到您的应用程序的 PID:

$prid = kubectl exec $pod -i -- pidof -s dotnet;
Run Code Online (Sandbox Code Playgroud)

通常它等于 1,但最好少做一些假设。就是这样。现在您可以启动调试器:

kubectl exec $pod -i -- /vsdbg/vsdbg --interpreter=mi --attach $prid;
Run Code Online (Sandbox Code Playgroud)

在关闭窗口之前不要忘记执行以下命令,否则您的应用程序将永远卡住:

-target-detach
-gdb-exit
Run Code Online (Sandbox Code Playgroud)

让我们把所有东西放在一起,创建一个可重用的脚本并将其保存在靠近根的地方,因为您可以将它用于所有 ASP.NET Core 项目:

param(
    # the selector from your yml file
    #  selector:
    #    matchLabels:
    #      app: myweb
    # -Selector app=myweb
    [Parameter(Mandatory=$true)][string]$Selector
)

Write-Host '1. searching pod by selector:' $Selector '...';
$pod = kubectl get pods --selector=$Selector -o jsonpath='{.items[0].metadata.name}';

Write-Host '2. installing updates ...';
kubectl exec $pod -i -- apt-get update;

Write-Host '3. installing unzip ...';
kubectl exec $pod -i -- apt-get install -y --no-install-recommends unzip;

Write-Host '4. downloading getvsdbgsh ...';
kubectl exec $pod -i -- curl -sSL https://aka.ms/getvsdbgsh -o '/root/getvsdbg.sh';

Write-Host '5. installing vsdbg ...';
kubectl exec $pod -i -- bash /root/getvsdbg.sh -v latest -l /vsdbg;

$cmd = 'dotnet';
Write-Host '6. seaching for' $cmd 'process PID in pod:' $pod '...';
$prid = kubectl exec $pod -i -- pidof -s $cmd;

Write-Host '7. attaching debugger to process with PID:' $pid 'in pod:' $pod '...';
kubectl exec $pod -i -- /vsdbg/vsdbg --interpreter=mi --attach $prid;
Run Code Online (Sandbox Code Playgroud)

现在,当终端从脚本文件夹运行时,您可以像这样执行此脚本:

powershell -ExecutionPolicy Bypass -File kubedbg.ps1 -Selector app=mywebapp
Run Code Online (Sandbox Code Playgroud)

但是我们不应该从 Visual Studio 进行调试吗?是的!让我们更进一步,从 Visual Studio MIEngine 启动我们的终端进程。在 Visual Studio 中打开您的项目。添加具有以下内容的新 XML 文件并将其命名为 kubedbg.xml:

RUN dotnet publish -c Debug -o ./results
Run Code Online (Sandbox Code Playgroud)

-File参数中,您需要指定我们之前创建的脚本文件的绝对路径。然后按 Ctrl+Alt+A 打开命令行窗口并运行以下命令: Debug.MIDebugLaunch /Executable:dotnet /OptionsFile:absolute_path_to_kubedbg_xml 此命令将在 Visual Studio 中启动调试过程,并具有您期望的所有标准优势。但是,除了从调试菜单中按全部分离之外,不要以任何其他方式停止调试!虽然这个命令一直写起来不是很方便。幸运的是,在 Visual Studio 中,您可以为带参数的命令指定别名。最终,您需要kubedbg.xml为每个项目创建一个新文件。考虑到这一点,通过在命令行窗口中键入以下命令来创建您的第一个别名:

alias kubedbg.mywebapp Debug.MIDebugLaunch /Executable:dotnet 
/OptionsFile:absolute_path_to_kubedbg.xml
Run Code Online (Sandbox Code Playgroud)

之后,您只需在命令行窗口中执行 kubedbg.mywebapp 即可开始调试。更好的是,您可以从“查找”工具栏组合框中运行相同的命令,但带有前缀:>kubedbg.mywebapp.这并不困难,因为也有文本完成。您可以在此处阅读有关命令别名的更多信息。调试愉快!PS:作为奖励,即使在公共云中运行时,您也可以以完全相同的方式调试应用程序。当 kubectl 被分配到公共​​云中的集群时,它只使用相同的脚本工作,并且由于内部真实的集群进程 ID 不等于 1,因此做出更少的假设回报

原作者:https : //medium.com/@pavel.agarkov/debugging-asp-net-core-app-running-in-kubernetes-minikube-from-visual-studio-2017-on-windows-6671ddc23d93