Skip to content

Commit

Permalink
Context propagation (#32)
Browse files Browse the repository at this point in the history
Context propagation between both different libraries n the same application and across applications by adding W3C headers.
  • Loading branch information
edeNFed authored Sep 29, 2022
1 parent 4755ac2 commit 483a265
Show file tree
Hide file tree
Showing 43 changed files with 5,108 additions and 1,148 deletions.
82 changes: 32 additions & 50 deletions docs/getting-started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The different emojivoto applications are communicating via gRPC. Instrumenting t
Run the following command:

```shell
kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
kubectl apply -k github.com/keyval-dev/opentelemetry-go-instrumentation/docs/getting-started/emojivoto
```

### Deploying Jaeger UI
Expand All @@ -47,51 +47,23 @@ In a real world application, you would probably want to send the tracing data to

## Instrumentation

Download [this patch file](https://raw.githubusercontent.com/keyval-dev/opentelemetry-go-instrumentation/master/docs/getting-started/voting-patch.yaml) and apply it to the voting deployment:
Apply the automatic instrumentation to the `emoji`, `voting`, and `web` applications by executing the following command:

```shell
kubectl patch deployment voting --patch-file voting-patch.yaml -n emojivoto
kubectl apply -f https://raw.githubusercontent.com/keyval-dev/opentelemetry-go-instrumentation/master/docs/getting-started/emojivoto-instrumented.yaml -n emojivoto
```

Looking at the patch file will give us a better idea of how the automatic instrumentation works:

```yaml
spec:
template:
spec:
shareProcessNamespace: true
containers:
- name: emojivoto-voting-instrumentation
image: keyval/otel-go-agent:v0.5.3
env:
- name: OTEL_TARGET_EXE
value: /usr/local/bin/emojivoto-voting-svc
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-voting"
securityContext:
runAsUser: 0
capabilities:
add:
- SYS_PTRACE
privileged: true
volumeMounts:
- mountPath: /sys/kernel/debug
name: kernel-debug
volumes:
- name: kernel-debug
hostPath:
path: /sys/kernel/debug
```
## Perform actions on the target Application

Now all that left to do is to perform some actions on the target application that will cause the creation of detailed distributed traces.

Port forward to the frontend service:

The instrumentation is achieved by performing the following steps:
```shell
kubectl port-forward svc/web-svc 8080:80 -n emojivoto
```

- Adding a sidecar container that runs the OpenTelemetry Go Instrumentation agent.
- Configuring the target executable to instrument, this is done via the `OTEL_TARGET_EXE` environment variable.
- Configuring the Jaeger exporter endpoint, this is done via the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable.
- Configuring the service name, this is done via the `OTEL_SERVICE_NAME` environment variable.
- Configuring the required permissions and security context for the instrumentation agent. Including sharing the process namespace, and mounting the kernel debugfs.
Go to `http://localhost:8080`, and click the **view the leaderboard** button.

## Viewing the traces

Expand All @@ -103,23 +75,33 @@ kubectl port-forward svc/jaeger 16686:16686 -n emojivoto

Then, open the Jaeger UI in your browser by navigating to http://localhost:16686/

After selecting the emojivoto-voting service, you should see the following traces:
After selecting the `emojivoto-web` service, you should see the following traces:
![Traces](jaeger_traces.png)

Each trace should contain data according to the OpenTelemetry specification, for example: gRPC method names, start and end timestamps, and even the goroutine id.
Let's start with a simple trace, click on one of the `/api/vote` traces, you should see something like the following:
![vote_trace](vote_trace.png)

Notice that we did not change the emojivoto-voting application to use OpenTelemetry. This is the exact same container that we used earlier.
A few things worth noticing in this trace:
- **In process context-propagation**: We can see that the `web` application got an HTTP request (the root span) which caused two sequential gRPC requests to the `emoji` and `voting` services.
- **Cross process context-propagation**: The automatic instrumentation adds the relevant headers to gRPC / HTTP requests in order to make traces distributed across processes. In Jaeger, different applications are marked in different colors.
- **Extremely low overhead**: The entire trace took 3.1 milliseconds to complete. This show that using eBPF for instrumentation adds extremely low overhead.
- **Following OpenTelemetry Specifications**: You can click on any span in the trace to view the different attributes. All the spans produced by the automatic instrumentation follows the OpenTelemetry specification and therefore will work with any OpenTelemetry compatible backend.

## Next Steps
Now we will view a more complex trace, search for traces for the `/api/leaderboard` endpoint.
You can quickly find them by clicking on the points with the highest duration in Jaeger's main screen.
![leaderboard_trace](leaderboard_trace.png)
We can get a pretty good understanding of how the leaderboard feature works by looking at this trace:
- First, the web service will perform a gRPC request to the `voting` service to get a list of the available emojis.
- Second, The web service will loop over the received list of emojis and for every item on the list it will perform a gRPC request to the `emoji` service to get the amount of votes for the current item.
- As you can see this happens sequentially, which is one of the reason the leaderboard endpoint takes about 150ms to complete.

Instrumenting other applications is easy:
### Notice that we did not change any application code to get those traces, we are using the exact same containers from the emojivoto project.

- Modify the patch file to match your application by setting the `OTEL_TARGET_EXE`,`OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_SERVICE_NAME` environment variables.
- Apply the modified patched file:
## Next Steps

```shell
kubectl patch deployment <deployment-name> --patch-file <modified-patch-file>
```
The easiest way to apply this automatic instrumentation for any application is by using a control plane such as [Odigos](https://github.com/keyval-dev/odigos).

For more details visit the [Odigos website](https://odigos.io).

## Cleanup

Expand Down
247 changes: 247 additions & 0 deletions docs/getting-started/emojivoto-instrumented.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: emoji
namespace: emojivoto
labels:
app.kubernetes.io/name: emoji
app.kubernetes.io/part-of: emojivoto
app.kubernetes.io/version: v11
spec:
replicas: 1
selector:
matchLabels:
app: emoji-svc
version: v11
template:
metadata:
labels:
app: emoji-svc
version: v11
spec:
serviceAccountName: emoji
shareProcessNamespace: true
terminationGracePeriodSeconds: 0
initContainers:
- name: copy-launcher
image: keyval/launcher:v0.1
command:
- cp
- -a
- /kv-launcher/.
- /odigos-launcher/
volumeMounts:
- name: launcherdir
mountPath: /odigos-launcher
containers:
- env:
- name: GRPC_PORT
value: "8080"
- name: PROM_PORT
value: "8801"
image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
name: emoji-svc
command:
- /odigos-launcher/launch
- /usr/local/bin/emojivoto-emoji-svc
volumeMounts:
- mountPath: /odigos-launcher
name: launcherdir
ports:
- containerPort: 8080
name: grpc
- containerPort: 8801
name: prom
resources:
requests:
cpu: 100m
- name: emojivoto-emoji-instrumentation
image: edenfed/otel-go-agent:v0.7
env:
- name: OTEL_TARGET_EXE
value: /usr/local/bin/emojivoto-emoji-svc
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-emoji"
securityContext:
runAsUser: 0
capabilities:
add:
- SYS_PTRACE
privileged: true
volumeMounts:
- mountPath: /sys/kernel/debug
name: kernel-debug
volumes:
- name: launcherdir
emptyDir: {}
- name: kernel-debug
hostPath:
path: /sys/kernel/debug
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: voting
namespace: emojivoto
labels:
app.kubernetes.io/name: voting
app.kubernetes.io/part-of: emojivoto
app.kubernetes.io/version: v11
spec:
replicas: 1
selector:
matchLabels:
app: voting-svc
version: v11
template:
metadata:
labels:
app: voting-svc
version: v11
spec:
serviceAccountName: voting
shareProcessNamespace: true
terminationGracePeriodSeconds: 0
initContainers:
- name: copy-launcher
image: keyval/launcher:v0.1
command:
- cp
- -a
- /kv-launcher/.
- /odigos-launcher/
volumeMounts:
- name: launcherdir
mountPath: /odigos-launcher
containers:
- env:
- name: GRPC_PORT
value: "8080"
- name: PROM_PORT
value: "8801"
image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
name: voting-svc
command:
- /odigos-launcher/launch
- /usr/local/bin/emojivoto-voting-svc
volumeMounts:
- mountPath: /odigos-launcher
name: launcherdir
ports:
- containerPort: 8080
name: grpc
- containerPort: 8801
name: prom
resources:
requests:
cpu: 100m
- name: emojivoto-voting-instrumentation
image: edenfed/otel-go-agent:v0.7
env:
- name: OTEL_TARGET_EXE
value: /usr/local/bin/emojivoto-voting-svc
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-voting"
securityContext:
runAsUser: 0
capabilities:
add:
- SYS_PTRACE
privileged: true
volumeMounts:
- mountPath: /sys/kernel/debug
name: kernel-debug
volumes:
- name: launcherdir
emptyDir: {}
- name: kernel-debug
hostPath:
path: /sys/kernel/debug
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: emojivoto
labels:
app.kubernetes.io/name: web
app.kubernetes.io/part-of: emojivoto
app.kubernetes.io/version: v11
spec:
replicas: 1
selector:
matchLabels:
app: web-svc
version: v11
template:
metadata:
labels:
app: web-svc
version: v11
spec:
serviceAccountName: web
shareProcessNamespace: true
terminationGracePeriodSeconds: 0
initContainers:
- name: copy-launcher
image: keyval/launcher:v0.1
command:
- cp
- -a
- /kv-launcher/.
- /odigos-launcher/
volumeMounts:
- name: launcherdir
mountPath: /odigos-launcher
containers:
- env:
- name: WEB_PORT
value: "8080"
- name: EMOJISVC_HOST
value: emoji-svc.emojivoto:8080
- name: VOTINGSVC_HOST
value: voting-svc.emojivoto:8080
- name: INDEX_BUNDLE
value: dist/index_bundle.js
image: docker.l5d.io/buoyantio/emojivoto-web:v11
name: web-svc
command:
- /odigos-launcher/launch
- /usr/local/bin/emojivoto-web
volumeMounts:
- mountPath: /odigos-launcher
name: launcherdir
ports:
- containerPort: 8080
name: http
resources:
requests:
cpu: 100m
- name: emojivoto-web-instrumentation
image: edenfed/otel-go-agent:v0.7
env:
- name: OTEL_TARGET_EXE
value: /usr/local/bin/emojivoto-web
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-web"
securityContext:
runAsUser: 0
capabilities:
add:
- SYS_PTRACE
privileged: true
volumeMounts:
- mountPath: /sys/kernel/debug
name: kernel-debug
volumes:
- name: launcherdir
emptyDir: {}
- name: kernel-debug
hostPath:
path: /sys/kernel/debug
Loading

0 comments on commit 483a265

Please sign in to comment.