Kubernetes Auto-instrumentation

Introduction

Middleware's auto-instrumentation solution, built on top of the The OpenTelemetry (OTel) Kubernetes Operator, provides automatic detection and instrumentation for .NET, Java, Node.js, Python, and Go services.

The auto-instrumentation feature allows you to:

  1. Automatically detect application languages across your cluster.
  2. Enable/disable instrumentation per namespace or application.
  3. Manage instrumentation through a user-friendly UI.
  4. Apply changes without manual configuration.

Middleware Application Monitoring leverages the OpenTelemetry Operator for Kubernetes and can be used to auto-instrument your applications implemented in supported programming languages.

Prerequisites

1 Kubernetes Version

Kubernetes version 1.21.0 or above. Check with the following command:

2 Middleware Kubernetes Agent

Install Middleware Kubernetes agent using these instructions. Check that the agent is installed with the following command:

Setup Middleware Auto-instrumentation

Middleware Auto-instrumentation setup should be installed after installing Middleware’s Kubernetes Agent.

Installation Methods

Helm
Bash

In most of cases, you will need to install cert-manager along with the Operator, unless you already have cert-manager installed or have alternative methods of generating certificates in your Kubernetes cluster.

With cert-manager
Without cert-manager

You can configure namespace inclusion/exclusion when installing the Helm chart:

a. Include specific namespaces:

Only the specified namespaces will be monitored for auto-instrumentation.

b. Exclude specific namespaces:

All namespaces except the specified ones will be monitored (system namespaces are automatically excluded).

In most of cases, you will need to install cert-manager along with the Operator, unless you already have cert-manager installed or have alternative methods of generating certificates in your Kubernetes cluster.

With cert-manager
Without cert-manager

You can configure namespace inclusion/exclusion using environment variables when installing script:

a. Include specific namespaces:

Only the specified namespaces will be monitored for auto-instrumentation.

b. Exclude specific namespaces:

All namespaces except the specified ones will be monitored (system namespaces are automatically excluded).

Also You can modify this auto-instrumentation file to customize OpenTelemetry settings.

Configuring Auto-instrumentation

Application Selection

  1. Go to the "Choose Target Application" section in the Kubernetes agent installation screen:

    • View automatically detected applications and their languages.
    • Enable or disable instrumentation for specific applications.
    • Use "Select All" to toggle instrumentation for all detected applications.
    AutoInstrumentation
  2. For each application, you can see:

    • Application name.
    • Workload type (Deployment, StatefulSet or Daemonset).
    • Programming language (automatically detected).
    • Current instrumentation status.

Applying Changes

Auto-instrumentation applies to Deployments, DaemonSets, and StatefulSets. Ensure your application uses one of these resource types.

After making changes to your instrumentation configuration:

  1. Click "Save Changes" to apply your configuration.

  2. Restart the affected applications for the changes to take effect. Example:-

Core Components

  1. OpenTelemetry Operator: The foundation of the auto-instrumentation system

    • Manages the lifecycle of OpenTelemetry instrumentation.
    • Handles the injection of instrumentation agents.
    • Integrated as a dependency in the Middleware Helm chart.
  2. Middleware-Specific Components:

    • Language Detector: Automatically identifies the programming language of your applications.
    • Auto-injector Webhook: Mutates pod specifications to add necessary instrumentation annotations.

These components work together to:

  • Detect application languages automatically.
  • Apply appropriate instrumentation configurations.
  • Manage the lifecycle of instrumentation agents.
  • Provide visibility through the Middleware UI.

Verification

To verify that auto-instrumentation is working:

  1. Check the auto-instrumentation pods:
  1. Check the detected applications in the Middleware UI. Verify that they are enabled and have been restarted.
  2. Check application logs for instrumentation messages.
  3. Monitor your applications in the Middleware APM section.

Manual Custom Configuration

When to Use Manual Configuration

Use manual configuration in these scenarios:

  • Language detection isn't working for your application.
  • You need custom instrumentation settings.
  • Your application has special requirements.
  • You want fine-grained control over the instrumentation.

Before proceeding with manual configuration, disable auto-instrumentation for the specific application through the UI to avoid conflicts:

In order to auto-instrument your applications, the OTel Kubernetes Operator needs to know which Kubernetes Pods to instrument and which automatic instrumentation configuration, called Instrumentation Custom Resource (CR), to use for those Pods.

The OTel Kubernetes Operator installation steps described in the Installation section also installs the default Instrumentation CR called mw-autoinstrumentation in the mw-agent-ns namespace.

To confirm that Instrumentation CR is installed, issue the folowing command

The Instrumentation CR looks like below

In the above Instrumentation CR, OTEL_EXPORTER_OTLP_ENDPOINT is set to Middleware Kubernetes Agent service endpoint using either 9319 TCP port for gRPC or 9320 TCP port for HTTP.

This Instrumentation CR will be used to annotate Pod specifications. The annotations will depend on the programming language used to implement process running inside the Pod.

