How to run the Open Telemetry .NET Agent without implementing scripts on an Alpine Linux image
To implement automatic instrumentation of the OpenTelemetry (OTEL) .NET Agent, the OTEL documentation says to:
### Download the Bash Script that creates the directory structure for OTEL
curl -sSfL https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh -O
### Install the .NET OTEL files
sh ./otel-dotnet-auto-install.sh
### Give permissions to the script to instrument Open Telemetry
chmod +x $HOME/.otel-dotnet-auto/instrument.sh
### Run the Instrumentation Script at Startup
. $HOME/.otel-dotnet-auto/instrument.sh
For some organizations, it may not be convenient to add additional scripts into the Startup workflow for the Application. Or, the Open Telemetry scripts may throw errors because the scripts require dependencies that are not present on the Linux Image used for the Dotnet Services.
Workaround Steps
- Create Environment Variables or ConfigMap entries that are vFunction-specific
- Find-and-replace https://$VF_SERVER_ADDRESS with the actual vFunction Server Address
- Find-and-replace $VF_APP_ID with the App ID taken from the Installation Instruction in the vFunction UI
- Find-and-replace $MY_SERVICE with the name of the Service that should appear in the vFunction UI
### Environment Variables
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://$VF_SERVER_ADDRESS/api/unauth/otlp
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=none
export OTEL_LOGS_EXPORTER=none
export OTEL_EXPORTER_OTLP_HEADERS=X-VF-APP=$VF_APP_ID
export OTEL_SERVICE_NAME=$MY_SERVICE
### ConfigMap Entries
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: 'http/protobuf'
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: 'https://$VF_SERVER_ADDRESS/api/unauth/otlp'
- name: OTEL_TRACES_EXPORTER
value: 'otlp'
- name: OTEL_METRICS_EXPORTER
value: none
- name: OTEL_LOGS_EXPORTER
value: none
- name: OTEL_EXPORTER_OTLP_HEADERS
value: 'X-VF-APP=$VF_APP_ID'
- name: OTEL_SERVICE_NAME
value: '$MY_SERVICE'
- Create Environment Variables or ConfigMap entries that are OpenTelemetry-specific
- Find-and-replace /$DESIRED/$PATH with the location where you’ll install the OpenTelemetry DLLs
### Environment Variables
export CORECLR_ENABLE_PROFILING=1
export CORECLR_PROFILER='{918728DD-259F-4A6A-AC2B-B85E1B658318}'
export OTEL_DOTNET_AUTO_HOME="/$DESIRED/$PATH"
export CORECLR_PROFILER_PATH="$OTEL_DOTNET_AUTO_HOME/linux-musl-x64/OpenTelemetry.AutoInstrumentation.Native.so"
export DOTNET_ADDITIONAL_DEPS="$OTEL_DOTNET_AUTO_HOME/AdditionalDeps"
export DOTNET_SHARED_STORE="$OTEL_DOTNET_AUTO_HOME/store"
export DOTNET_STARTUP_HOOKS="$OTEL_DOTNET_AUTO_HOME/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll"
### ConfigMap Entries
- name: CORECLR_ENABLE_PROFILING
value: '1'
- name: CORECLR_PROFILER
value: '{918728DD-259F-4A6A-AC2B-B85E1B658318}'
- name: OTEL_DOTNET_AUTO_HOME
value: /$DESIRED/$PATH
- name: CORECLR_PROFILER_PATH
value: "$OTEL_DOTNET_AUTO_HOME/linux-musl-x64/OpenTelemetry.AutoInstrumentation.Native.so"
- name: DOTNET_ADDITIONAL_DEPS
value: "$OTEL_DOTNET_AUTO_HOME/AdditionalDeps"
- name: DOTNET_SHARED_STORE
value: "$OTEL_DOTNET_AUTO_HOME/store"
- name: DOTNET_STARTUP_HOOKS
value: "$OTEL_DOTNET_AUTO_HOME/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll"
- Create an Init Container with the Dotnet Application that loads the Open Telemetry directory
- Find-and-replace https://$VF_SERVER_ADDRESS with the actual vFunction Server Address
- Find-and-replace $VF_APP_ID with the App ID taken from the Installation Instruction in the vFunction UI
- Find-and-replace $MY_SERVICE with the name of the Service that should appear in the vFunction UI
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-app
name: my-app
spec:
selector:
matchLabels:
app: my-app
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: my-app
spec:
initContainers:
- name: otel-installer
command:
- sh
- -c
- |
cd /otel-home \
&& wget -q https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v1.7.0/opentelemetry-dotnet-instrumentation-linux-musl-x64.zip \
&& unzip "opentelemetry-dotnet-instrumentation-linux-musl-x64.zip" \
&& rm "opentelemetry-dotnet-instrumentation-linux-musl-x64.zip"
image: alpine:latest
imagePullPolicy: IfNotPresent
resources: {}
volumeMounts:
- mountPath: /otel-home
name: otel-home
containers:
- name: my-app
env:
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: http/protobuf
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://$VF_SERVER_ADDRESS/api/unauth/otlp
- name: OTEL_TRACES_EXPORTER
value: otlp
- name: OTEL_METRICS_EXPORTER
value: none
- name: OTEL_LOGS_EXPORTER
value: none
- name: OTEL_EXPORTER_OTLP_HEADERS
value: X-VF-APP=$VF_APP_ID
- name: OTEL_SERVICE_NAME
value: $MY_SERVICE
- name: OTEL_DOTNET_AUTO_HOME
value: /otel-home
- name: CORECLR_ENABLE_PROFILING
value: "1"
- name: CORECLR_PROFILER
value: '{918728DD-259F-4A6A-AC2B-B85E1B658318}'
- name: CORECLR_PROFILER_PATH
value: $(OTEL_DOTNET_AUTO_HOME)/linux-musl-x64/OpenTelemetry.AutoInstrumentation.Native.so
- name: DOTNET_ADDITIONAL_DEPS
value: $(OTEL_DOTNET_AUTO_HOME)/AdditionalDeps
- name: DOTNET_SHARED_STORE
value: $(OTEL_DOTNET_AUTO_HOME)/store
- name: DOTNET_STARTUP_HOOKS
value: /otel-home/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll
image: my-image:latest
ports:
- containerPort: 8080
name: web
protocol: TCP
resources:
limits:
cpu: 500m
memory: 800Mi
requests:
cpu: 100m
memory: 500Mi
volumeMounts:
- mountPath: /otel-home
name: otel-home
readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
volumes:
- emptyDir:
sizeLimit: 500Mi
name: otel-home
- Install the Open Telemetery Collector
- Build and Deploy the Application