.NET on Kubernetes
Zero-code .NET instrumentation on Kubernetes with the OpenTelemetry Operator.
On Kubernetes, the OpenTelemetry Operator injects .NET automatic instrumentation into your pods. You don't change the application or the image.
Prerequisites
Complete Kubernetes (OpenTelemetry Operator) Steps 1–3. This installs the operator, the collector and the kubesense/otel-instrumentation resource.
Add the annotations
Add two annotations to the pod template (spec.template.metadata.annotations), not to the Deployment's own metadata:
apiVersion: apps/v1
kind: Deployment
metadata:
name: <APP_NAME>
spec:
template:
metadata:
annotations:
instrumentation.opentelemetry.io/inject-dotnet: "kubesense/otel-instrumentation"
instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"
spec:
containers:
- name: app
image: <YOUR_REGISTRY>/<APP_NAME>:<TAG>| Annotation | Value |
|---|---|
instrumentation.opentelemetry.io/inject-dotnet | <namespace>/<name> of the Instrumentation resource, here kubesense/otel-instrumentation |
instrumentation.opentelemetry.io/otel-dotnet-auto-runtime | linux-x64 for glibc images (Debian, Ubuntu, the default mcr.microsoft.com/dotnet/aspnet tags); linux-musl-x64 for Alpine images. If omitted, linux-x64 is used |
warning: A wrong runtime value is the most common reason .NET pods run but send no traces. The profiler fails to load without an error. Check the base image of your Dockerfile. Tags ending in -alpine need linux-musl-x64.
Restart the workload so new pods are created with the instrumentation:
kubectl rollout restart deployment/<APP_NAME> -n <namespace>Verify
# The init container and profiler variables are present
kubectl describe pod <pod-name> -n <namespace> | grep -E 'opentelemetry-auto-instrumentation|CORECLR_|OTEL_'Generate some traffic, then open APM → Traces in KubeSense and filter by the service name. It defaults to the workload name; to change it, set OTEL_SERVICE_NAME in the container's env.
Troubleshooting
| Symptom | Check |
|---|---|
| No init container in the pod | The annotations must be on the pod template, and the pod must have been created after they were added |
| Init container present, but no traces | Wrong otel-dotnet-auto-runtime value for the image's libc. Also check the collector logs (see Verify) |
| Application fails to start after instrumentation | Check the application's startup logs for OpenTelemetry or profiler messages. Set OTEL_LOG_LEVEL=debug in the container's env for more detail |