在不改動 source code 的情況下,將 Opentelemetry 的 Python auto-instrumentation 加入,導入 trace/log/metrics 監控數據生成

之前文章介紹了 opentelemetry 在 k8s 的安裝,今天要來接著把 instrumentation 來補完。將介紹無須改動 service code 的情況下,讓服務能透過 opentelemetry instrumentation 生成監控數據,協助我們透明化服務的使用狀況

Kiwi lee
9 min readJun 13, 2024

概述

以下是用 k8s opentelemetry operator 作 python automatic instrumentation 的範例

  1. 設定 collector CRD:收集監控數據,處理篩選後,輸出到對應儲存系統 (ex. tempo, loki, prometheus, kafka, opentelemetry…)
  2. 設定 instrumentation CRD:設定 automatic instrumentation (自動收集 pod 的監控數據)
  3. 設定 pod 的 annotations 來加入 opentelemetry instrumentation:透過加入 annotation,讓 instrumentation 加進去 pod 進行自動監控數據生成
  4. 觀察 pod:可以觀察一下 opentelemetry instrument 是怎麼在不添加 code 的情況下,將 opentelemetry 的 package 加進去 pod 內部
OpenTelemetry Logging | OpenTelemetry

設定 collector CRD

receivers

填寫 otlp

exporters

  • debug : 只列出已收到
  • debug/2 : 多加入 verbosity: detailed ,會印出完整的監控資料
  • otlphttp : 這邊是發送到 tempo 的 http 接口,填寫 SVC FQDN (架設在 monitor namespace)。沒有加入 TLS,所以註明 insecure: true

service.pipelines.traces

otlp 收集。輸出:stdout 與發送到 tempo

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: deployment-collector
namespace: monitor
spec:
serviceAccount: otelcontribcol
config: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318

processors:

exporters:
debug/2:
verbosity: detailed
debug:
otlphttp:
endpoint: http://tempo.monitor.svc.cluster.local.:4318
tls:
insecure: true

service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [debug,otlphttp]

在加入上面的 CRD 後,會自動生成下面的 k8s-object

設定 instrumentation CRD

insturment 包含 opentelemetry 支援的程式語言在同一份檔案

只設定 python 的部分

  • exporter 填寫要發送到 opentelemetry 的接口
  • python.image : 若是你們無法連線到外部的 image registry,可以調整這個數值
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: python-instrumentation
namespace: monitor
spec:
env: null
exporter:
endpoint: 'http://deployment-collector-collector.monitor.svc.cluster.local.:4318'
propagators:
- tracecontext
- baggage
python:
image: >-
image.com.tw/library/otel-autoinstrumentation-python:0.43b0
sampler:
argument: '1'
type: parentbased_traceidratio

要看有沒有成功,要去看 opentelemetry-operator 的 log

設定 pod 加入 opentelemetry instrumentation

加入

spec.template.annotations 裡面加入 instrumentation.opentelemetry.io/inject-python: $value

調整

✅ deployment 跟 Instrumentation 在同個 namespace

  • true : 預設的 insturment 名稱
  • $instrumentName : 注入 $instrumentName 的監控數據生成

❎ deployment 跟 Instrumentation 不在同個 namespace

  • $instrumentNS/$instrumentName

❌ 不使用

  • false : 不要使用

完整範本

連接到位在 monitor namespace 名為 python-instrumentation 的 instrumentation

apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deploy
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
app: hello-api
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
instrumentation.opentelemetry.io/inject-python: monitor/python-instrumentation

理論上設定部署上去後,就會生效了!如果沒有的話,可能要檢查 opentelemetry-operator 的 log,看是否是 instrument 找不到的問題

觀察 pod

經過 instrumentation 會加入 intiContainer,會將 opentelemetry auto instrumentation 的套件複製進去 main container 裡面

  initContainers:
- command:
- cp
- '-a'
- /autoinstrumentation/.
- /otel-auto-instrumentation-python
image: >-
image.com.tw/library/otel-autoinstrumentation-python:0.43b0
imagePullPolicy: IfNotPresent
name: opentelemetry-auto-instrumentation-python
resources:
limits:
cpu: 500m
memory: 32Mi
requests:
cpu: 50m
memory: 32Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /otel-auto-instrumentation-python
name: opentelemetry-auto-instrumentation-python
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-jm9cj
readOnly: true

main container 也會做些修改,像是修改 python_path ,寫入 otel 在 instrumentation 的參數 (如 OTEL_EXPORTER_OTLP_ENDPOINT )

服務會在有 opentelemetry 作為 middleware 來啟動,不會對使用者有什麼影響。

透過這個方法,可以在不改 code 的情況下,快速地將 trace 加入到服務中。

目前有支援的 python package contrib

opentelemetry-python-contrib/instrumentation at main · open-telemetry/opentelemetry-python-contrib (github.com)

部分擷取

Reference

如何在Kubernetes集群中自动安装OpenTelemetry探针 — 日志服务 — 阿里云 (alibabacloud.com)

--

--

Kiwi lee

Hi, I'm kiwi, Platform Engineer (SRE, DevOps). Python Engineer. Love art, books, longboard. https://kiwilee-blog.netlify.app/