OpenTelemetry Collector Builder (ocb) を使ってお好みの OTel Collector を作る
初めに
こんにちは!この記事は OpenTelemetry Advent Calendar 2022 の 20 日目です 🎄 !
みなさん OpenTelemetry してますか?
OpenTelemetry には、バックエンドにテレメトリを送信する際のプロキシとして作用する OpenTelemetry Collector(以下、OTel Collector) というコンポーネントがあります。
今回は OTel Collector を自分好みにカスタマイズして作れる(?)、OpenTelemetry Collector Builder(通称:ocb)について やってみた を書きます。
この記事を読むことで、OTel Collector の構成や設定方法が超ざっくり分かると思います。
Custom OTel Collector 作成イメージ
OTel Collector について
OpenTelemetry ではモニタリングソリューションにテレメトリを送信する際に、OTel Collector を介してデータを集約し、エクスポートをするようなアーキテクチャを取ることができます。
OTel Collector 概要図
OTel Collector 自体は Receiver / Processor / Exporter から構成されています。(参考)
以下に示す例の他にも数多の Receiver / Processor / Exporter が用意されており、リポジトリを徘徊してこんなことができる processor があるのか〜と物色するのはとても楽しいのでオススメです。
-
Receiver
:テレメトリの受け口- 例: otlpreceiver, jaegerreceiver, prometheusreceiver, ・・・
-
Processor
:受け取ったテレメトリの処理部- 例: batchprocessor, tailsamplingprocessor(🎄 2日目 by ymotongpoo さん), ・・・
-
Exporter
:テレメトリの送信口- 例: otlpexporter, filelogreceiver(🎄 1日目 by @katzchang さん]
OTel Collector には標準とコントリビューションの2つのディストリビューションがあり、以下のリポジトリでどのようなコンポーネントが含まれているかを確認することができます。
コントリビューション Distro. には、AWS, GCP, Splunk などのベンダ製のコンポーネントや、Status が development のコンポーネントもたくさん含まれ配布されていることが分かります。
コントリビューション Distro. は多くのコンポーネントを含んでいるため やってみた するにはうってつけなのですが、ことプロダクション環境においては以下の自明な理由より、
必要に応じたコンポーネントのみ内包し構成を制限することを推奨 されております。 ※ 出典
① reduce the size of the collector, reducing deployment times for the collector
デプロイ時間短縮のために、OTel Collector のサイズ縮小するため
② improve the security of the collector by reducing the available attack surface area
セキュリティ的な観点
そこで、OpenTelemetry Collector Builder(以下、ocb)の登場です。
ocb は OpenTelemetry Community が開発している OTel Collector のビルドツールで、どのコンポーネントで構成するかのレシピを書くだけで簡単に Custom OTel Collector を作ることができます!
Custom OTel Collector を作る
ocb を使った Custom OTel Collector を作るには以下のフローを辿ります。
公式ドキュメントに沿っていけば簡単にできます。
Step.1 ocb のインストール
❯ GO111MODULE=on go install go.opentelemetry.io/collector/cmd/builder@latest
❯ builder version
ocb version dev
バイナリ版も配布されています。
Step.2 OTel Collector のレシピ(Yaml) の作成
yaml ファイルに OTel Collector に組み込みたいコンポーネント(Receiver / Processor / Exporter) を記述していきます。今回は最もシンプルな構成として、otlpreceiver
と otlpexporter
から構成される OTel Collector を作ってみます。
receivers:
- gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.68.0
exporters:
- gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.68.0
Step.3 ビルド
ocb を使ってビルドします。ビルドの際に、上記のレシピを指定して実行すると Custom OTel Collector の完成です 🥳 otelcol-custom
というバイナリが生成されていることがわかります!
❯ builder --config=otelcol-recipe.yaml --output-path=./
Flag --output-path has been deprecated, use config distribution::output_path
2022-12-20T16:21:25.354+0900 INFO internal/command.go:125 OpenTelemetry Collector Builder {"version": "dev", "date": "unknown"}
2022-12-20T16:21:25.355+0900 INFO internal/command.go:158 Using config file {"path": "otelcol-recipe.yaml"}
2022-12-20T16:21:25.355+0900 INFO builder/config.go:107 Using go {"go-executable": "/usr/local/bin/go"}
2022-12-20T16:21:25.357+0900 INFO builder/main.go:76 Sources created {"path": "./"}
2022-12-20T16:21:54.742+0900 INFO builder/main.go:118 Getting go modules
2022-12-20T16:21:57.499+0900 INFO builder/main.go:87 Compiling
2022-12-20T16:23:12.856+0900 INFO builder/main.go:99 Compiled {"binary": ".//otelcol-custom"}
❯ ls -hlrt otelcol-custom
-rwxr-xr-x 1 zuck3rx staff 21M 12 20 16:23 otelcol-custom
実際に Kubernetes 環境にデプロイしてみる
今回は Kubernetes 環境にデプロイをするため、OTel Collector を Docker イメージにビルドします。Dockerfile 内で ocb を使ってバイナリを作成し、実行する処理を書いてあげれば OK です。
# ocb を用いてビルド
FROM golang:1.18 as build
WORKDIR /app
COPY . .
RUN go install go.opentelemetry.io/collector/cmd/builder@latest
RUN builder --config=otelcol-recipe.yaml --name=otelcol-custom --output-path=.
# debian のベースイメージを用いて実行
FROM gcr.io/distroless/base-debian11
WORKDIR /app
COPY --from=build /app/otelcol-custom /app
EXPOSE 4317/tcp 4318/tcp
CMD ["/app/telcol-custom"]
あとは適当なイメージレジストリにあげ、以下のような K8s マニフェスト群を用意します。
k8sリソースのマニフェストファイル
apiVersion: v1
kind: ServiceAccount
metadata:
name: otel-collector-custom
---
apiVersion: v1
kind: Service
metadata:
name: otel-collector-custom
labels:
app: opentelemetry-custom
component: otel-collector-custom
spec:
ports:
- name: otlp-grpc # Default endpoint for OpenTelemetry gRPC receiver.
port: 4317
protocol: TCP
targetPort: 4317
- name: otlp-http
port: 4318
protocol: TCP
targetPort: 4318
selector:
component: otel-collector-custom
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: otel-collector-custom
labels:
app: opentelemetry-custom
component: otel-collector-custom
spec:
selector:
matchLabels:
app: opentelemetry-custom
component: otel-collector-custom
minReadySeconds: 5
progressDeadlineSeconds: 120
replicas: 1
template:
metadata:
labels:
app: opentelemetry-custom
component: otel-collector-custom
spec:
containers:
- command:
- "./otelcol-custom"
- "--config=/conf/otelcol-config.yaml"
image: <Path>
name: otel-collector-custom
resources:
limits:
cpu: 1
memory: 2Gi
requests:
cpu: 200m
memory: 400Mi
ports:
- containerPort: 4317 # default OTLP receiver
- containerPort: 4318 # default OTLP receiver
volumeMounts:
- name: otel-collector-config-vol-custom
mountPath: /conf
serviceAccountName: otel-collector-custom
volumes:
- configMap:
name: otel-config-custom
name: otel-collector-config-vol-custom
OTel Collector でどのコンポーネントを使用するかの設定は、以下のような yaml を書いた上で、ConfigMap としてデプロイします。
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4318"
processors:
exporters:
otlp:
endpoint: jaeger-collector.observability.svc.cluster.local:55680
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp]
Receiver
は OTel Collector の otlp port を指定。Exporter
はトレーシングバックエンドである Jaeger の otlp port を指定する簡単な設定を記述しています。
ConfigMap と Pod などのリソースをデプロイして、Custom OpenTelemetry Collector を無事にデプロイすることができました 🥳
# ConfigMap デプロイ
❯ k create configmap otel-config-custom \
--from-file=./otelcol-config.yaml --dry-run=client \
-o yaml | kubectl apply -f -
# OTel Collector デプロイ
❯ k apply -f otelcol-manifest.yaml
# デプロイできた〜
❯ k get po | grep otel-collector
otel-collector-custom-7f55d6bd48-xlstf 1/1 Running 0 16s
当たり前ですが、組み込んでいないコンポーネントを使おうとすると今回の Custom OTel Collector では otlp
しか使えないよ!と怒られます。
❯ ./otelcol-custom --config=./otelcol-config-no.yaml
Error: failed to get config: cannot unmarshal the configuration: 1 error(s) decoding:
* error decoding 'exporters': unknown type: "jaeger" for id: "jaeger" (valid values: [otlp])
2022/12/20 17:34:14 collector server run finished with error: failed to get config: cannot unmarshal the configuration: 1 error(s) decoding:
* error decoding 'exporters': unknown type: "jaeger" for id: "jaeger" (valid values: [otlp])
jaeger を設定した config
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4318"
processors:
exporters:
otlp:
endpoint: jaeger-collector.observability.svc.cluster.local:55680
jaeger:
endpoint: jaeger-collector.observability.svc.cluster.local:14250
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
exporters: [jaeger]
最後に
今回は OpenTelemetry Collector Builder の記事でした。
使い方自体はとても簡単なので、こんなツールがあるんだーと知るキッカケになれたら幸いです。
ocb を使って自分好みの Custom OpenTelemetry Collector を作ってみてはいかがでしょうか!!
明日は @yusukesato06 さんの「OpenTelemetry Collector導入のPoCと今後に向けて」です。
宣伝
11月に開催された Cloud Native Days Tokyo 2022 で、OTel Collector の SpanMetricsProcessor
を使ってアプリケーションから取得したメトリクスとトレースを相関させる。といったセッションを行いましたので、こちらも合わせてご覧いただけると嬉しいです 🙇!!
Discussion