Elven Observability: Operator Collector (Automatic Instrumentation)
In order to use auto-instrumentation, we need to install the collector operator.
Dependencies:
cert-manager
Install the operator
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
- If you are going to instrument Golang applications:
kubectl -n opentelemetry-operator-system patch deployment opentelemetry-operator-controller-manager \
--type=json \
-p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--enable-go-instrumentation=true"}]'
Install the collector
It is a recommended practice to send telemetry from containers to an OpenTelemetry Collector rather than directly to a backend. The Collector helps simplify secrets management, decouples data export issues (such as the need for retries) from your applications, and allows you to add additional data to your telemetry, such as with the k8sattributesprocessor
component. If you choose not to use a Collector, you can skip to the next section.
https://opentelemetry.io/docs/kubernetes/operator/automatic/
Configuration example
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: otel
spec:
config:
receivers:
otlp:
protocols:
grpc:
http:
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
batch:
send_batch_size: 10000
timeout: 10s
exporters:
otlp:
endpoint: "tempo-distributor.domain.io:443"
tls:
insecure: false
insecure_skip_verify: true
prometheusremotewrite:
endpoint: https://mimir-distributor.domain.io/api/v1/push
headers:
X-Scope-OrgID:
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite]
traces:
receivers: [otlp]
processors: []
exporters: [otlp]
- Apply the collector
kubectl apply -k otel-collector-operator/
OpenTelemetry Instrumentation
To manage auto-instrumentation, the Operator needs to be configured to know which pods to instrument and which auto-instrumentation to use for those pods. This is done through the Instrumentation CRD.
Ex. Java
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: instrumentation-sample
spec:
propagators:
- tracecontext
- baggage
- b3
sampler:
type: parentbased_traceidratio
argument: "1"
env:
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: otel-collector.monitoring:4318
java:
env:
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://otel-collector.monitoring:4317
Ex. DOTNET
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: instrumentation-sample
spec:
propagators:
- tracecontext
- baggage
- b3
sampler:
type: parentbased_traceidratio
argument: "1"
env:
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: otel-collector.default:4318
dotnet:
env:
- name: OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED
value: "false"
- name: OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED
value: "false"
- name: OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED
value: "false"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://otel-collector.monitoring:4318
- name: OTEL_TRACES_EXPORTER
value: "true"
- name: OTEL_METRICS_EXPORTER
value: "true"
Add annotations to existing deployments
The final step is to opt-in your services for auto-instrumentation. This is done by updating your services spec.template.metadata.annotations
to include a language-specific annotation:
- .NET:
instrumentation.opentelemetry.io/inject-dotnet: “true”
- Go:
instrumentation.opentelemetry.io/inject-go: “true”
- Java:
instrumentation.opentelemetry.io/inject-java: “true”
- Node.js:
instrumentation.opentelemetry.io/inject-nodejs: “true”
- Python:
instrumentation.opentelemetry.io/inject-python: “true”
Test application using auto-instrumentation for JAVA
https://opentelemetry.io/docs/kubernetes/operator/automatic/
kubectl apply -f - <
Restart the deployment for the operator to inject the agent via an init-container
kubectl rollout restart deployment java-sample
Perform a port-forward on port 8080 and use the loop below to send traces, metrics, and logs.
kubectl port-forward svc/java-app 8080:8080
We will create a loop to send several requests.
while true; do curl http://localhost:8080/api/hello && echo "" && sleep 1; done
Tracing Grafana
Test application using auto-instrumentation for .NET
kubectl apply -f - <
Restart the deployment for the operator to inject the agent via an init-container
kubectl rollout restart deployment dotnet-sample
Restart the deployment for the operator to inject the agent via an init-container
kubectl port-forward svc/dotnet-app 80:80
We will create a loop to send several requests.
while true; do curl http://localhost/weatherforecast && echo "" && sleep 1; done
while true; do curl http://localhost/error && echo "" && sleep 1; done