在不改動 source code 的情況下,將 Opentelemetry 的 Python auto-instrumentation 加入,導入 trace/log/metrics 監控數據生成
之前文章介紹了 opentelemetry 在 k8s 的安裝,今天要來接著把 instrumentation 來補完。將介紹無須改動 service code 的情況下,讓服務能透過 opentelemetry instrumentation 生成監控數據,協助我們透明化服務的使用狀況
概述
以下是用 k8s opentelemetry operator 作 python
automatic instrumentation 的範例
- 設定 collector CRD:收集監控數據,處理篩選後,輸出到對應儲存系統 (ex. tempo, loki, prometheus, kafka, opentelemetry…)
- 設定 instrumentation CRD:設定 automatic instrumentation (自動收集 pod 的監控數據)
- 設定 pod 的 annotations 來加入 opentelemetry instrumentation:透過加入 annotation,讓 instrumentation 加進去 pod 進行自動監控數據生成
- 觀察 pod:可以觀察一下 opentelemetry instrument 是怎麼在不添加 code 的情況下,將 opentelemetry 的 package 加進去 pod 內部
設定 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
Reference
如何在Kubernetes集群中自动安装OpenTelemetry探针 — 日志服务 — 阿里云 (alibabacloud.com)