Usar o depurador do Visual Studio com o aplicativo Web ASP.NET Core em execução no Kubernetes?

9

Nossa equipe deseja executar o depurador do Visual Studio em instâncias implantadas do aplicativo ASP.NET em nosso cluster Kubernetes interno. Preciso descobrir como terminar o quebra-cabeça, mas não estou muito familiarizado com o Visual Studio 2019.

  • A imagem do Docker é compilada com as imagens oficiais do .NET Core e possui / vsdbg preenchido com a versão mais recente (que não suporta --attach).
  • O Visual Studio funciona com o meu Docker Desktop.
  • O Kubectl está configurado corretamente. Posso usar o cluster kubernetes incluído no Docker Desktop ou nosso cluster interno kubernetes para teste.
  • Atualmente, o Azure não é uma opção. Entendo pela documentação que é isso que a Microsoft prefere que eu faça.

Como devo configurar o Visual Studio para poder fazer isso?

Thorbjørn Ravn Andersen
fonte
Oi. Quero perguntar por que você disse no primeiro item da lista como "... tem / vsdbg preenchido com a versão mais recente (que não suporta --attach)." ? Se você tem vsdbg; deve suportar anexar.
Safak Ulusoy
@SafakUlusoy O vsdbg que eu instalei não suportava o sinalizador --attach.
Thorbjørn Ravn Andersen 08/04

Respostas:

4

Está bem. Vamos começar. Antes de tudo, verifique se você publicou seu aplicativo no modo de Depuração! Prefiro usar uma nova compilação de vários estágios do Docker para criar minhas imagens, para escrever algo assim no final de um estágio de compilação no Dockerfile:

RUN dotnet publish -c Debug -o ./results

Para enviar imagens ao Minikube, eu uso o registro de contêiner local, conforme descrito aqui. Mas você pode fazê-lo como costuma fazer. Quando você tiver seu contêiner em funcionamento, podemos começar a invadir ele. Usarei o Powershell para esse fim, mas o mesmo pode ser facilmente reescrito em qualquer outro idioma do terminal. Você pode seguir o tutorial passo a passo e executar comandos no seu terminal, um por um, verificando os valores de var com o comando echo quando necessário. No seu arquivo * .yml, você deve ter um seletor descrito algo como isto:

selector:
  matchLabels:
    app: mywebapp

Agarre-o e use-o para definir um $ Selector var no seu terminal Powershell:

$Selector = 'app=mywebapp'

Você precisa encontrar um pod em que seu aplicativo em contêiner esteja em execução pelo seletor:

$pod = kubectl get pods --selector=$Selector -o jsonpath='{.items[0].metadata.name}';

Supondo que você tenha apenas um contêiner no pod agora você pode executar comandos nesse contêiner. Por padrão, o contêiner não possui o vsdbg instalado, então vá em frente e instale-o:

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;

Em seguida, você precisa encontrar o PID do seu aplicativo dentro do contêiner:

$prid = kubectl exec $pod -i -- pidof -s dotnet;

Normalmente é igual a 1, mas é melhor fazer menos suposições. É isso aí. Agora você pode iniciar um depurador:

kubectl exec $pod -i -- /vsdbg/vsdbg --interpreter=mi --attach $prid;

Não se esqueça de executar os seguintes comandos antes de fechar a janela, caso contrário, seu aplicativo ficará bloqueado para sempre:

-target-detach
-gdb-exit

Vamos juntar tudo, criar um script reutilizável e salvá-lo em algum lugar próximo das raízes, pois você pode usá-lo com todos os seus projetos do 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;

Agora você pode executar este script assim quando o terminal estiver sendo executado a partir da pasta de scripts:

powershell -ExecutionPolicy Bypass -File kubedbg.ps1 -Selector app=mywebapp

Mas não devemos estar depurando do Visual Studio? Sim! Vamos além e lançar nosso processo de terminal no Visual Studio MIEngine. Abra seu projeto no Visual Studio. Adicione um novo arquivo XML com o seguinte conteúdo e denomine-kubedbg.xml:


<PipeLaunchOptions xmlns="http://schemas.microsoft.com/vstudio/MDDDebuggerOptions/2014"
    PipePath="powershell" TargetArchitecture="x64" MIMode="clrdbg"
    PipeArguments="
      -ExecutionPolicy Bypass
      -File C:\kube\kubedbg.ps1
      -Selector app=mywebapp">
  <LaunchCompleteCommand>None</LaunchCompleteCommand>
</PipeLaunchOptions>

No -Fileparâmetro, você precisa especificar o caminho absoluto para o arquivo de script que criamos anteriormente. Em seguida, pressione Ctrl + Alt + A para abrir a Janela de Comando e execute o seguinte comando: Debug.MIDebugLaunch /Executable:dotnet /OptionsFile:absolute_path_to_kubedbg_xml Este comando iniciará o processo de depuração no Visual Studio com todos os benefícios padrão que você esperaria. Mas não pare de depurar de outra maneira senão pressionando Desanexar tudo no menu Debug! Embora este comando não seja muito conveniente para escrever o tempo todo. Felizmente, no Visual Studio, você pode especificar aliases para comandos com parâmetros. Eventualmente, você precisaria de um novo kubedbg.xmlarquivo para cada projeto. Com isso em mente, vá em frente e crie seu primeiro alias digitando o seguinte comando na Janela de Comando:

alias kubedbg.mywebapp Debug.MIDebugLaunch /Executable:dotnet 
/OptionsFile:absolute_path_to_kubedbg.xml

Depois disso, você pode começar a depurar executando kubedbg.mywebapp na Janela de Comando. Ainda melhor, você pode executar o mesmo comando na caixa de combinação Localizar da barra de ferramentas, mas com prefixo: >kubedbg.mywebapp.isso não é difícil, pois também há um preenchimento de texto. Você pode ler mais sobre aliases de comando aqui. Feliz depuração! PS: como um bônus absolutamente da mesma maneira que você pode depurar seu aplicativo mesmo quando executado em uma nuvem pública. Quando o kubectl é atribuído a um cluster na nuvem pública, ele trabalha com o mesmo script e faz menos suposições pagas, uma vez que o ID do processo real do cluster não é igual a 1

devcass
fonte
Obrigado por uma resposta muito completa. Vejo que o --attachsinalizador é usado no comando kubectl usado para anexar o depurador, o que me preocupa um pouco. Você pode confirmar que isso funcionou para você ao preparar esta resposta?
Thorbjørn Ravn Andersen
Sim, realmente funcionou para mim! Mas não sei por que não funciona para você.
devcass 14/04
Obrigado por confirmar que está funcionando para você. Vou tentar isso amanhã.
Thorbjørn Ravn Andersen 14/04
De nada! Boa sorte! Estou aqui se você precisar de algo
devcass 14/04