マイクロサービスアーキテクチャでは、1 つのリクエストが複数のサービスを横断して処理されます。問題が発生した際に「どのサービスの、どの処理で遅延が発生しているのか」を特定するのは容易ではありません。CNCF Graduated プロジェクトである OpenTelemetry は、分散トレーシングを標準化し、この課題を解決するオブザーバビリティフレームワークです。Kubo のような K3s ベースの Kubernetes 環境でも、OpenTelemetry を導入することでサービス間のリクエストフローを完全に可視化できます。
分散トレーシングの基本概念
なぜ分散トレーシングが必要なのか
The New Stack の解説が指摘するように、Kubernetes 上のマイクロサービス環境では、メトリクスとログだけでは不十分です。あるリクエストが Pod 間、ノード間、Namespace 間を横断する際の全体像を把握するには、分散トレーシングが不可欠です。
OpenTelemetry のテレメトリシグナル
OpenTelemetry はベンダーニュートラルなオブザーバビリティフレームワークで、3 つのテレメトリシグナルを統合的に扱います:
- トレース(Traces): リクエストのエンドツーエンドのフローを追跡。Span の親子関係でサービス間の呼び出しチェーンを表現
- メトリクス(Metrics): 定量的な測定値。リクエスト数、レイテンシ、エラー率など
- ログ(Logs): イベントの記録。トレース ID と相関付けることで、特定のリクエストに関連するログを特定
トレーシングの構成要素
Trace
├── Span A (API Gateway, 150ms)
│ ├── Span B (Auth Service, 20ms)
│ └── Span C (Product Service, 100ms)
│ ├── Span D (Database Query, 40ms)
│ └── Span E (Cache Lookup, 5ms)
- Trace: 1 つのリクエストの全体的な処理フロー
- Span: Trace 内の個々の操作単位。開始時刻、終了時刻、属性、イベントを持つ
- Context: Trace ID と Span ID を含む情報。サービス間で伝播される
Captain.AI はトレーシングデータを AI で分析し、パフォーマンスボトルネックの自動検出と最適化の提案を行います。
OpenTelemetry Collector の構成
OpenTelemetry Collector は、テレメトリデータの受信、処理、エクスポートを担うベンダー非依存のコンポーネントです。Uptrace の解説と Logit.io の実装ガイドを参考に構成を解説します。
Collector のアーキテクチャ
Receivers → Processors → Exporters
(OTLP) (batch) (Jaeger)
(Zipkin) (filter) (Tempo)
(Jaeger) (sampling) (OTLP)
Kubernetes へのデプロイ(DaemonSet 方式)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: otel-collector
namespace: observability
spec:
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
containers:
- name: collector
image: otel/opentelemetry-collector-contrib:0.98.0
args: ["--config=/conf/otel-collector-config.yaml"]
volumeMounts:
- name: config
mountPath: /conf
volumes:
- name: config
configMap:
name: otel-collector-config
Collector の設定例
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
namespace: observability
data:
otel-collector-config.yaml: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
memory_limiter:
check_interval: 1s
limit_mib: 512
tail_sampling:
decision_wait: 10s
policies:
- name: errors-policy
type: status_code
status_code: {status_codes: [ERROR]}
- name: slow-traces
type: latency
latency: {threshold_ms: 1000}
- name: probabilistic
type: probabilistic
probabilistic: {sampling_percentage: 10}
exporters:
otlp/tempo:
endpoint: tempo:4317
tls:
insecure: true
otlp/jaeger:
endpoint: jaeger-collector:4317
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, tail_sampling, batch]
exporters: [otlp/tempo]
Kubo で運用する K3s クラスタでは、DaemonSet 方式が推奨されます。ノードごとに 1 つの Collector を配置し、リソース効率を最大化します。
アプリケーションの計装
自動計装(Zero-Code Instrumentation)
OpenTelemetry の自動計装を使えば、コードを変更せずにトレーシングを導入できます。
Python の例:
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
# 環境変数での設定
export OTEL_SERVICE_NAME=my-python-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
# 自動計装で起動
opentelemetry-instrument python app.py
Java の例:
# Java Agent を使った自動計装
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=my-java-service \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
-jar my-app.jar
Kubernetes Operator による自動注入
Medium の実装記事が解説するように、OpenTelemetry Operator を使えば Pod のアノテーションで自動計装を注入できます:
apiVersion: v1
kind: Pod
metadata:
annotations:
instrumentation.opentelemetry.io/inject-python: "true"
spec:
containers:
- name: my-app
image: my-python-app:latest
手動計装の例(Go)
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)
func handleRequest(ctx context.Context) {
tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "handleRequest")
defer span.End()
// カスタム属性の追加
span.SetAttributes(
attribute.String("user.id", userID),
attribute.Int("http.status_code", 200),
)
// 子 Span の作成
ctx, childSpan := tracer.Start(ctx, "database-query")
result := queryDatabase(ctx)
childSpan.End()
}
Captain.AI と OpenTelemetry を組み合わせることで、AI がトレースデータからサービス間のボトルネックを自動的に特定し、改善提案を生成することが可能です。
バックエンド連携:Jaeger と Grafana Tempo
Jaeger との連携
Jaeger は CNCF Graduated の分散トレーシングバックエンドです。Medium のステップバイステップガイドを参考に:
# Jaeger Operator によるデプロイ
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: jaeger
namespace: observability
spec:
strategy: production
storage:
type: elasticsearch
options:
es.server-urls: http://elasticsearch:9200
Grafana Tempo との連携
Civo の実践ガイドが詳しく解説するように、Grafana Tempo は大規模なトレースデータの保存に最適化されたバックエンドです:
# Tempo の設定例
apiVersion: v1
kind: ConfigMap
metadata:
name: tempo-config
data:
tempo.yaml: |
server:
http_listen_port: 3200
distributor:
receivers:
otlp:
protocols:
grpc:
storage:
trace:
backend: s3
s3:
bucket: tempo-traces
endpoint: minio:9000
コンテキスト伝播
dasroot.net の解説が強調するように、分散トレーシングで最も重要なのが コンテキスト伝播 です。W3C Trace Context 標準に基づくヘッダーを使用します:
traceparent: 00-{trace-id}-{span-id}-{flags}
tracestate: vendor-specific-data
すべてのサービスがこのヘッダーを伝播することで、エンドツーエンドのトレースが完成します。
サンプリング戦略とパフォーマンス最適化
テールサンプリング
すべてのトレースを保存するとストレージコストが爆発的に増加します。markaicode の実装ガイドが推奨するテールサンプリング戦略:
processors:
tail_sampling:
decision_wait: 10s
policies:
# エラーを含むトレースは 100% 保存
- name: errors
type: status_code
status_code: {status_codes: [ERROR]}
# 1秒以上かかったトレースは 100% 保存
- name: slow-traces
type: latency
latency: {threshold_ms: 1000}
# その他は 10% サンプリング
- name: probabilistic
type: probabilistic
probabilistic: {sampling_percentage: 10}
パフォーマンス最適化のポイント
- バッチ処理: Collector でバッチサイズとタイムアウトを適切に設定
- メモリリミッター: OOM を防止するためのメモリ制限設定
- DaemonSet デプロイ: サイドカーよりリソース効率が高い
- 属性の最適化: 不要な属性を削除し、ペイロードサイズを削減
Andrew Odendaal のガイドによると、適切なサンプリング戦略により、トレースデータ量を 90% 削減しつつ、重要なトレースは 100% 保持できます。
まとめ
OpenTelemetry による分散トレーシングは、マイクロサービス環境のオブザーバビリティを根本的に改善します。本記事のポイントをまとめると:
- OpenTelemetry はトレース・メトリクス・ログを統合するベンダーニュートラルなフレームワーク
- Collector による柔軟なテレメトリパイプラインの構築
- 自動計装 でコード変更なしにトレーシングを導入可能
- Jaeger / Grafana Tempo との連携でトレースの保存・可視化
- テールサンプリング でコストを抑えつつ重要なトレースを保持
Kubo は K3s ベースで CNCF エコシステムとの高い親和性を持ち、OpenTelemetry の導入によりマイクロサービス環境の可視性を飛躍的に向上させることができます。分散システムのオブザーバビリティに取り組む方は、ぜひ Kubo をご検討ください。
AI によるトレースデータの自動分析に興味がある方は、Captain.AI の詳細をご確認ください。導入のご相談はお問い合わせからお気軽にどうぞ。