Opentelemetry collector 在 kubernetes 中的介紹,包含 opentelemetry 的運作基礎
介紹 opentelmetry 的基礎概念,像是 collector 中的 receivers, processors, exports, service.pipeline 的參數設定,然後進入 k8s 的 opentelemetry,兩種版本的差異,及最後的安裝與 demo
關於 opentelemetry 的最基礎知識
- opentelemetry 不會像 prometheues, jaeger, loki 擔任 metrics/log/trace 的資料儲存後端
- opentelemetry 專注在生成 (generate)、收集 (collect)、管理 (manage)、輸出 (export)。(我自己會覺得跟 fluentbit 很像)
- 支持各種 third-party 元件的收集 (ex. prometheus),元件的輸出 (ex. tempo, jaeger, loki)
- 生成與收集的項目包含:metrics, trace, log
- 收集的 opentelemetry 元件:opentelemetry collector
- 生成的 opentelemetry 元件:opentelemetry instrument
最核心的元件 — opentelemetry collector
負責收集處理輸出監控相關的數據
- Receivers: 接收監控數據
receivers:
# Data sources: logs
fluentforward:
endpoint: 0.0.0.0:8006
# Data sources: traces, metrics, logs
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
# Data sources: metrics
prometheus:
config:
scrape_configs:
- job_name: otel-collector
scrape_interval: 5s
static_configs:
- targets: [localhost:8888]
- Processors: 監控數據的處理 & 監控過程中的控管
processors:
# Data sources: traces
attributes:
actions:
- key: environment
value: production
action: insert
- key: db.statement
action: delete
- key: email
action: hash
# Data sources: traces, metrics, logs
batch:
# Data sources: metrics
filter:
metrics:
include:
match_type: regexp
metric_names:
- prefix/.*
- prefix_.*
# Data sources: traces, metrics, logs
memory_limiter:
check_interval: 5s
limit_mib: 4000
spike_limit_mib: 500
# Data sources: traces
resource:
attributes:
- key: cloud.zone
value: zone-1
action: upsert
- key: k8s.cluster.name
from_attribute: k8s-cluster
action: insert
- key: redundant-attribute
action: delete
# Data sources: traces
probabilistic_sampler:
hash_seed: 22
sampling_percentage: 15
# Data sources: traces
span:
name:
to_attributes:
rules:
- ^\/api\/v1\/document\/(?P<documentId>.*)\/update$
from_attributes: [db.svc, operation]
separator: '::'
Opentelemetry 推薦要加的 processor
- memory_limiter: 加入 memory 限制器,避免監控數據把 opentelemetry collector 給塞爆。超過 soft_limit 會開始拒絕 metrics (receivers 需實作 error retry 機制),而超過 hard_limit 則會開始進行 garbage collection
- Any sampling or initial filtering processors
- Any processor relying on sending source from
Context
(e.g.k8sattributes
) - batch: 藉由批次累積後的上傳,可以減低負擔。可調整的項目像是
send_batch_size
(最大的 batch)、timeout
(無論大小,批次的發送時間) - Any other processors
- Exporters: 輸出處理完後的監控數據
exporters:
# Data sources: traces, metrics, logs
file:
path: ./filename.json
# Data sources: traces
otlp/jaeger:
endpoint: jaeger-server:4317
tls:
cert_file: cert.pem
key_file: cert-key.pem
# Data sources: traces, metrics, logs
kafka:
protocol_version: 2.0.0
# Data sources: traces, metrics, logs
# NOTE: Prior to v0.86.0 use `logging` instead of `debug`
debug:
verbosity: detailed
# Data sources: traces, metrics, logs
otlp:
endpoint: otelcol2:4317
tls:
cert_file: cert.pem
key_file: cert-key.pem
# Data sources: traces, metrics
otlphttp:
endpoint: https://otlp.example.com:4318
tls:
insecure: true
# Data sources: metrics
prometheus:
endpoint: 0.0.0.0:8889
namespace: default
# Data sources: metrics
prometheusremotewrite:
endpoint: http://prometheus.example.com:9411/api/prom/push
# When using the official Prometheus (running via Docker)
# endpoint: 'http://prometheus:9090/api/v1/write', add:
# tls:
# insecure: true
可以輸出給 prometheus, tempo, jaeger, 另一座的 opentelemetry, kafka 等等的。
須注意 exporter 中的 otlp
是 GRPC,若是要傳送 HTTP,需要用 otlphttp
。
- Services.pipeline: 定義 trace, metrics, log 的處理流程,裡面填入的元件必須在上面的 receivers, processors, exporters 定義才能正確使用
所以完整的 opentelemetry collector 範例如下:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
otlp:
endpoint: otelcol:4317
extensions:
health_check:
pprof:
zpages:
service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
collector 負責處理監控數據。而 instrument 就是負責生成監控數據
生成監控數據 — opentelemetry instrument
- 支援自動收集 (可以自動補抓內部套件的使用,ex. Python 可自動抓取到的 Python package 清單 LINK )
- 支援自己埋監控點 (Manual instrumentation, Exporting data)
- 目前支援的程式語言
上面大概是最基本的 opentelmetry 元件了 (๑•̀ㅂ•́)و✧
下面就來介紹 k8s 的 Opentelemery。
Kubernetes 中的 Opentelemetry
有兩種版本,分別是 opentelemetry collector 與 opentelemetry operator。
Opentelemetry Collector
可選擇 deployment, daemonset 模式,有一些預設的 receivers 可以選擇 (Important Components for Kubernetes | OpenTelemetry)。利用 configmap 來管理 opentelemetry collector 的設定。
Opentelemetry Operator
基於 kubernetes 的 crd 所改裝的 opentelemetry,會由opentelemetry-operator 的 deployment 來 watch opentelemetry 的 CRD (collector, instrument) 產生,然後執行像是生成 opentelemetry collector 的 deployment,或是 mutate 有需要 instrument 的 pod,使其內部能發送監控數據。
Collector 的 CRD 可以選擇 deployment, daemonset, statefulset, sidecar 形式,可以同時有多個 collector 存在。
不過 image 版本上,我在使用 helm-chart 時 collector 預設是 v0.93.0
,operator 則是 v0.92.1
,但因為 CRD 管控實在太香,所以我後來是選擇安裝 Opentelemetry Operator 的模式。
安裝 Opentelemetry Operator
因為 opentelemetry operator 是依靠 k8s crd 來創建 collector 與 instrument,所以需要跟 api-server 註冊 webhook。
要建立能跟 api-server 的 webhook,則需要有 TLS certificates 的 server,而用 cert-manager
這個套件的話,是最簡單的手法 🤣
安裝 dependency — cert-manager
- 先安裝 crds
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.crds.yaml
在安裝本體
2. 安裝本體
$ helm install my-release --namespace cert-manager --version v1.14.5 jetstack/cert-manager
安裝 operator 本體
$ helm install opentelemetry-operator open-telemetry/opentelemetry-operator \
--set "manager.collectorImage.repository=otel/opentelemetry-collector-k8s"
加入 crds — 使用 sidecar 模式
這邊 demo 會使用 jaeger 來做示範
首先先安裝 OpenTelemetryCollector 的 CRD
- mode: sidecar
- config.receivers: jaeger
- config.exporters: debug
- config.service.pipeline: jaeger -> debug
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: sidecar-for-my-app
spec:
mode: sidecar
config: |
receivers:
jaeger:
protocols:
thrift_compact:
processors:
exporters:
debug:
service:
pipelines:
traces:
receivers: [jaeger]
processors: []
exporters: [debug]
然後 pod 內的 annotations 加入 sidecar.opentelemetry.io/inject: “true”
(如果是 deployment 類型的,也是需要加在 pod template 裡面)
apiVersion: v1
kind: Pod
metadata:
name: myapp
annotations:
sidecar.opentelemetry.io/inject: "true"
spec:
containers:
- name: myapp
image: jaegertracing/vertx-create-span:operator-e2e-tests
ports:
- containerPort: 8080
protocol: TCP
這樣產生出來的 pod,就會多一個 sidecar container 來做監控
啟動的 log
然後打該 pod 的 port 8080 curl $podIP:8080
,其 otc-container 的即可看到對應的 trace 資訊
若是我們想看更完整的 debug 資訊,可參考 debugexporter,只要改變 exporter 的參數
exporter:
debug:
verbosity: detailed
這樣 log 就會把監控數據給印出來,如下圖
以上把 opentelemetry 的基礎使用介紹完了~~~
我自己是把 opentelemetry 當成監控數據的 proxy,接收來自各種來源的資訊 (receivers),做完處理後 (processors),再扔給對應的儲存空間 (exporters)。本身不會做資料的儲存。
因此 opentelemetry 有很多方便使用的 plugin 可以使用,就像 ansible 一樣,輕鬆的呼叫,而不用煩惱自己要去做串接,可以快速的收集。
再來也有不同的 mode,deployment, daemonset, sidecar 可以選擇,端看你對於監控數據的收集需求,選擇自己想要的模式,甚至可以用混合的。
但此外 opentelemetry 有一塊 instrument,也是很重要的核心,我自己覺得更是 opentelemetry 實用的地方,可以自動生成系統的監控數據,一樣可以減輕我們撰寫這些 trace 斷點的時間。下一篇應該會提到 opentelemetry 在 python 服務中,要如何安裝 auto-instrument。