Using Jaeger in OpenShift/Kubernetes
General Instructions
-
Clone the git repository
git clone https://github.com/ibm-cloud-architecture/learning-distributed-tracing-101.git
-
Change to the lab directory
cd learning-distrubing-tracing-101/lab-jaeger-ocp
Understanding Jaeger
-
Read the OpenShift Documentation Understanding Jaeger
Installing the Jaeger operator
-
OpenShift 3
-
Install from OperatorHub.io https://operatorhub.io/operator/jaeger
-
-
OpenShift 4, You can use the CodeReady Containers for local development cluster https://cloud.redhat.com/openshift/install/crc/installer-provisioned
(OpenShift 3) Creating an instance of Jaeger
Create a Custom Resource for Jaeger
-
Log in to the OpenShift Container Platform web console.
-
Select project
operators
-
Verify Jaeger Operator installed
-
From the command line, create a Jaeger instance in the
default
namespace
kubectl apply -f - <<EOF apiVersion: jaegertracing.io/v1 kind: Jaeger metadata: name: my-jaeger EOF
(OpenShift 4) Creating an instance of Jaeger
Create a Custom Resource for Jaeger
-
Log in to the OpenShift Container Platform web console.
-
Select project
openshift-operators
-
Navigate to Operators → Installed Operators
-
Click the Jaeger Operator provided by Red Hat
-
Under Provided APIs
-
Click Create Instance
-
Edit namespace to your project for example
default
-
Review yaml and Click Create
Verify Jaeger instance created
-
Verify the Jaeger services in the
default
namespaceoc get services -n default | grep jaeger my-jaeger-agent ClusterIP None <none> 5775/UDP,5778/TCP,6831/UDP,6832/UDP 7m my-jaeger-collector ClusterIP 172.21.191.135 <none> 9411/TCP,14250/TCP,14267/TCP,14268/TCP 7m my-jaeger-collector-headless ClusterIP None <none> 9411/TCP,14250/TCP,14267/TCP,14268/TCP 7m my-jaeger-query ClusterIP 172.21.89.78 <none> 443/TCP 7m
Take a look at the my-jaeger-collector on port 14268/TCP this is the service to be used by our services to send the Jaeger traces containing the spans, you will configure this in the kubernetes deployment yaml manifest.
|
-
Find the route to the Jaeger UI
oc get route my-jaeger NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD my-jaeger my-jaeger-default.apps-crc.testing my-jaeger-query <all> reencrypt None
-
Open the Jaeger UI in the browser using value HOST/PORT https://my-jaeger-default.apps-crc.testing
Deploy the Application
-
Deploy the services
service-a
andservice-b
Use the file
jaeger-nodejs.yaml
for Node.js or the filejaeger-java.yaml
for JavaHere is an example using Node.js services and deployments:
oc apply -f jaeger-nodejs.yaml -n default
Let’s look at the file content on how the services are defined to be deploy into OpenShift cluster:
--- apiVersion: v1 kind: Service metadata: name: service-a labels: app: service-a spec: ports: - port: 8080 name: http selector: app: service-a --- apiVersion: apps/v1 kind: Deployment metadata: name: service-a labels: app: service-a version: v1 spec: replicas: 1 selector: matchLabels: app: service-a template: metadata: labels: app: service-a version: v1 spec: containers: - name: app image: csantanapr/service-a-nodejs env: - name: JAEGER_ENDPOINT value: http://my-jaeger-collector:14268/api/traces - name: SERVICE_FORMATTER value: service-b imagePullPolicy: Always ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: service-b labels: app: service-b spec: ports: - port: 8081 name: http selector: app: service-b --- apiVersion: apps/v1 kind: Deployment metadata: name: service-b labels: app: service-b version: v1 spec: replicas: 1 selector: matchLabels: app: service-b template: metadata: labels: app: service-b version: v1 spec: containers: - name: app image: csantanapr/service-b-nodejs env: - name: JAEGER_ENDPOINT value: http://my-jaeger-collector:14268/api/traces imagePullPolicy: Always ports: - containerPort: 8081
In the yaml deployment manifest there are few items to point out:
-
Ports
-
The port for the container is specified in the service and the container in the deployment, for example
service-a
with port8080
andservice-b
with port8081
-
-
Environment Variables
-
The variable
JAEGER_ENDPOINT
is specified to indicate to the Jaeger client library to send the traces using http to the jaeger collector servicehttp://my-jaeger-collector:14268/api/traces
that is deployed on the same namespacedefault
as the services. You could also opt for using a side card and use UDP to send traces to an agent side card and this will foward the traces to the jaeger collector for more info see the jaeger operator documentation on how to enable this with an annotation. -
The variable
SERVICE_FORMATTER
used byservice-a
to indicate the hostname ofservice-b
that will use to format the hello message.
-
-
-
Verify services are deployed and running:
oc get all -l app=service-a -n default oc get all -l app=service-b -n default NAME READY STATUS RESTARTS AGE pod/service-a-785975554d-5cql2 1/1 Running 0 19m pod/service-b-674b748766-t7464 1/1 Running 0 19m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/service-a ClusterIP 172.30.182.142 <none> 8080/TCP 20m service/service-b ClusterIP 172.30.108.212 <none> 8081/TCP 19m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/service-a 1/1 1 1 19m deployment.apps/service-b 1/1 1 1 19m
-
Expose the service
service-a
with a routeoc create route edge --service=service-a -n default
-
Get the hostname for the route:
oc get route service-a -n default NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD service-a service-a-default.apps-crc.testing service-a http edge None
Find Traces
-
Use curl or open browser with the endpoint URL using the HOST/PORT of the route
curl -k https://service-a-default.apps-crc.testing/sayHello/Carlos Hello from service-b Carlos!
From the result you can see that
service-a
calledservice-b
and replied back. -
In the Jaeger UI select service-a and click Find Traces
-
Click on one of the traces and expand the spans in the trace
Check one of the labs Lab Jaeger - Node.js or Lab Jaeger - Java for a more in depth lab for Opentracing with Jaeger.