
OpenTelemetry Collector、本番はQuick Startのまま置かない

OpenTelemetry CollectorをKubernetes本番環境に配置するなら、ノード固有の収集をDaemonSet、外部への集中転送をGatewayに分け、両者の間とバックエンドまでの送信経路を設計する。公式Quick Startは基本動作を確かめるローカルデモであり、本番環境の構築を目的としていない。
導入は、収集元と転送先の確定、各シグナルのpipeline接続、メモリ制御、送信キューと再試行、Collector自身の監視という順で進める。特にキューの容量と保持方法は、転送先の停止中にどれだけデータを待たせたいかによって決まる。設定を追加しただけで欠損がなくなるわけではなく、満杯や再試行期限切れも想定に入れる。
DaemonSetで集め、Gatewayから送る

Kubernetes向けの公式インストール例は、DaemonSetと単一のGatewayインスタンスを同時に配置する開始点を示し、本番向けには構成の調整が必要だとしている。DaemonSetはノードごとにCollectorを置くため、ノード上のコンテナログやホストのメトリクスを収集する役割に合う。Gatewayは独立した受信口としてOTLPを受け、共通処理やバックエンドへの転送を担う。
基本経路は「アプリケーションやノード上の収集元 → DaemonSetのCollector → Kubernetes Service → GatewayのCollector → 監視バックエンド」と整理できる。Gatewayは別ノードのローカルログファイルを直接読めないため、ファイルを読むreceiverはノード側に置く。一方、バックエンドの宛先や認証情報をGateway側にまとめれば、ノード側の設定を転送先ごとに増やさずに済む。
すべてのアプリケーション信号をDaemonSet経由にする必要はない。アプリケーションからGatewayへ直接OTLPを送る構成も選べる。ただし、ノード由来のログやメトリクスを集める処理と、クラスタ外へ送る処理は分けて定義したほうが、必要な権限、負荷、障害箇所を判断しやすい。
役割別のpipelineをつなぐ
Collectorではreceiver、processor、exporterを定義するだけではデータは流れない。service.pipelinesでtraces、metrics、logsのうち使う信号を選び、それぞれに受信、処理、送信のコンポーネントを結び付ける。初めは実際に使う送信元と転送先だけを残し、不要な受信ポートやpipelineを有効にしない。
- DaemonSet側:アプリケーションから受けるならOTLP receiverを置く。コンテナログやホストメトリクスを読むなら、それぞれに対応するreceiver、マウント、権限を追加する。処理後はGatewayのServiceを宛先とするOTLP exporterへ渡す。
- Gateway側:DaemonSetからのOTLPをreceiverで受け、必要な共通処理を通して、バックエンド向けexporterへ送る。バックエンドの認証情報もここで扱う。
- 両側のservice.pipelines:実際に収集する信号ごとにreceivers、processors、exportersを列挙する。extensionを定義した場合はservice.extensionsでも有効にする。
この構成を最小単位にすると、どこでデータが止まったかを追いやすい。例えばノードのログだけが届かないなら、まずノード側の読み取り設定とlogs pipelineを調べられる。トレースもログもGatewayまでは届くのにバックエンドに現れないなら、Gateway側のexporterとキューを調べる。
ノード由来の収集機能を追加するときは、使うCollectorの配布物に必要なreceiverが含まれるかも確認する。receiver名を設定に書いても、実行イメージにそのコンポーネントがなければ起動できない。収集対象を決めてから配布物、権限、マウントを選ぶ順序が合理的だ。
メモリを制御し、後段でバッチ化する

各pipelineではmemory_limiterを受信直後のprocessorとして置き、その後に必要なフィルタリングや属性処理、batchを続ける。先に不要なデータを落とせば、batchに載せる量を減らせる。batchは送信をまとめて効率を上げる処理であり、転送先の停止中にデータを永続保存する仕組みではない。
memory_limiterの設定は、Collector Podのメモリ制限と整合させる。receiverの処理、batch、exporterのメモリ内キューも容量を使うので、コンテナの上限をそのまま処理に使い切る設定は避ける。メモリ圧迫時には新しいデータの受け入れを抑えるため、送信元が拒否を受けたときに再送できるかも欠損の範囲に関わる。
平常時のメモリ使用量だけで上限を決めると、バックエンド停止中のキュー増加を見落とす。さらに復旧時は、滞留分の送信と新着データの処理が重なる。DaemonSetとGatewayでは入力の種類と流量が違うため、同じメモリ設定を機械的に複製せず、各Podの実際の負荷に合わせて調整する。
各ネットワーク区間にキューと再試行を置く

DaemonSetからGateway、Gatewayからバックエンドへ送るexporterには、それぞれsending_queueとretry_on_failureを設定する。公式の耐障害性ガイドは、送信キューと再試行を使う一方、キュー満杯、再試行期限切れ、永続保存先の障害ではデータが失われ得ると説明している。片方の区間だけを守っても、もう片方の停止には対応できない。
queue_sizeは受信量と許容したい停止時間から決める。小さければ停止中に満杯になり、大きければメモリやディスクの使用量が増す。retry_on_failureのmax_elapsed_timeも短すぎると、キューにデータが残っていても古い送信の再試行が終わる。通常時だけでなくピーク時の流量を見て、容量と期限を組み合わせる。
Collectorの再起動をまたいで未送信データを残したい区間では、file_storage extensionを定義し、exporterのsending_queue.storageに指定して、service.extensionsでも有効にする。保存先は書き込み可能な永続ボリュームに置き、Pod再作成後も対応するCollectorが同じキューを読めるようにする。Podとともに消える保存領域では、再起動時の保護にならない。
Gatewayを複製する場合、各インスタンスのキューと保存先の対応も必要になる。複数のCollectorが同じキューファイルを無造作に共有する構成は避け、各インスタンスが自分の保存領域を引き継げるようにする。永続キューを使っても、ディスク容量の枯渇や保存領域そのものの障害は別に監視する。
Collector自身の状態で切り替えを判断する
バックエンドにデータが見えていても、キューが満杯に近ければ転送経路には余裕がない。Collectorの内部メトリクスを収集し、otelcol_exporter_queue_sizeとotelcol_exporter_queue_capacity、送信失敗、受信拒否、プロセスのメモリ使用量をDaemonSet側とGateway側で分けて見る。health_checkはCollectorの稼働確認に使い、宛先までの到達確認は別に行う。
本番への切り替え前には、各信号が通常時に届くことに加え、下流を一時的に受信不能にしたときの挙動を確かめる。キューが増え、下流の復旧後に減るか、送信失敗や受信拒否が継続していないかを確認する。永続キューを採用した区間では、未送信データを残した状態でPodを再作成し、保存先への再接続と再送を確認する。
判定の要点は、どのpipelineが受け入れを拒否し、どのexporterのキューが詰まり、復旧後に送信を再開できるかを区別できることだ。そこまで観測できれば、容量不足、転送先の停止、ノード側の収集不備を同じ「データが見えない」という症状として扱わずに済む。
関連記事:
関連記事
ニュースレターを購読
Web3、AI、暗号資産の最新ニュースを受信箱にお届けします。




