OpenTelemetry Operator ベストプラクティス¶
著者: 刘锐
OpenTelemetry Operator は、Kubernetes Operator の一種です。
主に以下の操作を管理します。
- OpenTelemetry Collector
- Auto-instrumentation:OpenTelemetry 計測ライブラリを使用してワークロードを自動計測します。
Guanceのコレクター DataKit は OpenTelemetry の設計思想を取り入れ、OTLP プロトコルと互換性があります。そのため、OpenTelemetry Collector を経由せずにデータを直接 DataKit にプッシュすることも、OpenTelemetry Collector の exporter を OTLP に設定し、アドレスを DataKit に向けることも可能です。
ここでは、2 つの方法で APM データをGuanceに統合します。
- APM データを OpenTelemetry Collector 経由でGuanceにプッシュする。
- APM データを直接Guanceにプッシュする。
前提条件¶
-
k8s環境 - Guanceアカウント
OpenTelemetry 関連コンポーネントのインストール¶
OpenTelemetry Operator のインストール¶
opentelemetry-operator.yamlをダウンロード
wget https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
opentelemetry-operator.yamlをインストール
[root@k8s-master ~]# kubectl apply -f opentelemetry-operator.yaml
namespace/opentelemetry-operator-system created
customresourcedefinition.apiextensions.k8s.io/instrumentations.opentelemetry.io created
customresourcedefinition.apiextensions.k8s.io/opentelemetrycollectors.opentelemetry.io created
serviceaccount/opentelemetry-operator-controller-manager created
role.rbac.authorization.k8s.io/opentelemetry-operator-leader-election-role created
clusterrole.rbac.authorization.k8s.io/opentelemetry-operator-manager-role created
clusterrole.rbac.authorization.k8s.io/opentelemetry-operator-metrics-reader created
clusterrole.rbac.authorization.k8s.io/opentelemetry-operator-proxy-role created
rolebinding.rbac.authorization.k8s.io/opentelemetry-operator-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/opentelemetry-operator-manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/opentelemetry-operator-proxy-rolebinding created
service/opentelemetry-operator-controller-manager-metrics-service created
service/opentelemetry-operator-webhook-service created
deployment.apps/opentelemetry-operator-controller-manager created
certificate.cert-manager.io/opentelemetry-operator-serving-cert created
issuer.cert-manager.io/opentelemetry-operator-selfsigned-issuer created
mutatingwebhookconfiguration.admissionregistration.k8s.io/opentelemetry-operator-mutating-webhook-configuration created
validatingwebhookconfiguration.admissionregistration.k8s.io/opentelemetry-operator-validating-webhook-configuration created
podを確認
[root@k8s-master df-demo]# kubectl get pod -n opentelemetry-operator-system
NAME READY STATUS RESTARTS AGE
opentelemetry-operator-controller-manager-7b4687df88-9s967 2/2 Running 0 26h
OpenTelemetry Collector のインストール¶
opentelemetry-collector.yamlを作成
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: demo
spec:
config: |
receivers:
otlp:
protocols:
grpc:
http:
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
batch:
send_batch_size: 10000
timeout: 10s
exporters:
logging:
otlp:
endpoint: "http://datakit-service.datakit:4319" # トレース情報をGuanceプラットフォームに出力
tls:
insecure: true
#compression: none # gzipを無効化
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [logging,otlp]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [logging]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [logging]
opentelemetry-collector.yamlを実行
podを確認
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-collector-59b9447bf9-dz47k 1/1 Running 0 61m
Instrumentation のインストール¶
OpenTelemetry Operator は、OpenTelemetry 自動計測ライブラリを注入および設定できます。現在、Apache HTTPD、DotNet、Go、Java、NodeJS、Python をサポートしています。
自動計測を使用するには、SDK と計測の設定を使用して計測リソースを設定します。
opentelemetry-instrumentation.yamlを作成
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: my-instrumentation
spec:
exporter:
endpoint: http://demo-collector:4317 # Opentelemetry collector アドレス
# endpoint: http://datakit-service.datakit:4319 # Guance datakit opentelemetry collector アドレス
propagators:
- tracecontext
- baggage
- b3
#sampler:
#type: parentbased_traceidratio
#argument: "0.25"
java:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
nodejs:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:latest
python:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:latest
- exporter:データ送信先アドレス。Opentelemetry collector でも、
otlpプロトコルを受信できる他のコレクターでも構いません。 - propagators: トレースデータの伝播器。伝播器の動作の詳細については、ドキュメントを参照してください。
- sampler: サンプリング
-
java\nodejs\python: 各言語のエージェント。実際のプロジェクトの要件に応じて記述します。
-
opentelemetry-instrumentation.yamlを実行
instrumentationを確認
[root@k8s-master ~]# kubectl get instrumentation
NAME AGE ENDPOINT SAMPLER SAMPLER ARG
my-instrumentation 65m http://demo-collector:4317
または、kubectl get otelinst コマンドで確認することもできます。
[root@k8s-master ~]# kubectl get otelinst
NAME AGE ENDPOINT SAMPLER SAMPLER ARG
my-instrumentation 71m http://demo-collector:4317
Guance¶
Kubernetes DataKit のインストール¶
OpenTelemetry コレクターの設定¶
datakit.yamlのDaemonSet以下にvolumeMountsを追加:
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: daemonset-datakit
name: datakit
namespace: datakit
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
app: daemonset-datakit
template:
metadata:
labels:
app: daemonset-datakit
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
containers:
...
volumeMounts:
- mountPath: /usr/local/datakit/conf.d/opentelemetry/opentelemetry.conf
name: datakit-conf
subPath: opentelemetry.conf
....
datakit.yamlのConfigMapdata 以下にopentelemetry.confを追加
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-conf
namespace: datakit
data:
opentelemetry.conf: |-
[[inputs.opentelemetry]]
[inputs.opentelemetry.grpc]
trace_enable = true
metric_enable = true
addr = "0.0.0.0:4319" # デフォルトは 4317
[inputs.opentelemetry.http]
enable = false
http_status_ok = 200
- DataKit を再起動
アプリケーション¶
ここでは JAVA アプリケーション springboot-server を用意します。
springboot-server.yamlを作成
apiVersion: v1
kind: Service
metadata:
name: springboot-server
labels:
app: springboot-server
spec:
selector:
app: springboot-server
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 31010
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-server
spec:
selector:
matchLabels:
app: springboot-server
replicas: 1
template:
metadata:
labels:
app: springboot-server
annotations:
sidecar.opentelemetry.io/inject: "true"
instrumentation.opentelemetry.io/inject-java: "true"
spec:
containers:
- name: app
image: registry.cn-shenzhen.aliyuncs.com/lr_715377484/springboot-server
ports:
- containerPort: 8080
protocol: TCP
springboot-server.yamlを実行
podを確認
[root@k8s-master ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-collector-59b9447bf9-dz47k 1/1 Running 0 24h 100.111.156.98 k8s-node1 <none> <none>
springboot-server-64b78f4487-9hv9r 1/1 Running 0 24h 100.111.156.108 k8s-node1 <none> <none>
podの詳細を確認
root@k8s-master ~]# kubectl describe pod springboot-server-64b78f4487-9hv9r
Name: springboot-server-64b78f4487-9hv9r
Namespace: default
Priority: 0
Node: k8s-node1/172.31.22.247
Start Time: ...
Labels: app=springboot-server
pod-template-hash=64b78f4487
Annotations: cni.projectcalico.org/containerID: 5700e2ab666a8bbc32b1ac84cc3d98137a7e186ca5cf4b0b6e7407ac8139d391
cni.projectcalico.org/podIP: 100.111.156.108/32
cni.projectcalico.org/podIPs: 100.111.156.108/32
instrumentation.opentelemetry.io/inject-java: true
sidecar.opentelemetry.io/inject: true
Status: Running
IP: 100.111.156.108
IPs:
IP: 100.111.156.108
Controlled By: ReplicaSet/springboot-server-64b78f4487
Init Containers:
opentelemetry-auto-instrumentation:
Container ID: containerd://c5747d8217b43fcb1a8eac00fbd33d70c7b25d1a3f0faaccdacea94c8b1e016b
Image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
Image ID: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java@sha256:f903e6eb067f28cba1f37b6ac592b511c61ce0bf2a73f6e7619359ac5d500d85
Port: <none>
Host Port: <none>
Command:
cp
/javaagent.jar
/otel-auto-instrumentation/javaagent.jar
...
Mounts:
/otel-auto-instrumentation from opentelemetry-auto-instrumentation (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-lbmf6 (ro)
Containers:
app:
Container ID: containerd://0db185a75e9eeb5eed97aaf8e707f4bd30f210e404f5fae98fc0d55a300a4470
Image: registry.cn-shenzhen.aliyuncs.com/lr_715377484/springboot-server
Image ID: registry.cn-shenzhen.aliyuncs.com/lr_715377484/springboot-server@sha256:bf394ec31566653bc6aa0e56dfc94a602bde3d95dfb08ac96d7f33c5dc00005e
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: ...
Ready: True
Restart Count: 0
Environment:
JAVA_TOOL_OPTIONS: -javaagent:/otel-auto-instrumentation/javaagent.jar
OTEL_SERVICE_NAME: springboot-server
OTEL_EXPORTER_OTLP_ENDPOINT: http://demo-collector:4317
OTEL_RESOURCE_ATTRIBUTES_POD_NAME: springboot-server-64b78f4487-9hv9r (v1:metadata.name)
OTEL_RESOURCE_ATTRIBUTES_NODE_NAME: (v1:spec.nodeName)
OTEL_PROPAGATORS: tracecontext,baggage,b3
OTEL_RESOURCE_ATTRIBUTES: k8s.container.name=app,k8s.deployment.name=springboot-server,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.replicaset.name=springboot-server-64b78f4487
Mounts:
/otel-auto-instrumentation from opentelemetry-auto-instrumentation (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-lbmf6 (ro)
Init Containers:初期化コンテナ。opentelemetry-auto-instrumentation sidecar を実行します。
デフォルトで JAVA アプリケーションに注入される環境変数
Environment:
JAVA_TOOL_OPTIONS: -javaagent:/otel-auto-instrumentation/javaagent.jar
OTEL_SERVICE_NAME: springboot-server
OTEL_EXPORTER_OTLP_ENDPOINT: http://demo-collector:4317
OTEL_RESOURCE_ATTRIBUTES_POD_NAME: springboot-server-64b78f4487-9hv9r (v1:metadata.name)
OTEL_RESOURCE_ATTRIBUTES_NODE_NAME: (v1:spec.nodeName)
OTEL_PROPAGATORS: tracecontext,baggage,b3
OTEL_RESOURCE_ATTRIBUTES: k8s.container.name=app,k8s.deployment.name=springboot-server,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.replicaset.name=springboot-server-64b78f4487
これで、JAVA アプリケーションに opentelemetry-auto-instrumentation sidecar が正常に注入されました。
Trace データの生成¶
-
ホスト上で以下のコマンドを実行して、
100.111.156.108 は pod のtraceデータを生成します。ipです。 -
また、svc のポートにアクセスして
traceデータを生成することもできます。
アプリケーションのログ情報を確認¶
[root@k8s-master ~]# kubectl logs -f springboot-server-64b78f4487-9hv9r
....
2023-08-* 16:34:17.454 [http-nio-8080-exec-8] INFO c.z.o.s.c.ServerController - [auth,74] traceId=a1b510158fc09c55c04de2d9472d10d7 spanId=61b6bd8264f7d8b1 - this is auth
2023-08-* 16:34:17.456 [http-nio-8080-exec-5] INFO c.z.o.s.f.CorsFilter - [doFilter,32] traceId=a1b510158fc09c55c04de2d9472d10d7 spanId=62370160a0fc0738 - url:/billing,header:
accept :application/json, application/*+json
traceparent :00-a1b510158fc09c55c04de2d9472d10d7-057f9e068e9cc007-01
b3 :a1b510158fc09c55c04de2d9472d10d7-057f9e068e9cc007-1
user-agent :Java/1.8.0_212
host :localhost:8080
connection :keep-alive
2023-08-* 16:34:17.456 [http-nio-8080-exec-5] INFO c.z.o.s.c.ServerController - [billing,82] traceId=a1b510158fc09c55c04de2d9472d10d7 spanId=9514404368a2d4fd - this is method3,null
trace 関連情報(traceparent、b3)が生成されていることが確認できます。
また、ログにも traceId と spanId が生成されていることがわかります。ログを trace に関連付ける方法については、ドキュメント ログ連携 を参照してください。
アプリケーションデータを直接Guanceにプッシュ¶
opentelemetry-instrumentation.yamlファイルのOTEL_EXPORTER_OTLP_ENDPOINTを調整
[root@k8s-master ~]# kubectl describe pod springboot-server-64b78f4487-t7gph |grep OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_ENDPOINT: http://datakit-service.datakit:4319
- 以下の
yamlを再実行
kubectl delete -f opentelemetry-instrumentation.yaml
kubectl apply -f opentelemetry-instrumentation.yaml
kubectl delete -f springboot-server.yaml
kubectl apply -f springboot-server.yaml
-
アプリケーションの URL にアクセスし、trace データを生成します。
-
Guanceアカウントにログインし、トレースビューを確認します。
