With Kubernetes, environment variables are typically managed in the .yaml manifest files rather
than baking them into the Docker image. So let’s remove the following two environment variables from the Dockerfile:
vi /home/splunk/workshop/docker-k8s-otel/helloworld/Dockerfile
Then remove the following two environment variables:
To save your changes in vi, press the esc key to enter command mode, then type :wq! followed by pressing the enter/return key.
Build a new Docker Image
Let’s build a new Docker image that excludes the environment variables:
cd /home/splunk/workshop/docker-k8s-otel/helloworld
docker build -t helloworld:1.2 .
Note: we’ve used a different version (1.2) to distinguish the image from our earlier version.
To clean up the older versions, run the following command to get the container id:
docker ps -a | grep helloworld
Then run the following command to delete the container:
docker rm <old container id> --force
Now we can get the container image id:
docker images | grep 1.1
Finally, we can run the following command to delete the old image:
docker image rm <old image id>
Import the Docker Image to Local Container Repository
Normally we’d push our Docker image to a repository such as Docker Hub.
But for this workshop, we’ll push the Docker image to the local container
repository running on our EC2 instance at localhost:9999
# Update the image tagdocker tag helloworld:1.2 localhost:9999/helloworld:1.2
# Import the image into the local repositorydocker push localhost:9999/helloworld:1.2
Deploy the .NET Application
Hint: To enter edit mode in vi, press the ‘i’ key. To save changes, press the esc key to enter command mode, then type :wq! followed by pressing the enter/return key.
To deploy our .NET application to K8s, let’s create a file named deployment.yaml in /home/splunk:
The deployment.yaml file is a kubernetes config file that is used to define a deployment resource. This file is the cornerstone of managing applications in Kubernetes! The deployment config defines the deployment’s desired state and Kubernetes then ensures the actual state matches it. This allows application pods to self-heal and also allows for easy updates or roll backs to applications.
Then, create a second file in the same directory named service.yaml:
A Service in Kubernetes is an abstraction layer, working like a middleman, giving you a fixed IP address or DNS name to access your Pods, which stays the same, even if Pods are added, removed, or replaced over time.
Then, create a third file in the same directory named ingress.yaml:
We can then use these manifest files to deploy our application:
cd /home/splunk
# create the deploymentkubectl apply -f deployment.yaml
# create the servicekubectl apply -f service.yaml
# create the ingresskubectl apply -f ingress.yaml
deployment.apps/helloworld created
service/helloworld created
ingress.networking.k8s.io/helloworld-ingress created
Test the Application
Use the following command to access the application:
curl http://helloworld.localhost/hello/Kubernetes
Configure OpenTelemetry
The .NET OpenTelemetry instrumentation was already baked into the Docker image. But we need to set a few
environment variables to tell it where to send the data.
Add the following to deployment.yaml file you created earlier:
IMPORTANT replace $INSTANCE in the YAML below with your instance name,
which can be determined by running echo $INSTANCE.
Then use the following command to generate some traffic:
curl http://helloworld.localhost/hello/Kubernetes
After a minute or so, you should see traces flowing in the o11y cloud. But, if you want to see your trace sooner, we have …
A Challenge For You
If you are a developer and just want to quickly grab the trace id or see console feedback, what environment variable could you add to the deployment.yaml file?
Click here to see the answer
If you recall in our challenge from Section 4, Instrument a .NET Application with OpenTelemetry, we showed you a trick to write traces to the console using the OTEL_TRACES_EXPORTER environment variable. We can add this variable to our deployment.yaml, redeploy our application, and tail the logs from our helloworld app so that we can grab the trace id to then find the trace in Splunk Observability Cloud. (In the next section of our workshop, we will also walk through using the debug exporter, which is how you would typically debug your application in a K8s environment.)
First, open the deployment.yaml file in vi:
vi deployment.yaml
Then, add the OTEL_TRACES_EXPORTER environment variable:
env:- name:PORTvalue:"8080"- name:NODE_IPvalueFrom:fieldRef:fieldPath:status.hostIP- name:OTEL_EXPORTER_OTLP_ENDPOINTvalue:"http://$(NODE_IP):4318"- name:OTEL_SERVICE_NAMEvalue:"helloworld"- name:OTEL_RESOURCE_ATTRIBUTES value:"deployment.environment=YOURINSTANCE"# NEW VALUE HERE:- name:OTEL_TRACES_EXPORTERvalue:"otlp,console"
Then, in your other terminal window, generate a trace with your curl command. You will see the trace id in the console in which you are tailing the logs. Copy the Activity.TraceId: value and paste it into the Trace search field in APM.