Istio のトレース情報を OpenTelemetry Protocol を使って転送する
Istio にいつの間にか OpenTelemetry Protocol でトレースを転送する機能が搭載されていのでシュッとできるかなと思ったけど色々手順があったのでブログで紹介したいと思います。
データの転送先は New Relic に転送を実施しています。
参考情報
本記事を構成する上で参考にさせて頂いた記事やスライドを紹介します。
環境情報
以下の環境で検証しています
EKS 1.30
Istio 1.22.3
Bookinfo Application がデプロイされている前提で進めているので Bookinfo Application までの準備をすませてから取り組んでください。
既にIstio環境を時前で持っている場合はそちらを利用して頂いても大丈夫です。
OpenTelemetry Collector の準備
OpenTelemetry Collector(otel collector) の準備をします。
最低限の設定をしているので必要に応じて設定を変更して下さい。
# otel.yaml
apiVersion: v1
kind: Service
metadata:
name: opentelemetrycollector
namespace: observability
spec:
type: ClusterIP
ports:
- name: grpc-otlp # Default endpoint for OpenTelemetry receiver.
port: 4317
protocol: TCP
targetPort: 4317
- name: http-otlp # HTTP endpoint for OpenTelemetry receiver.
port: 4318
protocol: TCP
targetPort: 4318
- name: health
port: 13133
protocol: TCP
targetPort: 13133
selector:
app.kubernetes.io/name: opentelemetrycollector
---
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-conf
namespace: observability
data:
otel-collector-conf.yaml: |
receivers:
zipkin:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
otlp:
endpoint: "https://otlp.nr-data.net:4317" #https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp/
headers:
api-key: "<newrelic license key>"
extensions:
health_check:
service:
extensions:
- health_check
telemetry:
logs:
level: "DEBUG"
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: opentelemetrycollector
namespace: observability
spec:
selector:
matchLabels:
app.kubernetes.io/name: opentelemetrycollector
template:
metadata:
labels:
app.kubernetes.io/name: opentelemetrycollector
spec:
containers:
- name: otel-collector
args:
- --config=/conf/otel-collector-conf.yaml
image: otel/opentelemetry-collector-contrib:0.107.0
ports:
- containerPort: 4317
protocol: TCP
name: grpc-otlp
- containerPort: 4318
protocol: TCP
name: http-otlp
- containerPort: 13133
protocol: TCP
name: health
volumeMounts:
- mountPath: /conf
name: otel-conf
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: 200m
memory: 400Mi
volumes:
- configMap:
name: otel-conf
items:
- key: otel-collector-conf.yaml
path: otel-collector-conf.yaml
name: otel-conf
クラスタに反映します
kubectl apply -f otel.yaml
IstioOperator の編集
IstioOperator でトレーシングを有効にします。
#operator.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: demo
meshConfig:
accessLogFile: /dev/stdout
enableTracing: true
extensionProviders:
- name: otel-tracing
opentelemetry:
port: 4317
service: opentelemetrycollector.observability.svc.cluster.local
resource_detectors:
environment: {}
defaultProviders:
tracing:
- otel-tracing
extentionsProvider で opentelemetry を設定することによって OpenTelemetry 形式でのトレーシングを利用することができます。
筆者はistioctlで管理をしていたのでistioctlで変更を反映させます。
istioctl install -f operator.yaml -y
resource_detectors
が設定されていないというようなエラーが出ますが特に気にしなくても大丈夫ですが設定をしたい場合は ProxyConfig
を設定してください。
一例です
apiVersion: networking.istio.io/v1beta1
kind: ProxyConfig
metadata:
name: istio-proxyconfig
namespace: istio-system
spec:
concurrency: 0
environmentVariables:
OTEL_RESOURCE_ATTRIBUTES: "service.name=istio-proxy"
Telemetry API の設定
実際に IstioOperator で設定した内容を Telemetry APIを利用して有効化させます。
randomSamplingPercentage
でサンプリングレートを変更ができるのでお好みの数値に変更して下さい。
# telemetry.yaml
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: otel-demo
spec:
tracing:
- providers:
- name: otel-tracing
randomSamplingPercentage: 100
反映させます
kubectl apply -f telemetry.yaml
ここまでくると準備は完了なので istio-proxy を ingect させているPod群を再起動させましょう。何回かリクエストをさせて New Relic 側の画面でトレースが流れてきているか確認します。(黒塗り箇所はLB名がそのまま出てしまっているので隠しています。)
トレースが流れていることが確認できました。
Spanでいうところの ingress などとついている箇所が istio-proxy が生成した Span になっています。
内容としては以上になりますがカスタマイズなどで色々なことができそうなのでまた時間があればやってみたいと思います。
ハマったところ
実はこの作業をしている時に istio-proxy から otel collector に対して接続ができなくなっていて何故だろうと調べていたのですがなかなかエラーログがでず otel collector にもそれらしいエラーログがでていなかったので1行ずつ調べている時にこのようなログがでていました。
info localhostgate/featuregate.go:63 The default endpoints for all servers in components have changed to use localhost instead of 0.0.0.0. Disable the feature gate to temporarily revert to the previous default.
最初は見逃していたのですがこれが原因でログで調べたら1発で偉大な先人の知見があったので解決することが出来ました。
Discussion
Otel Collector 経由しなくても直接 New Relic に送る方法があったので追記で、otlp endpoint が用意されていれば他のツールでもできると思います。
公式ドキュメントの実装を参考にしました
extensionProvider の設定を http を利用するように変更
ServiceEntry と DestinationRule を追加