

Collecting memory dumps for .NET Core on Kubernetes
source link: https://cezarypiatek.github.io/post/memory-dump-on-kubernetes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Collecting memory dumps for .NET Core on Kubernetes

In the world of Kubernetes and microservices, diagnosing and debugging issues can be a challenging task. One powerful tool in your troubleshooting arsenal is memory dump analysis. Memory dumps capture the state of an application’s memory at a particular point in time, providing insights into potential issues, bottlenecks, and crashes. In this blog post, I’ll walk you through the process of collecting a memory dump from a .NET Core application running on Kubernetes.
Step 1: Getting Started 🔗︎
If you don’t already have it, you’ll need to install kubectl
, the command-line tool for interacting with Kubernetes clusters. You can follow the installation instructions provided on the official Kubernetes documentation or use the winget
command if you’re on Windows:
winget install Kubernetes.kubectl
Having the kubectl tool installed, begin by identifying the relevant pods using a label selector. For instance, you can list the pods with the label app.kubernetes.io/instance=YOUR_APP_NAME
in the YOUR_NAMESPACE_NAME
namespace:
kubectl get pods --selector=app.kubernetes.io/instance=YOUR_APP_NAME --namespace YOUR_NAMESPACE_NAME -o=name --kubeconfig "path_to_kubeconfig.yaml"
The --kubeconfig
parameter is used to specify the path to the configuration file for authenticating and interacting with a Kubernetes cluster. This file contains information about the cluster’s API server, authentication credentials, and context. You can obtain the kubeconfig file from your Kubernetes administrator or generate it yourself if you have access to the cluster. If you are using Rancher
, follow this guideline to obtain your kubeconfig
file.
Step 2: Accessing the Pod 🔗︎
To access the pod and execute commands within it, you can use the kubectl exec
command. This example assumes you’re accessing the pod with the name YOUR_POD_NAME:
kubectl exec -it "pod/YOUR_POD_NAME" --kubeconfig "path_to_kubeconfig.yaml" --namespace YOUR_NAMESPACE_NAME -- sh
You will need to download dotnet-dump
. However, you might have limited permission regarding saving data to disk in container so it’s good to execute the following steps from /tmp
directory. Navigate to the /tmp directory within the pod:
cd /tmp
Step 3: Creating a Memory Dump 🔗︎
Now, let’s proceed to collect the memory dump for the .NET Core application. Start by downloading the dotnet-dump tool:
curl -L -o dotnet-dump https://aka.ms/dotnet-dump/linux-x64
Give the necessary permissions to the downloaded tool:
chmod 777 ./dotnet-dump
Specify an extraction directory for the tool:
export DOTNET_BUNDLE_EXTRACT_BASE_DIR="/tmp/bundle_extract"
Now, initiate the memory dump collection. Replace 1 with the appropriate process ID of your .NET Core application:
./dotnet-dump collect -p 1
The collected memory dump will be saved as core_ in the /tmp directory.
Step 4: Archiving the Memory Dump 🔗︎
Once the memory dump is generated, you can compress it for easier transfer and analysis:
gzip core_<timestamp>
Step 5: Downloading the Memory Dump 🔗︎
Now that the memory dump is ready, you can copy it from the pod to your local machine using the kubectl cp command.
First you need to exit the pod console:
exit
Being back on your workstation console, execute the following command to download the memory file to your machine:
kubectl cp "YOUR_POD_NAME:/tmp/core_<timestamp>.gz" ./core_<timestamp>.gz --kubeconfig "path_to_kubeconfig.yaml" --namespace YOUR_NAMESPACE_NAME
Step 5: Unpacking the Memory Dump 🔗︎
Now you need to unpack the memory dump file. You can do that with Total Commander
or using the PowerShell script that I found here Unzip GZ files using Powershell
Now you are ready to start a memory analysis. You can do that with VisualStudio, WindDBG or with dotMemory.
Everything Everywhere All at Once 🔗︎
All the steps described above can be compiled into a simple PowerShell
script to bring the whole process to a single command execution.
param (
[Parameter(Mandatory=$true)][string] $PodName,
[Parameter(Mandatory=$true)][string] $Namespace,
[Parameter(Mandatory=$true)][string] $KubeconfigFile,
[Parameter(Mandatory=$true)][string] $OutputDirectory
)
Write-Host "Preparing dump file"
$linuxDumpScript = @"
cd /tmp && \
curl -L -o dotnet-dump https://aka.ms/dotnet-dump/linux-x64 && \
chmod 777 ./dotnet-dump && \
export DOTNET_BUNDLE_EXTRACT_BASE_DIR='/tmp/bundle_extract' && \
./dotnet-dump collect -p 1
"@ -replace "`r`n","`n"
$dumpLog = kubectl exec -it "pod/$PodName" --kubeconfig $KubeconfigFile --namespace "$Namespace" -- sh -c $linuxDumpScript.Trim()
Write-Host $dumpLog
$pattern = "Writing full to (.*?)Complete"
$matches = [Regex]::Matches($dumpLog, $pattern)
if ($matches.Count -eq 0) {
Write-Error "Cannot find dump file name"
return
}
$dumpFile = $matches[0].Groups[1].Value.Trim()
Write-Host "Dump file $($matches[0].Groups[1].Value)"
Write-Host "Packing dump file"
kubectl exec -it "pod/$PodName" --kubeconfig $KubeconfigFile --namespace "$Namespace" -- sh -c "gzip $dumpFile" | Out-Host
$fileName = [System.IO.Path]::GetFileName($dumpFile)
$archiveFileName = "$fileName.gz"
if ([string]::IsNullOrWhiteSpace($OutputDirectory)) {
$OutputDirectory = "."
}
# Relative path is required by `kubectl cp`
$directoryRelativePath = Resolve-Path -Relative $OutputDirectory
$outputFile = Join-Path $directoryRelativePath $archiveFileName
Write-Host "Downloading dump file to $outputFile"
kubectl cp "$PodName`:$dumpFile`.gz" $outputFile --kubeconfig $KubeconfigFile --namespace $Namespace
function DeGZip-File {
param (
$infile,
$outfile = ($infile -replace '\.gz$', '')
)
$input = [System.IO.File]::OpenRead($inFile)
$output = [System.IO.File]::Create($outFile)
$gzipStream = [System.IO.Compression.GzipStream]::new($input, [System.IO.Compression.CompressionMode]::Decompress)
$buffer = [byte[]]::new(1024)
while ($true) {
$read = $gzipStream.Read($buffer, 0, 1024)
if ($read -le 0) { break }
$output.Write($buffer, 0, $read)
}
$gzipStream.Close()
$output.Close()
$input.Close()
}
Write-Host "Unpacking dump file"
DeGZip-File (Join-Path $OutputDirectory $archiveFileName) (Join-Path $OutputDirectory $fileName)
Save the script as MemoryDump.ps1
file and enjoy creating memory dumps with this single line:
./MemoryDump.ps1 -PodName 'YOUR_POD_NAME' -Namespace 'YOUR_NAMESPACE' -KubeconfigFile './YOUR_KUBECONFIG.yaml'
Conclusion 🔗︎
Collecting memory dumps from applications running on Kubernetes can provide valuable insights into their state during critical moments. Armed with the information from memory dumps, you can more effectively troubleshoot and address issues within your .NET Core applications. Remember that memory dump analysis requires familiarity with debugging tools and techniques, but it’s a skill that can significantly enhance your ability to maintain and improve your applications' performance and reliability.
Recommend
-
7
Exam Dumps: Protect Your Future by Becoming Certified Specialist After Acing Oracle 1Z0-062 Exam
-
27
Simple In-Memory Caching in .Net Core with IMemoryCache 2020-01-15asp.net core 6 min readCaching is the process of storing the data that’s frequently used so that data...
-
60
Posted Feb 32020-02-02T23:00:00-06:00 by remotephone Why am I here?This handy tweet was posted on twitter sharing a memory dump to...
-
15
Bus errors, core dumps, and binaries on NFS Here's another bit of Linux arcana that comes in handy every five years or so, when a fresh group of people run into a problem that just won't go away. Maybe it's happened to you and yo...
-
11
Using database dumps when queries are forbidden I once built a system which could find out if systems weren't being backed up properly. It worked by comparing the list of systems which were supposed to have backup services to the...
-
9
A parasitic RPC service that broke core dumps I already told a story about how you can hose your machine by pointing the Linux kernel at a custom core dump handler and then...
-
4
Collecting Metrics from Windows Kubernetes Nodes in AKSWindows applications constitute a large portion of the services and applications that run in many organizations. When movin...
-
5
Core dumps, feedback loops, and a game of telephone April 28, 2022 In the fall of 2003, I started an eight-month internship...
-
7
So, you read the last post and now know where to find your core dumps, great. Now what? That always seems to be the question, doesn’t it. W...
-
6
Wasm core dumps and debugging Rust in Cloudflare Workers 08/14/2023
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK