2017-10-24 20:49:30 +00:00
# OpenTracing
2017-10-13 13:55:03 +00:00
2019-02-10 15:59:05 +00:00
Enables requests served by NGINX for distributed tracing via The OpenTracing Project.
2018-06-24 04:51:46 +00:00
2023-05-05 16:31:13 +00:00
Using the third party module [opentracing-contrib/nginx-opentracing ](https://github.com/opentracing-contrib/nginx-opentracing ) the Ingress-Nginx Controller can configure NGINX to enable [OpenTracing ](http://opentracing.io ) instrumentation.
2017-10-13 13:55:03 +00:00
By default this feature is disabled.
2018-06-24 04:51:46 +00:00
## Usage
2019-02-10 15:59:05 +00:00
To enable the instrumentation we must enable OpenTracing in the configuration ConfigMap:
2018-06-24 04:51:46 +00:00
```
data:
enable-opentracing: "true"
```
2019-10-30 03:30:01 +00:00
To enable or disable instrumentation for a single Ingress, use
the `enable-opentracing` annotation:
```
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/enable-opentracing: "true"
```
2018-06-24 04:51:46 +00:00
We must also set the host to use when uploading traces:
```
zipkin-collector-host: zipkin.default.svc.cluster.local
2019-02-20 15:16:34 +00:00
jaeger-collector-host: jaeger-agent.default.svc.cluster.local
2019-02-15 20:20:10 +00:00
datadog-collector-host: datadog-agent.default.svc.cluster.local
2018-06-24 04:51:46 +00:00
```
2019-12-12 23:12:12 +00:00
NOTE: While the option is called `jaeger-collector-host` , you will need to point this to a `jaeger-agent` , and not the `jaeger-collector` component.
2021-02-18 19:40:04 +00:00
Alternatively, you can set `jaeger-endpoint` and specify the full endpoint for uploading traces. This will use TCP and should be used for a collector rather than an agent.
2018-06-24 04:51:46 +00:00
2019-02-15 20:20:10 +00:00
Next you will need to deploy a distributed tracing system which uses OpenTracing.
[Zipkin ](https://github.com/openzipkin/zipkin ) and
[Jaeger ](https://github.com/jaegertracing/jaeger ) and
[Datadog ](https://github.com/DataDog/dd-opentracing-cpp )
have been tested.
2018-06-24 04:51:46 +00:00
Other optional configuration options:
```
2019-05-25 13:12:27 +00:00
# specifies the name to use for the server span
opentracing-operation-name
# specifies specifies the name to use for the location span
opentracing-location-operation-name
2021-10-24 21:36:21 +00:00
# sets whether or not to trust incoming tracing spans
opentracing-trust-incoming-span
2018-10-10 03:25:53 +00:00
# specifies the port to use when uploading traces, Default: 9411
2018-06-24 04:51:46 +00:00
zipkin-collector-port
# specifies the service name to use for any traces created, Default: nginx
zipkin-service-name
2018-10-10 03:25:53 +00:00
# specifies sample rate for any traces created, Default: 1.0
2018-06-28 14:42:32 +00:00
zipkin-sample-rate
2018-10-10 03:25:53 +00:00
# specifies the port to use when uploading traces, Default: 6831
2018-06-24 04:51:46 +00:00
jaeger-collector-port
2021-02-18 19:40:04 +00:00
# specifies the endpoint to use when uploading traces to a collector instead of an agent
jaeger-endpoint
2018-06-24 04:51:46 +00:00
# specifies the service name to use for any traces created, Default: nginx
jaeger-service-name
2021-03-23 23:43:34 +00:00
# specifies the traceparent/tracestate propagation format
jaeger-propagation-format
2018-06-24 04:51:46 +00:00
# specifies the sampler to be used when sampling traces.
# The available samplers are: const, probabilistic, ratelimiting, remote, Default: const
jaeger-sampler-type
# specifies the argument to be passed to the sampler constructor, Default: 1
jaeger-sampler-param
2019-02-15 20:20:10 +00:00
2019-05-21 10:14:33 +00:00
# Specifies the custom remote sampler host to be passed to the sampler constructor. Must be a valid URL.
# Default: http://127.0.0.1
jaeger-sampler-host
# Specifies the custom remote sampler port to be passed to the sampler constructor. Must be a number. Default: 5778
jaeger-sampler-port
2019-09-17 09:35:53 +00:00
# Specifies the header name used for passing trace context. Must be a string. Default: uber-trace-id
jaeger-trace-context-header-name
# Specifies the header name used for force sampling. Must be a string. Default: jaeger-debug-id
jaeger-debug-header
# Specifies the header name used to submit baggage if there is no root span. Must be a string. Default: jaeger-baggage
jaeger-baggage-header
# Specifies the header prefix used to propagate baggage. Must be a string. Default: uberctx-
jaeger-tracer-baggage-header-prefix
2019-02-15 20:20:10 +00:00
# specifies the port to use when uploading traces, Default 8126
datadog-collector-port
# specifies the service name to use for any traces created, Default: nginx
datadog-service-name
2020-10-01 21:42:22 +00:00
# specifies the environment this trace belongs to, Default: prod
datadog-environment
2019-02-15 20:20:10 +00:00
# specifies the operation name to use for any traces collected, Default: nginx.handle
datadog-operation-name-override
2020-01-08 00:59:59 +00:00
# Specifies to use client-side sampling for distributed priority sampling and ignore sample rate, Default: true
datadog-priority-sampling
# specifies sample rate for any traces created, Default: 1.0
datadog-sample-rate
2018-06-24 04:51:46 +00:00
```
2019-02-10 16:24:32 +00:00
All these options (including host) allow environment variables, such as `$HOSTNAME` or `$HOST_IP` . In the case of Jaeger, if you have a Jaeger agent running on each machine in your cluster, you can use something like `$HOST_IP` (which can be 'mounted' with the `status.hostIP` fieldpath, as described [here ](https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#capabilities-of-the-downward-api )) to make sure traces will be sent to the local agent.
2019-02-10 15:59:05 +00:00
2021-10-24 21:36:21 +00:00
Note that you can also set whether to trust incoming spans (global default is true) per-location using annotations like the following:
```
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/opentracing-trust-incoming-span: "true"
```
2018-06-24 04:51:46 +00:00
## Examples
2020-02-12 23:19:57 +00:00
The following examples show how to deploy and test different distributed tracing systems. These example can be performed using Minikube.
2018-06-24 04:51:46 +00:00
### Zipkin
2017-10-13 13:55:03 +00:00
2017-10-24 20:49:30 +00:00
In the [rnburn/zipkin-date-server ](https://github.com/rnburn/zipkin-date-server )
2019-02-10 15:59:05 +00:00
GitHub repository is an example of a dockerized date service. To install the example and Zipkin collector run:
2017-10-13 13:55:03 +00:00
```
2017-10-24 20:49:30 +00:00
kubectl create -f https://raw.githubusercontent.com/rnburn/zipkin-date-server/master/kubernetes/zipkin.yaml
kubectl create -f https://raw.githubusercontent.com/rnburn/zipkin-date-server/master/kubernetes/deployment.yaml
2017-10-13 13:55:03 +00:00
```
2022-01-17 00:57:28 +00:00
Also we need to configure the Ingress-NGINX controller ConfigMap with the required values:
2017-10-13 13:55:03 +00:00
2017-10-24 20:49:30 +00:00
```
$ echo '
2017-10-13 13:55:03 +00:00
apiVersion: v1
2017-10-24 20:49:30 +00:00
kind: ConfigMap
2017-10-13 13:55:03 +00:00
data:
enable-opentracing: "true"
zipkin-collector-host: zipkin.default.svc.cluster.local
metadata:
2020-05-17 18:27:56 +00:00
name: ingress-nginx-controller
2018-06-24 04:51:46 +00:00
namespace: kube-system
2017-10-24 20:49:30 +00:00
' | kubectl replace -f -
2017-10-13 13:55:03 +00:00
```
2019-02-10 15:59:05 +00:00
In the Zipkin interface we can see the details:
2018-06-24 04:51:46 +00:00

### Jaeger
2017-10-13 13:55:03 +00:00
2019-02-10 15:59:05 +00:00
1. Enable Ingress addon in Minikube:
2018-06-24 04:51:46 +00:00
```
$ minikube addons enable ingress
```
2017-10-13 13:55:03 +00:00
2019-02-10 15:59:05 +00:00
2. Add Minikube IP to /etc/hosts:
2018-06-24 04:51:46 +00:00
```
$ echo "$(minikube ip) example.com" | sudo tee -a /etc/hosts
```
2017-10-13 13:55:03 +00:00
2019-02-10 15:59:05 +00:00
3. Apply a basic Service and Ingress Resource:
2018-06-24 04:51:46 +00:00
```
# Create Echoheaders Deployment
2022-06-10 11:01:52 +00:00
$ kubectl run echoheaders --image=registry.k8s.io/echoserver:1.4 --replicas=1 --port=8080
2018-10-10 03:25:53 +00:00
2018-06-24 04:51:46 +00:00
# Expose as a Cluster-IP
$ kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
2018-10-10 03:25:53 +00:00
2018-06-24 04:51:46 +00:00
# Apply the Ingress Resource
$ echo '
2021-08-21 20:42:00 +00:00
apiVersion: networking.k8s.io/v1
2018-06-24 04:51:46 +00:00
kind: Ingress
metadata:
name: echo-ingress
spec:
2021-11-09 15:43:49 +00:00
ingressClassName: nginx
2018-06-24 04:51:46 +00:00
rules:
- host: example.com
http:
paths:
2021-11-02 00:12:58 +00:00
- path: /echo
pathType: Prefix
backend:
service:
name: echoheaders-x
port:
number: 80
2018-06-24 04:51:46 +00:00
' | kubectl apply -f -
```
2018-10-10 03:25:53 +00:00
4. Enable OpenTracing and set the jaeger-collector-host:
2018-06-24 04:51:46 +00:00
```
$ echo '
apiVersion: v1
kind: ConfigMap
data:
enable-opentracing: "true"
2019-02-20 15:16:34 +00:00
jaeger-collector-host: jaeger-agent.default.svc.cluster.local
2018-06-24 04:51:46 +00:00
metadata:
2020-05-17 18:27:56 +00:00
name: ingress-nginx-controller
2018-06-24 04:51:46 +00:00
namespace: kube-system
' | kubectl replace -f -
```
5. Apply the Jaeger All-In-One Template:
```
$ kubectl apply -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml
```
6. Make a few requests to the Service:
```
$ curl example.com/echo -d "meow"
2018-10-10 03:25:53 +00:00
2018-06-24 04:51:46 +00:00
CLIENT VALUES:
client_address=172.17.0.5
command=POST
real path=/echo
query=nil
request_version=1.1
request_uri=http://example.com:8080/echo
2018-10-10 03:25:53 +00:00
2018-06-24 04:51:46 +00:00
SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001
2018-10-10 03:25:53 +00:00
2018-06-24 04:51:46 +00:00
HEADERS RECEIVED:
accept=*/*
connection=close
content-length=4
content-type=application/x-www-form-urlencoded
host=example.com
user-agent=curl/7.54.0
x-forwarded-for=192.168.99.1
x-forwarded-host=example.com
x-forwarded-port=80
x-forwarded-proto=http
x-original-uri=/echo
x-real-ip=192.168.99.1
x-scheme=http
BODY:
meow
```
7. View the Jaeger UI:
```
$ minikube service jaeger-query --url
2018-10-10 03:25:53 +00:00
2018-06-24 04:51:46 +00:00
http://192.168.99.100:30183
```
2018-10-10 03:25:53 +00:00
2019-02-10 15:59:05 +00:00
In the Jaeger interface we can see the details:
2018-06-24 04:51:46 +00:00
