1+ #! /bin/bash
2+ # This script assumes that you are using a k8s environment and have deployed an application simulation already.
3+ #
4+ # It has been tested with the following setup instructions for the cluster:
5+ # minikube start --cpus 6 --memory 10g --network-plugin=cni --cni=false && cilium install && cilium status --wait
6+ #
7+ # With the simulation deployed into the k8s namespace "my-simulation", run it as follows:
8+ #
9+ # ./otel4k8s.sh "my-simulation"
10+ #
11+ # This will deploy cert manager, otel operater, a LGTM-stack in a single container and the instrumentation instructions
12+ # for your applications. The last step will restart all pods that belong to the simulation.
13+ #
14+ # For a more detailed configuration run
15+ #
16+ # ./otel4k8s.sh --help
17+ #
18+ # NOTE: Currently only java will be auto instrumented, other languages will be added soon
19+
20+ CERT_MANAGER_VERSION=1.16.3
21+ O11Y_NAMESPACE=o11y
22+ APP_NAMESPACE=" "
23+
24+ WITH_CERT_MANAGER=1
25+ WITH_OTEL_OPERATOR=1
26+ WITH_LGTM_CONTAINER=1
27+
28+ KUBECTL=" kubectl"
29+
30+ # Function to display help
31+ show_help () {
32+ echo " Usage: otel4k8s.sh [OPTION]"
33+ echo " Deploy cert manager, OpenTelemetry operator, a LGTM-stack in a single container and automatic instrumentation for a running app simulation"
34+ echo
35+ echo " Options:"
36+ echo " --patch Increase the patch number by 1."
37+ echo " (no option) Display the current version."
38+ }
39+
40+ if [[ $# -eq 1 && ${1} != --* ]]; then
41+ APP_NAMESPACE=${1}
42+ else
43+
44+ for ARG in " $@ " ; do
45+ case " $ARG " in
46+ --help)
47+ show_help
48+ exit 0
49+ ;;
50+ --app-namespace=* )
51+ APP_NAMESPACE=" ${ARG#* =} "
52+ shift
53+ ;;
54+ --o11y-namespace=* )
55+ O11Y_NAMESPACE=" ${ARG#* =} "
56+ shift
57+ ;;
58+ --no-cert-manager)
59+ WITH_CERT_MANAGER=0
60+ shift
61+ ;;
62+ --no-lgtm)
63+ WITH_LGTM_CONTAINER=0
64+ shift
65+ ;;
66+ --no-otel-operator)
67+ WITH_OTEL_OPERATOR=0
68+ shift
69+ ;;
70+ --dry-run)
71+ KUBECTL=" echo kubectl"
72+ shift
73+ ;;
74+ * )
75+ echo " Unknown option: $ARG "
76+ show_help
77+ exit 1
78+ ;;
79+ esac
80+ done
81+
82+ fi
83+
84+ # helper function that will rerun commands until they are successful
85+ retry_until_success () {
86+ local delay=5 # Seconds to wait between retries
87+ local max_attempts=0 # 0 means unlimited retries
88+ local attempt=0
89+
90+ while true ; do
91+ " $@ " && return 0 # Run the command; if it succeeds, return success
92+
93+ attempt=$(( attempt + 1 ))
94+ echo " Attempt $attempt failed. Retrying in $delay seconds..."
95+
96+ if [[ $max_attempts -gt 0 && $attempt -ge $max_attempts ]]; then
97+ echo " Maximum retry attempts reached. Giving up."
98+ return 1
99+ fi
100+
101+ sleep " $delay "
102+ done
103+ }
104+
105+ # Install Cert Manager
106+ if [[ ${WITH_CERT_MANAGER} -eq 1 ]]; then
107+ retry_until_success ${KUBECTL} apply -f " https://github.com/cert-manager/cert-manager/releases/download/v${CERT_MANAGER_VERSION} /cert-manager.yaml"
108+ fi
109+
110+ # Install the OTel operator
111+ if [[ ${WITH_OTEL_OPERATOR} -eq 1 ]]; then
112+ retry_until_success ${KUBECTL} apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
113+ fi
114+
115+ # Install LGTM in one container
116+ if [[ ${WITH_LGTM_CONTAINER} -eq 1 ]]; then
117+ ${KUBECTL} create namespace ${O11Y_NAMESPACE}
118+ retry_until_success ${KUBECTL} apply -f https://raw.githubusercontent.com/grafana/docker-otel-lgtm/refs/heads/main/k8s/lgtm.yaml --namespace " ${O11Y_NAMESPACE} "
119+ fi
120+
121+ add_otel_instrumentation () {
122+ ${KUBECTL} apply --namespace " ${APP_NAMESPACE} " -f - << EOF
123+ apiVersion: opentelemetry.io/v1alpha1
124+ kind: Instrumentation
125+ metadata:
126+ name: my-instrumentation
127+ spec:
128+ exporter:
129+ endpoint: http://lgtm.${O11Y_NAMESPACE} .svc.cluster.local:4317
130+ sampler:
131+ type: always_on
132+ EOF
133+ }
134+
135+ retry_until_success add_otel_instrumentation
136+
137+ # TODO: This is currently only injecting the java automatic instrumentation, we need a way to identify the language and inject the right one
138+ # see https://github.com/cisco-open/app-simulator/issues/147
139+ for deployment in $( kubectl get deployments -n " ${APP_NAMESPACE} " -o jsonpath=' {.items[*].metadata.name}' ) ; do
140+ ${KUBECTL} patch deployment ${deployment} -n " ${APP_NAMESPACE} " -p ' {"spec": {"template":{"metadata":{"annotations":{"instrumentation.opentelemetry.io/inject-java":"true"}}}} }'
141+ done
142+
143+ ${KUBECTL} rollout restart deployment -n " ${APP_NAMESPACE} "
144+
145+ ${KUBECTL} port-forward service/lgtm 3000:3000 4317:4317 4318:4318 --namespace ${O11Y_NAMESPACE} &
0 commit comments