>> Hey. I'm Kyle from the Dotnet-Monitor Team
and today I'm really excited
to do a walkthrough of one of
Dotnet-Monitor's most common use cases,
running it as a sidecar in a Kubernetes cluster.
This video assumes you already have
some background knowledge of Dotnet-Monitor.
If this is your first time hearing about it,
I'd recommend checking out the link
getting started guide on how to
use Dotnet-Monitor and then coming back to this video.
Today we're going to talk a little bit about
the motivations behind why you might want to use
Dotnet-Monitor as part of
your Kubernetes cluster and then we're going to walk step by
step through everything you'll need to do in order to
try this out for yourself. Let's get started.
[MUSIC].
When it comes to running down the applications on Windows,
collecting and analyzing diagnostic artifacts
is pretty well documented.
However, we recognize that a lot of
customers moving to Linux and Kubernetes
might struggle to find parity with
diagnostics tools available for Dotnet.
In this video, we're going to dive into how
Dotnet-Monitor can help improve the observability,
collection, and egress of artifacts for Dotnet apps
running on Linux, specifically with Kubernetes.
For this tutorial, we're going to employ
something known as the Sidecar Pattern.
In this pattern, we'll have two containers in
the same pod or Dotnet app and Dotnet-Monitor.
As a brief refresher, in Kubernetes,
the pod is the smallest unit of scale that we work with,
and it can hold multiple containers that
all share that pod's resources.
The sidecar is another container that's
located alongside your Dotnet app in the same pod.
This means that the sidecar can attach to
the parent application and provide diagnostics
without requiring you to add diagnostics
tooling to your main apps container.
To better visualize what's going on here,
let's take a quick look at this diagram.
In this scenario, our sample user app provides a service to
the public Internet and
Dotnet-Monitor sits alongside the application,
providing diagnostics functionality in
a container that isn't publicly exposed.
This helps you keep your container small while benefiting
from the tools made available through Dotnet-Monitor.
It's time to deploy our cluster to production,
and actually your deployment strategy will vary
depending on your choice of Cloud provider and CLI.
For this particular scenario though,
I'll be using the Kubernetes command-line client with Azure.
We'll start out by logging into
our Azure Container Registry and
then we'll create a Kubernetes cluster.
We want to make sure that our context is set to our new cluster,
so we'll do that here.
Then we can use the following command to make
sure our context is set correctly.
Finally, we can verify that our nodes are up and running.
Fortunately for us, it looks like everything is good to go,
so we can start setting up our configuration.
The first step in getting this up and running will be creating
a YAML file for a simple two container configuration.
We're not going to go too in-depth
here with the YAML configuration,
but if you need a refresher,
you can follow the link in
the description for our tutorial that'll walk you
through deploying a multi-container group with a YAML file.
To make it easier for you to follow along,
there's a provided link to our sample manifest,
which is what I'll be using here.
I'm going to skim over some of this,
but I'll talk through a couple of the important points that you'll
need for using Dotnet-Monitor as a sidecar.
The first container in the group defines
our sample Internet-facing web application.
As you can see here, we've already published
our application's image and we're able
to reference it with its identifier.
This is where you'd insert the applications image.
But if you want to follow along with the demo when we
collect some artifacts later on this video,
you can use our image.
The second container, or our sidecar,
is where Dotnet-Monitor lives.
This would be completely separate from the application and it's
solely for helping to collect
diagnostics from the first container.
To give you a better feel for all the different ways
that you can configure Dotnet-Monitor,
we're going to use a combination of environment variables,
ConfigMaps, and a Settings.json file.
Ultimately, it's up to you how
you prefer to write configuration,
but they should give you an idea of some
of the different options that you have.
For more detailed information about
the different configuration sources Dotnet-Monitor supports,
we'll leave a link to our documentation.
Here we've said a few environment variables to enable
collection rules as well as
a corresponding environment variable on our test app.
We'll be relying on projected volumes to
access our configMaps and Secrets,
dotnet-monitor-egress, dotnet-monitor-triggers,
and apikey, and we'll set those up in a minute.
Finally, we`ll also be using
Dotnet-Monitor's recommended container limits,
which you can learn more about in our documentation.
Next, we need to add our ConfigMaps.
So that you don't need to write your own,
you can follow the link to access these files.
We're going to be creating two ConfigMaps;
dotnet-monitor-egress and dotnet-monitor-triggers.
For dotnet-monitor-egress, we'll be setting up
Azure egress using managed identity authentication.
We'll name our egress provider, monitorBlob,
and this is the name that we'll use to reference it later
when we want to send artifacts to Azure Blob Storage.
Note that this is only available in Dotnet-Monitor 6.2 and above.
For earlier versions of Dotnet-Monitor,
you can authenticate using your account key
as shown in our documentation.
Now, let's head into our Azure portal and go to
our storage account specifically looking at access control.
We're going to add a new role assignment for
our target applications agent pool
called Storage Blob Data Contributor.
This is going to enable us to send
our artifacts from Dotnet-Monitor to
our storage account without having to share
any secret information with Dotnet-Monitor.
Under members, I'm going to assign access to a managed identity,
and then after selecting my subscription and setting
my managed identity to be a user-assigned managed identity,
we can select our agent pool.
Finally, after we've finished our role assignment,
we can grab our client ID by going into our resource JSON view and
we're going to copy that into
our ConfigMap to link our app with the storage account.
We're also going to set up a local file system egress.
We'll name this monitorFile and we'll list
the path where we want our artifacts to be egressed.
Now, let's go ahead and add in our ConfigMap to Dotnet-Monitor.
We can use the following command to make sure that
Dotnet-Monitor pulls in
the egress configuration that we just drew.
Next, Let's also load in our settings.json file that
contains a simple collection rule using the following command.
We'll try out a simple collection rule scenario in a little bit to
help us check if we've configured everything correctly.
Finally, we need to set up authentication.
Though Dotnet-Monitor can be run without
authentication by using the no-auth flag,
you should only disable authentication once you have
evaluated and mitigated the security implications of doing so.
Let's run the generate key command to get
an API key that we can use for authentication.
[inaudible] our subject PublicKey and Bearer token.
We'll use that subject and
PublicKey to create a secret using kubectl,
but keep that bearer token handy because
we'll need it in just a little bit.
Once we've done that, we'll double check that everything worked
as expected using the following commands.
We should be able to see our ConfigMaps and secret year,
which, fortunately, we do.
We're almost ready to start collecting diagnostics,
but first we'll need to apply the manifest that we looked
at in the previous section so that it takes effect.
Give this a few seconds and then
if we check on the state of our pods,
if we've done everything correctly,
our pods should say that it's running, which it does.
We can check on Dotnet-Monitor's logs now and we'll get
a bunch of messages indicating
that Dotnet-Monitor is up and running,
as well as any warning messages that can help us
determine if we've made a mistake in our configuration.
Fortunately for us, everything here looks good,
and it also looks like our collection rules are up and running.
So now we can start using Dotnet-Monitor with our target app.
In order to control Dotnet-Monitor
locally while it's running in your cluster,
you'll need to port-forward traffic from
your host to your target cluster.
To do this, let's get the name
of the pod that we want to forward traffic
to using the same command that we just used a little bit ago.
Once you have your target pod name,
all we actually have to do is forward the traffic for
Dotnet-Monitor and our target app using the following command.
Now that we've started forwarding traffic from
our local network to the desired pod,
we can make API calls to get
diagnostics from Dotnet-Monitor about our app.
To see the full list of things that you can
do with the Dotnet-Monitor API,
take a look at our documentation.
But just to make sure that things are working as expected,
we can try out a few examples.
Let's check to see what processes Dotnet-Monitor finds.
Naturally, we should expect to see
our target application show up.
Here we can see its pid,
uid, and name,
which will be helpful if we end up having
multiple processes and we need to identify a specific one.
To make sure we can collect artifacts and
egress them locally into our Azure Blob Storage,
let's collect a gcdump on our process using
curl and set our Azure egress provider to monitorBlob,
which is what we named our Azure egress in configuration.
Give this a few seconds and then in Azure,
we can see that our gcdump has successfully shown up.
Now, let's change your request by setting
the egress provider to monitorFile,
which is what we named our local file egress in configuration.
To get to our artifact,
we'll exec into our monitor container using
the following command and then we'll
navigate to our egress directory.
As you can see, our gcdump is right where it's supposed to be,
so both of our egress providers are working as expected.
The last thing we want to do is make sure we can collect
artifacts automatically using collection rules.
For the purposes of this demo,
we'll be using a very simple rule in
order to verify that things are working as expected.
But you can take a look at our documentation for
more examples of what you can do with collection rules.
Our rules states that we should collect a dump if
our target application returns a status code in the 400s range.
This is something that we can easily trigger
ourselves to verify that it's working,
and we'll use curl to attempt to reach
an invalid page on our target application.
Now, if we head over to Azure,
we should see two artifacts,
our gcdump from earlier,
and the one our collection rule automatically collected just now.
At this point, we've covered all of the fundamentals for
getting Dotnet-Monitor up and running in Kubernetes,
which means that you should have all of
the building blocks you need to
help use Dotnet-Monitor in your own scenarios.
If you have any questions or feedback,
feel free to leave them in our survey
or to create an issue on our GitHub page.
For more information on how to use Dotnet-Monitor,
we'll continue adding tutorials to the linked playlist with
more scenarios and new features coming soon. Thanks for watching.