Debugging ASP.NET Core app running in Kubernetes Minikube and in the cloud from Visual Studio 2017 on Windows

Pavel Agarkov
4 min readOct 1, 2017

If you want to use VSCode here is another tutorial for you.

This article is outdated. Please read the new one for Visual Studio 2019

Minikube allows you to run Kubernetes mini-cluster right on your Windows machine. But what about debugging?

Actually debugging ASP.NET Core application running in Kubernetes Minikube is not that different from debugging the app running inside any other container solution (Docker, OpenShift, Mesos, etc) or even directly on Linux and finally in the cloud.

The key point here is a debugger. You need two pieces of puzzle to make it work: MIEngine on the Visual Studio side and CLRDBG (now renamed to vsdbg) on the Linux side. These two pieces should be connected over SSH. Any tool that can establish SSH connection from Windows directly inside running container will do the trick.

When running inside Minikube you can use either docker exec or kubectl exec. In this tutorial we are going to use kubectl.

Ok. Let’s get it started. Firs of all make sure that you have published your app in Debug mode! I prefer to use a new Docker feature multi-stage build for building my images so I would write something like this in the end of a build stage in Dockerfile:

RUN dotnet publish -c Debug -o ./results

To push images to Minikube I do use local container regestry as described here. But you can do it as you usually do.

When you have your container up and running we can start hacking to it. I will use Powershell for that purpose but the same can be easily rewritten in any other terminal language. You can follow tutorial step by step and execute commands in your terminal one by one checking var’s values with echo command when necessary.

In your *.yml file you should have a selector described something like this:

selector:
matchLabels:
app: mywebapp

Grab it and use to define a $Selector var in your Powershell terminal:

$Selector = 'app=mywebapp'

You need to find a pod where your containerized application is running by its selector:

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

Assuming that you have only one container on the pod now you can execute commands on that container. By default container does not have vsdbg installed so go ahead and install it:

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;

Next you need to find PID of your app inside of the container:

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

Normally it is equal to 1 but it is better to make less assumptions.
That’s it. Now you can start a debugger:

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

When you refresh your app in the browser you would see something like this in the terminal:

That’s just like what you normally see when running your app from Visual Studio.

Don’t forget to execute the following commands before you close the window otherwise your app will stuck forever:

-target-detach
-gdb-exit

Let’s put everything together, create reusable script and save it somewhere near to the roots since you can use it with all your ASP.NET Core projects:

Now you can execute this script like this when terminal is running from the script folder:

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

But aren’t we supposed to be debugging from Visual Studio? Yes! Let’s go further and launch our terminal process from Visual Studio MIEngine.

Open your project in Visual Studio. Add new XML file with the following content and name it kubedbg.xml:

In -File parameter you need to specify absolute path to the script file we created before. Then press Ctrl+Alt+A to open Command Window and run the following command:

Debug.MIDebugLaunch /Executable:dotnet /OptionsFile:absolute_path_to_kubedbg_xml

This command will start debugging process inside Visual Studio with all standard benefits you would expect. But don’t stop debugging any other way than by pressing Detach All from Debug menu!

Although this command is not very convenient to write all the time. Luckily in Visual Studio you can specify aliases for commands with parameters. Eventually you would need new kubedbg.xml file for each project. With this in mind go ahead and create your first alias by typing the following command in Command Window:

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

After that you can start debugging just by executing kubedbg.mywebapp in Command Window. Even better you can run the same command from the Find toolbar combobox but with prefix: >kubedbg.mywebapp. That’s not difficult since there is a text completion too. You can read more about command aliases here.

Happy debugging!

PS: As a bonus absolutely the same way you can debug your app even when running inside public cloud. When kubectl is assigned to a cluster in the public cloud it just works with the same script and making less assumptions payed back since inside real cluster process ID is not equal to 1

--

--