# Adobe の OpenTelemetry パイプラインの内側: 大規模環境におけるシンプルさ

LLMS index: [llms.txt](/llms.txt)

---

Developer Experience SIG は継続的なシリーズの一環として、さまざまな組織の実際の OpenTelemetry Collector デプロイメントについてインタビューを行い、実践的な教訓をより広いコミュニティと共有しています。
この記事では Adobe を取り上げます。
Adobe はグローバルなソフトウェア企業であり、そのオブザーバビリティチームは大規模環境でのシンプルさを追求した OpenTelemetry ベースのテレメトリーパイプラインを構築しています。
シグナルの種類ごとに数千の Collector が同社のインフラストラクチャ全体で稼働しています。

## 組織構造 {#organizational-structure}

Adobe の中央オブザーバビリティチームは、全社にオブザーバビリティインフラストラクチャを提供する責任を担っています。
しかし、シニアソフトウェアエンジニアの [Bogdan Stancu](https://github.com/bogdan-st) が説明したように、Adobe の買収の歴史により、全体が完全に統合されているわけではありません。
一部の大規模プロダクトグループは専用のオブザーバビリティチームを持っており、中央チームは主要なプロバイダーとして機能しています。

OpenTelemetry ベースのパイプラインは、主に新しいアプリケーションとデプロイメント向けに設計された新しい選択肢として、既存のモニタリングソリューションと並行して導入されました。
導入は任意であり、強制されていません。
既存のモニタリングが確立されたアプリケーションは移行されていません。

## OpenTelemetry の導入 {#opentelemetry-adoption}

OpenTelemetry を導入する決定は、プロジェクトの機能とチームの目標の一致によって推進されました。
オブザーバビリティチームは、Adobe の多様な技術ランドスケープに対応し、複数のバックエンドをサポートし、サービスチームが簡単に導入できるソリューションを必要としていました。

> 「私たちが求めていたすべてと合致していました」と Bogdan は語りました。

[OpenTelemetry Operator](/docs/platforms/kubernetes/operator/)、Collector のコンポーネントモデル、そしてコミュニティの Helm チャートが、個々のサービスチームに深い OpenTelemetry の専門知識を要求せずにスケールできる、プラットフォームレベルのオブザーバビリティ基盤の構成要素を提供しました。

## アーキテクチャ: 3層の Collector パイプライン {#architecture-a-three-tier-collector-pipeline}

Adobe の Collector アーキテクチャは 3 層設計に従っています。
2つの Collector を含むユーザー向け Helm チャート、シグナルごとの Collector デプロイメントを持つ集中管理の名前空間、そしてオブザーバビリティバックエンドです。

![Adobe のアーキテクチャ図](adobe-architecture.png)

### 第1層: ユーザー Helm チャート {#tier-1-the-user-helm-chart}

オブザーバビリティチームは、サービスチームが自身の名前空間にデプロイする Helm チャートを提供しています。
このチャートは2つの Collector を作成します。

**サイドカー Collector（アプリケーション Pod 内）**: アプリケーションコンテナと並行して実行され、意図的にロックダウンされています。
サービスチームはその設定を変更できません。
チームがダウンストリームにエクスポートすることを選択したものに関係なく、メトリクス、ログ、トレースのすべてのテレメトリーを収集します。
設定変更によるアプリケーションの再起動を防ぐため、設定は不変です。

**デプロイメント Collector（スタンドアロン）**: サイドカーから OTLP でテレメトリーを受信し、ルーティングとエクスポートを処理します。
サイドカーとは異なり、この Collector は Helm の値を通じて設定可能です。
オブザーバビリティチームは適切なデフォルト値を提供しますが、サービスチームはエクスポーターをカスタマイズしたり、新しい宛先を追加したりできます。
設定が変更された場合、デプロイメント Collector のみが再起動します。
アプリケーション Pod とそのサイドカーは影響を受けません。

### 第2層: 管理対象の名前空間 {#tier-2-the-managed-namespace}

デプロイメント Collector は、オブザーバビリティチームが完全に管理する集中型の名前空間にテレメトリーを転送します。
ここでの重要なアーキテクチャ上の決定はシグナルレベルの分離です。
管理対象の名前空間は、テレメトリーの種類ごとに個別の Collector デプロイメントを実行します。
メトリクス用、ログ用、トレース用がそれぞれ1つずつです。

あるシグナルの種類でバックエンドがレート制限されたり、データの拒否を始めたりしても、他のシグナルは中断されることなく流れ続けます。
数千の Collector からのアップストリームトラフィックを処理しているにもかかわらず、これらの管理対象のデプロイメントは一般的にデフォルトのレプリカ数で運用されており、積極的なオートスケーリングを必要としていません。

サービスチームは Helm の値で希望するバックエンドを設定し、OTLP エクスポートに HTTP ヘッダーを設定します。
管理対象の名前空間の Collector は、このヘッダーと[ルーティングコネクター](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/6aff35ab5351482a4664f29a7d5428cedcf61a92/connector/routingconnector?from_branch=main)を使用して、テレメトリーを正しいエクスポーターに振り分けます。

### 第3層: オブザーバビリティバックエンド {#tier-3-the-observability-backends}

管理対象の名前空間の Collector は、オブザーバビリティチームが管理するバックエンドの宛先にテレメトリーをエクスポートします。
複数のバックエンドがサポートされており、チームは Helm チャートの values ファイルで宛先を選択します。

## 自動計装: 2行で動作 {#auto-instrumentation-two-lines-and-it-works}

Adobe は、OpenTelemetry がサポートする言語全体で自動計装を行うために OpenTelemetry Operator を活用しています。
Operator はすべてのクラスターにデプロイされており、サービスチームは Kubernetes デプロイメントマニフェストに2つのアノテーションを追加することで計装を有効にします。

```yaml
instrumentation.opentelemetry.io/inject-java: 'true'
sidecar.opentelemetry.io/inject: 'true'
```

> 「デプロイメントに 2 行追加するだけです。
> そしてそのまま動きます」と Bogdan は語りました。

チームは Helm の値で言語を選択し、Operator が残りを処理します。
チームは手動の SDK 計装を自由に追加できますが（サイドカーはすべての OTLP データを受け入れます）、オブザーバビリティチームがサポートするパスは自動計装の体験に焦点を当てています。
Operator は、デプロイメントフリート全体でサイドカーと自動計装の管理を問題なく処理してきました。

この設計思想はプラットフォーム全体に通じています。
デフォルトのパスに必要な労力を最小限にしつつ、高度なユースケースにも対応できるようにするということです。

## カスタムディストリビューションとコンポーネント {#custom-distribution-and-components}

Adobe は、使用するコンポーネントのみを含む独自の OpenTelemetry Collector ディストリビューションをビルドし、Contrib からの不要な依存関係を排除しています。
このカスタムディストリビューションは、サービスチームに提供される Helm チャートのデフォルトです。
ただし、チームはカスタムビルドに含まれていないコンポーネントが必要な場合、手動で Contrib ディストリビューションに切り替えることができます。

Adobe はカスタムコンポーネントも保守しており、特に注目すべきは、チェーンされた Collector アーキテクチャにおける根本的な課題に対処するエクステンションです。

### チェーン Collector の問題 {#the-chain-collector-problem}

Collector がチェーンされると、エラーの可視性が問題になります。
ユーザーのデプロイメント Collector と管理対象の名前空間の Collector 間の OTLP トランザクションは、管理対象の名前空間の Collector がバックエンドへのエクスポートを試行する _前に_ 200のレスポンスで完了します。
バックエンドがデータを拒否した場合、エラーは管理対象の名前空間の Collector のログでのみ確認できます。

> 「ユーザーには200しか見えません。
> メトリクスはエクスポートされ、すべて順調です」と Bogdan は説明しました。
> 「それは私たちが望んでいたことではありませんでした。」

この問題に対処するため、Bogdan はバックエンド認証のサーキットブレーカーとして機能するカスタムエクステンションを構築しました。
このエクステンションは管理対象の名前空間の Collector のレシーバーで実行され、バックエンドにモック認証リクエストを事前に送信して結果をキャッシュします。
認証が失敗した場合、OTLP トランザクションが完了する前にアップストリームの Collector に401を返し、ユーザーが確認できる場所にエラーを伝搬させます。

このエクステンションの構築は、Bogdan にとって最初の Go プロジェクトの一つでした。
アップストリームへの貢献を試みた経験が、OpenTelemetry コミュニティへのより深い関与のきっかけとなりました。
今後について、Bogdan はエクスポーターの障害がチェーンされた Collector を通じてアップストリームに伝搬する、より汎用的なバックプレッシャーメカニズムが Collector に導入されることを歓迎すると述べています。

## デプロイメントとライフサイクル管理 {#deployment-and-lifecycle-management}

オブザーバビリティチームは、Collector ディストリビューションと OpenTelemetry Operator を四半期ごとのサイクルでアップグレードしています。
アップグレードの問題はまれです。

Helm チャートが更新されると、サービスチームは次のデプロイメント時に新しい Collector バージョンを取得します。
しかし、オブザーバビリティチームは Operator と古い Collector バージョン間の互換性の課題に遭遇しました。
Operator がアップグレードされると、新しい設定の期待に合わせて `OpenTelemetryCollector` カスタムリソースを変更することがあります。
サービスチームが大幅に古い Collector バージョンを実行している場合、これらの変更に互換性がなく、Collector の起動が妨げられることがあります。

解決策はシンプルで、Collector をアップグレードすれば問題は解消しますが、自分たちの側で何も変更していないのに突然 Collector が動作しなくなったチームにとっては混乱を招くことがありました。

### コンポーネントの非推奨化への対応 {#navigating-component-deprecations}

Adobe のデプロイメントは、OpenTelemetry の進化に伴うコンポーネントの非推奨化にも対応してきました。
チームは元々、HTTP ヘッダーに基づいてテレメトリーを異なるバックエンドに振り分けるためにルーティングプロセッサーを使用していましたが、プロセッサーが非推奨になった際にルーティングコネクターに移行しました。

移行には作業が必要でしたが、チームはこれを急速に進化するプロジェクトと共に歩む上で想定される一部と捉えています。

> 「これは私たちが認識していたリスクです。
> OpenTelemetry のランドスケープ全体が常に変化しており、迅速な開発を『問題』と呼べるのであれば、その利点は『問題』を上回ります」と Bogdan は説明しました。

## うまくいっている点 {#what-works-well}

全体的な体験は良好です。
Collector のコンポーネントモデル、Operator による自動計装の体験、そして Helm チャートベースのデプロイメントモデルは、すべて安定して動作しています。
最小限の設定でゼロからフルオブザーバビリティを実現するプラットフォームのプラグアンドプレイの性質は、導入チームから好評を得ています。

## 他の組織へのアドバイス {#advice-for-others}

プラットフォームレベルのオブザーバビリティパイプラインを構築した Adobe の経験に基づくアドバイスです。

- **OpenTelemetry をビルドするためのプラットフォームとして扱う**: そのまま使ってすべての問題を解決することを期待しないでください。
  特定のニーズに合わせて拡張やカスタマイズできるように設計されています。
- **カスタムコンポーネントの構築を恐れない**: Collector のアーキテクチャにより、ニーズに合わせたエクステンションの構築は簡単です。
- **ユーザーのシンプルさを重視した設計をする**: デフォルトのパスに必要な労力を最小限にしてください。
  プラットフォームを利用するチームはオブザーバビリティの専門家ではありません。
- **チェーンされた Collector でのエラーの可視性を計画する**: OTLP トランザクションの成功は、エンドツーエンドの配信を保証しません。
  ユーザーにエラーがどのように表示されるかを検討してください。

## 今後の展望 {#whats-next}

Adobe の事例は、中央のオブザーバビリティチームが大規模で多様な組織全体にスケーラブルなセルフサービスの OpenTelemetry パイプラインを提供する方法を示しています。
Operator、Helm チャート、サイドカー、そしてシグナルごとの Collector デプロイメントを組み合わせることで、サービスチームは最小限の労力でオブザーバビリティを利用でき、オブザーバビリティチームは集中型インフラストラクチャの制御を維持できるプラットフォームを構築しました。

私たちは今後も、さまざまな組織が本番環境で OpenTelemetry を運用する際の課題にどのように取り組んでいるかを紹介するストーリーを共有していきます。

あなた自身の OpenTelemetry ストーリーを共有しませんか？
CNCF の [#otel-devex](https://cloud-native.slack.com/archives/C01S42U83B2) Slack チャンネルにぜひご参加ください。
OpenTelemetry をどのように活用しているか、そして開発者体験を一緒にどう改善していけるか、ぜひお聞かせください。
