Skip to content

Commit d815047

Browse files
k8s operator example and dev docs. (#155)
Ensuring our container for our autoinstrumentation distribution loads correctly using the OpenTelemetry k8s Operator Cc @akhileshpok --------- Co-authored-by: Steve Gordon <[email protected]>
1 parent 2d47f7e commit d815047

File tree

6 files changed

+215
-0
lines changed

6 files changed

+215
-0
lines changed

Elastic.OpenTelemetry.sln

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoInstrumentation.Integra
4747
EndProject
4848
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.OpenTelemetry.AutoInstrumentation", "src\Elastic.OpenTelemetry.AutoInstrumentation\Elastic.OpenTelemetry.AutoInstrumentation.csproj", "{B1CA9165-89D9-4D6E-AFEF-5434A8D8A672}"
4949
EndProject
50+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "k8s", "k8s", "{21E61166-2640-4E38-8108-1BA510C07110}"
51+
ProjectSection(SolutionItems) = preProject
52+
examples\k8s\elastic-otel-dotnet.yml = examples\k8s\elastic-otel-dotnet.yml
53+
examples\k8s\my-dotnet-application.yml = examples\k8s\my-dotnet-application.yml
54+
examples\k8s\README.md = examples\k8s\README.md
55+
EndProjectSection
56+
EndProject
5057
Global
5158
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5259
Debug|Any CPU = Debug|Any CPU
@@ -130,6 +137,7 @@ Global
130137
{F3AA76EC-C7D8-42DA-947D-4376B6562772} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
131138
{782E4DC1-8186-4BAC-B2F4-89E6DF22A4DD} = {AAD39891-0B70-47FA-A212-43E1AAE5DF56}
132139
{B1CA9165-89D9-4D6E-AFEF-5434A8D8A672} = {E622CFF2-C6C4-40FB-BE42-7C4F2B38B75A}
140+
{21E61166-2640-4E38-8108-1BA510C07110} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
133141
EndGlobalSection
134142
GlobalSection(ExtensibilityGlobals) = postSolution
135143
SolutionGuid = {573B2B5F-8CBB-4D52-A55A-4E65E282AAFB}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2+
USER $APP_UID
3+
WORKDIR /app
4+
EXPOSE 8080
5+
EXPOSE 8081
6+
7+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
8+
ARG BUILD_CONFIGURATION=Release
9+
WORKDIR /src
10+
COPY ["examples/Example.AspNetCore.Mvc/Example.AspNetCore.Mvc.csproj", "examples/Example.AspNetCore.Mvc/"]
11+
COPY ["src/Elastic.OpenTelemetry/Elastic.OpenTelemetry.csproj", "src/Elastic.OpenTelemetry/"]
12+
COPY ["examples/ServiceDefaults/ServiceDefaults.csproj", "examples/ServiceDefaults/"]
13+
RUN dotnet restore "examples/Example.AspNetCore.Mvc/Example.AspNetCore.Mvc.csproj"
14+
COPY . .
15+
WORKDIR "/src/examples/Example.AspNetCore.Mvc"
16+
RUN dotnet build "Example.AspNetCore.Mvc.csproj" -c $BUILD_CONFIGURATION -o /app/build
17+
18+
FROM build AS publish
19+
ARG BUILD_CONFIGURATION=Release
20+
RUN dotnet publish "Example.AspNetCore.Mvc.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
21+
22+
FROM base AS final
23+
WORKDIR /app
24+
COPY --from=publish /app/publish .
25+
ENTRYPOINT ["dotnet", "Example.AspNetCore.Mvc.dll"]

examples/Example.AspNetCore.Mvc/Example.AspNetCore.Mvc.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>net8.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
78
</PropertyGroup>
89

910
<ItemGroup>
@@ -15,4 +16,10 @@
1516
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
1617
</ItemGroup>
1718

19+
<ItemGroup>
20+
<Content Include="..\..\.dockerignore">
21+
<Link>.dockerignore</Link>
22+
</Content>
23+
</ItemGroup>
24+
1825
</Project>

examples/k8s/README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Run Elastic Distribution of OpenTelemetry .NET on k8s
2+
3+
The following documents how to auto instrument using the OpenTelemetry k8s Operator.
4+
5+
First create a namespace for your k8s deployment:
6+
7+
```bash
8+
kubectl create namespace my-dotnet-ns
9+
```
10+
11+
Next up we'll set our Elastic Cloud endpoint and key as k8s secrets.
12+
13+
```bash
14+
kubectl create secret generic elastic-otel -my-dotnet-ns \
15+
"--from-literal=endpoint=<cloud_endpoint>" \
16+
"--from-literal=apiKey=Authorization=Bearer <api_key>"
17+
```
18+
19+
Next create an `Instrumentation` resource by creating an [`elastic-otel-dotnet.yml`](elastic-otel-dotnet.yml) file.
20+
21+
Then apply it to create it in our namespace
22+
23+
```bash
24+
kubectl apply -f elastic-otel-dotnet.yml -n my-dotnet-ns
25+
```
26+
27+
We then edit the namespace to make sure our Instrumentation annotations get applied always:
28+
29+
```bash
30+
kubectl edit namespace my-dotnet-ns
31+
```
32+
ensure the following `instrumentation` gets added under `metadata>annotations`
33+
34+
```yml
35+
apiVersion: v1
36+
kind: Namespace
37+
metadata:
38+
annotations:
39+
instrumentation.opentelemetry.io/inject-dotnet: elastic-otel-dotnet
40+
```
41+
42+
We can now create our pod containing our dotnet image.
43+
44+
To add your containerized image create a new `my-dotnet-application.yml` file
45+
46+
```yml
47+
apiVersion: v1
48+
kind: Pod
49+
metadata:
50+
name: my-dotnet-application
51+
namespace: my-dotnet-application
52+
labels:
53+
app: my-dotnet-application
54+
spec:
55+
containers:
56+
- image: _YOUR_APPLICATIONS_DOCKER_URL_
57+
imagePullPolicy: Always
58+
name: my-dotnet-application
59+
```
60+
61+
We can then spin up this pod by applying the template
62+
63+
```bash
64+
kubectl apply -f my-dotnet-application.yml -n my-dotnet-ns
65+
```
66+
67+
Once spun up we can query the logs with
68+
69+
```bash
70+
kubectl logs my-dotnet-application -n my-dotnet-ns
71+
```
72+
73+
It should print the Elastic Distribution of OpenTelemetry .NET preamble
74+
75+
```log
76+
[2024-09-06 18:49:36.011][00001][------][Information] Elastic Distribution of OpenTelemetry .NET: 1.0.0-alpha.6.1
77+
```
78+
79+
TIP: You can expose this pod locally to your host using:
80+
81+
```bash
82+
kubectl port-forward -n my-dotnet-ns pods/my-dotnet-application 8081:8080
83+
```
84+
85+
Here we forward the container port `8080` to your local port `8081` allowing you to browse your application.
86+
87+
88+
89+
90+
### Use a local image as pod image
91+
92+
Useful when developing.
93+
94+
```bash
95+
docker build . -t asp-net-example -f examples/Example.AspNetCore.Mvc/Dockerfile
96+
minikube image load asp-net-example:latest --daemon
97+
```
98+
99+
This ensures minikube can resolve `asp-net-example:latest`, you can now update your
100+
application spec section to:
101+
102+
```yml
103+
spec:
104+
containers:
105+
- image: asp-net-example:latest
106+
imagePullPolicy: Never
107+
name: asp-net-example
108+
```
109+
110+
NOTE: Make sure `imagePullPolicy` is set to `Never`
111+
112+
113+
### Debug deployments
114+
115+
The `describe` command is great to validate the init-container ran and exposed
116+
all the necessary environment variables.
117+
118+
```bash
119+
kubectl describe pod my-dotnet-application -n my-dotnet-ns
120+
```
121+
122+
You can use `exec` to inspect the container to see if it matches your expectations.
123+
```log
124+
kubectl exec my-dotnet-application -n my-dotnet-ns -- ls -la /otel-auto-instrumentation-dotnet
125+
```
126+
127+
128+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apiVersion: opentelemetry.io/v1alpha1
2+
kind: Instrumentation
3+
metadata:
4+
name: elastic-otel-dotnet
5+
namespace: my-dotnet-application
6+
spec:
7+
env:
8+
- name: OTEL_EXPORTER_OTLP_ENDPOINT
9+
valueFrom:
10+
secretKeyRef:
11+
name: elastic-otel
12+
key: endpoint
13+
exporter:
14+
endpoint: $OTEL_EXPORTER_OTLP_ENDPOINT
15+
propagators:
16+
- tracecontext
17+
- baggage
18+
- b3
19+
sampler:
20+
type: parentbased_traceidratio
21+
argument: "1.0"
22+
dotnet:
23+
image: docker.elastic.co/observability/elastic-otel-dotnet:edge
24+
env:
25+
- name: OTEL_EXPORTER_OTLP_HEADERS
26+
valueFrom:
27+
secretKeyRef:
28+
name: elastic-otel
29+
key: apiKey
30+
- name: OTEL_LOG_LEVEL
31+
value: "info"
32+
- name: ELASTIC_OTEL_LOG_TARGETS
33+
value: "stdout"
34+
35+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: my-dotnet-application
5+
namespace: my-dotnet-application
6+
labels:
7+
app: my-dotnet-application
8+
spec:
9+
containers:
10+
- image: asp-net-example:latest
11+
imagePullPolicy: Never
12+
name: asp-net-example

0 commit comments

Comments
 (0)