The following annotations SHOULD NOT be configured in the metadata section of the Deployment, DaemonSet, or StatefulSet definitions themselves, but rather in the metadata section of the Pod specifications within these objects.

Below is the list of supported programming languages and the annotations used for auto-instrumentation.

Java

To enable auto-instrumentation for a Java application, add the following annotation to your Pod specification:

Node.js

To enable auto-instrumentation for a Node.js application, add the following annotation to your Pod specification:

Python

To enable auto-instrumentation for a Python application, add the following annotation to your Pod specification:

.NET

To enable auto-instrumentation for a .NET application and specify the runtime identifier (RID), use the following annotations:

For Linux glibc based images (default):

For Linux musl based images:

Go

To enable auto-instrumentation for a Go application, you need to set the path to the executable and ensure the container has elevated permissions. Use the following annotations in the Pod specifications:

Additionally, set the required security context for the container in the Pod specification (spec.containers) as shown below:

Resource Attributes

If you want to add resource attributes to the traces generated by auto-instrumentation, you can add annotations in the following format to your Pod specification.

your-key and "your-value" are the keys and values for the resource attributes you want to add. You can add multiple resource attributes by having multiple such annotations.

Advanced Configuration

The annotations described above for all the supported programming languages used mw-agent-ns/mw-autoinstrumentation as the value for the annotation. This is because the OTel Kubernetes Operator installed using Middleware installation instructions creates mw-autoinstrumentation Instrumentation CR in mw-agent-ns namespace.

You can also create your own Instrumentation CR in any namespace and use them in the auto-instrumentation annotations.

Below are the all possible values for the auto-instrumentation annotation:

  • "true": Inject an Instrumentation CR from the current namespace. It is expected that you will have only one Instrumentation CR defined in the current namespace. The behavior could be unpredictable if you have multiple Instrumentation CRs defined in the current namespace.
  • "my-instrumentation": Inject a specific Instrumentation CR with name my-instrumentation from the current namespace.
  • "my-other-namespace/my-instrumentation": Inject a specific Instrumentation CR with name my-instrumentation from namespace my-other-namespace. This is the option used in all our examples above with Instrumentation CR name “mw-otel-auto-instrumentation” and namespace mw-agent.
  • "false": Do not inject an Instrumentation CR. This is useful for temporarily stopping instrumentation.

When using a Pod based workloads, such as Deployment or StatefulSet, make sure to add the annotation to the Pod template section (spec.template.metadata.annotations) and not to the Deployment or Statefuset metadata section (metadata.annotations).

Explore your data on Middleware

Once the auto-instrumentation setup is complete and the relevant Pods are restarted, the data should start flowing to Middleware for any new requests made to your applications. You can explore APM traces data by going to the APM section of your Middleware account.

Uninstall

Helm
Bash

Uninstall cert-manager and middleware autoinstrumentation setup

This will remove the mw resources , OTel Kubernetes Operator AND cert-manager (including one you installed previously) from your cluster. Ensure that this is what you want to do.

Uninstall only middleware autoinstrumentation setup

If you wish to keep cert-manager and only uninstall middleware autoinstrumentation setup, issue the command below

Uninstall cert-manager and middleware autoinstrumentation setup

This will remove the mw resources , OTel Kubernetes Operator AND cert-manager (including one you installed previously) from your cluster. Ensure that this is what you want to do.

Uninstall only middleware autoinstrumentation setup

If you wish to keep cert-manager and only uninstall OTel Kubernetes Operator, issue the command below

Troubleshooting

Google Kubernetes Engine

If you are using GKE private cluster, you will need to add a firewall rule that allows your GKE control plane CIDR block access to port 9443/tcp on worker nodes.

Use the command below to find out GKE control plane CIDR block

  • Replace <CLUSTER_NAME> with the name of your cluster.
  • Replace <REGION> with the region of your cluster.

For example,

Then you can add a firewall rule to allow ingress from this IP range and TCP port 9443 using command below

<GKE_CONTROL_PLANE_CIDR> and <GKE_CONTROL_PLANE_TAG> can be found by following the steps in the GKE firewall docs.

More information can be found in the Official GCP Documentation. See the GKE documentation on adding rules and the Kubernetes issue for more detail.

Applications not detected:

  • Check if your application uses a supported programming language.
  • For multi-container pods, ensure main application container is first in the pod spec.
  • Ensure applications are running and healthy.
  • Check language detector logs for potential issues.
  • Restart the language detector if detection problems persist.

Instrumentation not working:

  • Ensure the namespace is enabled for auto-instrumentation.
  • Confirm the application was restarted after enabling instrumentation.
  • Confirm required annotations are present in object YAML.
  • Examine webhook admission errors and mw-autoinstrumentation namespace component logs.
  • Verify network connectivity to Middleware endpoints.
  • Check opentelemtery operator logs.

If problem continue after these steps, please contact Middleware support Slack. Include your debug logs and config info (with sensitive information removed)

Additional Resources