Enable Single Step Instrumentation (SSI) on Kubernetes — automatically instruments applications for APM without code changes. Only use if the Datadog Agent is already running on the cluster — if not, use agent-install first.
Before doing anything else: Fully resolve all variables in
## Context to resolve before acting. Do not begin Step 0 until every variable has a concrete value.
Invoke this skill when the user expresses intent to:
Do NOT invoke this skill if:
agent-install firstverify-ssidd-apm-k8s-sdk-featuresThese are not a reading exercise — actively verify each one before proceeding.
Environment
agent-install completeBase image — verify before proceeding:
kubectl exec -n <APP_NAMESPACE> -l app=<APP_LABEL> -- ldd --version 2>&1 | head -1
If the output contains glibc or GLIBC or GNU libc — proceed.
ERROR: Output contains musl — stop. SSI's injector requires glibc and is ABI-incompatible with musl libc. The injector will load but silently abort injection, and no traces will be sent. Switch the base image to a glibc-based equivalent (e.g. python:X-slim, node:X-bookworm-slim, any Debian/Ubuntu/UBI image), then rebuild, reload, restart the pod, and rerun this check before continuing.
Language and runtime
-javaagent JVM flagExisting instrumentation — verify before proceeding:
# Check source files for manual tracer imports
grep -r "import ddtrace\|from ddtrace\|require 'ddtrace'\|require(\"dd-trace\")\|opentelemetry\|tracer\.trace(" <SOURCE_DIR> 2>/dev/null || echo "No manual instrumentation found"
# Check dependency manifests
grep -rE "ddtrace|dd-trace|opentelemetry" requirements.txt package.json Gemfile go.mod pom.xml 2>/dev/null || echo "No tracer dependency found"
ERROR: Any match found — remove the import/package before continuing (see Step 0). SSI silently disables itself when existing instrumentation is detected.
If no matches — proceed.
| Variable | How to resolve |
|---|---|
AGENT_NAMESPACE | Same namespace used in agent-install (e.g. datadog) |
APP_NAMESPACE | Ask the user which namespace their application runs in |
TARGET_LANGUAGES | Identify from repo — check Dockerfiles, package manifests, or ask the user |
DEPLOYMENT_NAME | Identify from repo or ask the user |
APP_LABEL | Check spec.selector.matchLabels.app in the Deployment manifest |
CLUSTER_NAME | Check spec.global.clusterName in datadog-agent.yaml, or kubectl config current-context — needed for kind clusters in Step 0 |
Scan all source files for: import ddtrace, from ddtrace, require 'ddtrace', require("dd-trace"), opentelemetry, tracer.trace(
Also check dependency manifests for ddtrace / dd-trace / OTel SDK packages.
If found — remove the import/package, then rebuild and reload:
docker build -f <DOCKERFILE_PATH> -t <IMAGE_NAME> <BUILD_CONTEXT>
[DECISION: how does this cluster get local images?]
Check the repo's setup script (e.g. create.sh, Makefile, justfile) for how images are loaded — do not guess from the cluster name or context. Common patterns:
| What you find in the setup script | Load command |
|---|---|
minikube image load or minikube cache add | minikube -p <PROFILE> image load <IMAGE_NAME> — profile is the -p flag value in the script, NOT necessarily the kubectl context name |
kind load docker-image | kind load docker-image <IMAGE_NAME> --name <CLUSTER_NAME> |
docker push to a registry | Push the new image; the cluster will pull on restart — skip local load |
k3d image import | k3d image import <IMAGE_NAME> -c <CLUSTER_NAME> |
| No image load step (cloud cluster, always pulls from registry) | Skip — image will be pulled on next deployment |
If the setup script is ambiguous, run the load command it uses exactly as written.
kubectl rollout restart deployment/<DEPLOYMENT_NAME> -n <APP_NAMESPACE>
kubectl wait --for=condition=Ready pod \
-l app=<APP_LABEL> \
-n <APP_NAMESPACE> \
--timeout=120s
SSI is configured on the existing DatadogAgent resource — do not create a separate manifest.
[DECISION: targeting scope — ask the user if unclear]
enabled: true with no targets or enabledNamespacesenabledNamespacestargets with podSelectordisabledNamespacesRecommended ddTraceVersions: java: "1", python: "2", js: "5", dotnet: "3", ruby: "2", php: "1"
Option A — Target specific workloads (recommended for production):