CRD Reference

Complete reference for the ObtraceInstrumentation custom resource — declarative configuration for GitOps workflows.

CRD Reference

The ObtraceInstrumentation custom resource defines how workloads in your cluster are instrumented. It is the primary configuration mechanism for Obtrace Zero and is fully compatible with GitOps tools like ArgoCD and Flux.

Resource definition

apiVersion: obtrace.io/v1alpha1
kind: ObtraceInstrumentation
metadata:
  name: obtrace-production

Short names for kubectl: oti, obtrace

kubectl get oti
kubectl describe obtrace obtrace-production

Spec fields

apiKey

Direct API key for authenticating with ingest-edge.

spec:
  apiKey: "obt_live_xxx"

For production, use apiKeySecretRef instead to avoid storing secrets in Git.

apiKeySecretRef

Reference to a Kubernetes Secret containing the API key.

spec:
  apiKeySecretRef:
    name: obtrace-credentials
    key: api-key

The Secret must exist in a namespace accessible by the operator. The operator reads the Secret at injection time and injects the value as an environment variable.

ingestEndpoint

URL of the ingest-edge service.

spec:
  ingestEndpoint: "https://ingest.obtrace.io"

Default (in-cluster): https://ingest-edge.obtrace.svc.cluster.local:8080

strategy

Global instrumentation strategy. See Strategies for details.

spec:
  strategy: "auto"  # auto | sdk | ebpf | hybrid | disable

namespaces

List of namespaces to instrument. If empty or not set, all namespaces are targeted (excluding system namespaces).

spec:
  namespaces:
    - "production"
    - "staging"

Use "*" to explicitly instrument all namespaces:

spec:
  namespaces:
    - "*"

excludeNames

List of workload names (Deployment, StatefulSet, DaemonSet) to skip.

spec:
  excludeNames:
    - "debug-pod"
    - "test-runner"
    - "legacy-cron"

selector

Kubernetes label selector to restrict which Pods are instrumented.

spec:
  selector:
    matchLabels:
      team: platform
    matchExpressions:
      - key: tier
        operator: In
        values: ["api", "worker"]

languageHints

Override detected language for specific workloads. The key is the Deployment/StatefulSet/DaemonSet name.

spec:
  languageHints:
    "api-gateway": "go"
    "legacy-service": "nodejs"
    "ml-worker": "python"

Valid values: nodejs, python, java, go, dotnet, php, ruby, rust, unknown.

Go and Rust hints force eBPF strategy. All other languages force SDK strategy.

sampling

Controls trace sampling rates.

spec:
  sampling:
    traceRatio: 0.5
    rulesPerService:
      "checkout-api": 1.0
      "health-checker": 0.01
FieldTypeDescription
traceRatiofloat (0.0-1.0)Global sampling ratio. 1.0 = sample everything, 0.1 = 10%
rulesPerServicemap[string]floatPer-service override. Key is the resolved service name

propagation

Controls trace context header injection and extraction.

spec:
  propagation:
    injectHeaders: true
    extractHeaders: true

When injectHeaders is true, agents add traceparent and X-Obtrace-Trace-Id to outbound HTTP requests. When extractHeaders is true, agents read these headers from inbound requests to continue distributed traces.

resourceAttributes

Custom key-value attributes added to every telemetry resource.

spec:
  resourceAttributes:
    "team": "platform"
    "cost_center": "engineering"
    "region": "us-east-1"

These are injected as OBTRACE_ATTR_* environment variables and included in the OTLP resource attributes of every span, log, and metric.

Status fields

The operator populates the status subresource with discovery and instrumentation state.

status:
  phase: "Active"
  instrumentedPods: 47
  discoveredWorkloads:
    - name: checkout-api
      namespace: production
      kind: Deployment
      language: nodejs
      framework: express
      strategy: sdk
      instrumented: true
      lastDetectedAt: "2026-03-23T10:30:00Z"
  conditions:
    - type: Ready
      status: "True"
      lastTransitionTime: "2026-03-23T10:00:00Z"
      reason: OperatorHealthy
      message: "Webhook serving, discovery active"
FieldDescription
phaseCurrent operator phase
instrumentedPodsCount of Pods with obtrace.io/instrumented=true
discoveredWorkloadsArray of all detected workloads with language, framework, strategy
conditionsStandard Kubernetes conditions

Printer columns

kubectl get oti displays:

NAME                 STRATEGY   INSTRUMENTED   PHASE    AGE
obtrace-production   auto       47             Active   2d

Complete example

apiVersion: obtrace.io/v1alpha1
kind: ObtraceInstrumentation
metadata:
  name: obtrace-production
spec:
  apiKeySecretRef:
    name: obtrace-credentials
    key: api-key
 
  ingestEndpoint: "https://ingest.obtrace.io"
 
  strategy: "auto"
 
  namespaces:
    - "production"
    - "staging"
 
  excludeNames:
    - "debug-pod"
    - "load-test-runner"
 
  languageHints:
    "api-gateway": "go"
    "legacy-service": "nodejs"
 
  sampling:
    traceRatio: 0.5
    rulesPerService:
      "checkout-api": 1.0
      "search-service": 0.1
 
  propagation:
    injectHeaders: true
    extractHeaders: true
 
  resourceAttributes:
    "team": "platform"
    "cost_center": "engineering"

Multiple CRDs

You can create multiple ObtraceInstrumentation resources for different scopes:

apiVersion: obtrace.io/v1alpha1
kind: ObtraceInstrumentation
metadata:
  name: obtrace-production
spec:
  namespaces: ["production"]
  strategy: "hybrid"
  sampling:
    traceRatio: 1.0
---
apiVersion: obtrace.io/v1alpha1
kind: ObtraceInstrumentation
metadata:
  name: obtrace-staging
spec:
  namespaces: ["staging"]
  strategy: "sdk"
  sampling:
    traceRatio: 0.1

The operator matches Pods to the first ObtraceInstrumentation whose namespaces field includes the Pod's namespace.

On this page