テレメトリをバックエンドに送り、パイプラインを保護する
Tempo、Loki、Prometheus 向けの OTLP exporter を設定し、TLS、認証、シークレットも扱います。
テレメトリを収集することは仕事の半分に過ぎません。もう半分は、それを適切な場所に安全に届けることです。このガイドでは、一般的なオープンソースのバックエンド(例には Grafana のスタックを使います)向けの exporter の設定方法と、TLS、認証、設定ファイルの外に置くシークレットで、Collector への入出力のトラフィックを保護する方法を説明します。
OTLP exporter:gRPC と HTTP
OTLP を話す exporter は 2 つあります。
otlpは gRPC を使います。エンドポイントは、スキームなしのhost:portで、通常はポート 4317 です。otlphttpは HTTP を使います。エンドポイントは URL で、通常はポート 4318 であり、exporter はそれにシグナルのパス(/v1/traces、/v1/metrics、/v1/logs)を追加します。
同じタイプのものを複数定義するには、名前のサフィックスを使います。
exporters:
otlp/tempo:
endpoint: tempo.observability.svc.cluster.local:4317
tls:
insecure: true
otlphttp/loki:
endpoint: http://loki.observability.svc.cluster.local:3100/otlp
otlphttp/prometheus:
endpoint: http://prometheus.observability.svc.cluster.local:9090/api/v1/otlp
知っておくべきバックエンドの詳細:
- Tempo は、設定で OTLP receiver が有効になっている場合に、自身の receiver のポート(4317 gRPC、4318 HTTP)で、直接 OTLP を受け付けます。
- Loki は、HTTP ポートの
/otlpで OTLP のログを受け付けるため、otlphttpでは、最終的な URL は/otlp/v1/logsになります。 - Prometheus は、
/api/v1/otlp/v1/metricsで OTLP のメトリクスを受け付けますが、OTLP receiver を有効にして起動した場合にのみです(--web.enable-otlp-receiverフラグ)。
これらのパスは、お使いのバージョンの各製品のドキュメントで確認してください。その後、各シグナルをそのバックエンドにルーティングします。
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/tempo]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlphttp/loki]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlphttp/prometheus]
パイプラインは、複数の exporter を持つことで、同じデータを複数の場所に送れます。たとえば、主要なバックエンドとアーカイブです。
exporter の TLS
信頼できないネットワークを横断するものには、TLS を使います。
exporters:
otlp/backend:
endpoint: otlp.example.com:4317
tls:
ca_file: /etc/otel/certs/ca.crt # プライベート CA を信頼するため
cert_file: /etc/otel/certs/client.crt # 相互 TLS 用
key_file: /etc/otel/certs/client.key
パブリックな CA の場合は、システムのルートが使われるため、tls ブロック全体を省略できます。insecure: true は TLS を無効にし、クラスター内での開発専用です。本番では insecure_skip_verify: true を避けてください。TLS が提供する保護が失われるからです。
receiver の TLS と認証
ネットワークポートでリッスンする Collector は、TLS を要求し、制御できないものから到達可能な場合は、認証を要求すべきです。
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
tls:
cert_file: /etc/otel/certs/server.crt
key_file: /etc/otel/certs/server.key
client_ca_file: /etc/otel/certs/ca.crt # クライアント証明書を要求する (mTLS)
トークンベースの認証には、認証 extension を使います。bearertokenauth extension は、トークンの送信と確認の両方ができます。
extensions:
bearertokenauth/client:
scheme: Bearer
token: ${env:BACKEND_TOKEN}
exporters:
otlphttp/backend:
endpoint: https://otlp.example.com
auth:
authenticator: bearertokenauth/client
service:
extensions: [bearertokenauth/client]
受信リクエストを検証するには、basicauth や oidc のような他の extension があり、receiver から auth: { authenticator: <name> } で参照します。利用可能なオプションは、ディストリビューションとバージョンによって異なるため、extension の README を確認してください。
単純なヘッダーベースの認証情報には、exporter にヘッダーを設定することもできます。
exporters:
otlphttp/saas:
endpoint: https://otlp.vendor.example.com
headers:
api-key: ${env:VENDOR_API_KEY}
シークレットを設定の外に置く
Git にある設定ファイルに、トークンやパスワードをそのまま書かないでください。環境変数を参照し、シークレットストアから変数を供給します。
exporters:
otlphttp/backend:
headers:
authorization: Bearer ${env:BACKEND_TOKEN}
Kubernetes では、Secret から変数を注入します。
env:
- name: BACKEND_TOKEN
valueFrom:
secretKeyRef:
name: otel-backend
key: token
Secret 自体は、Git で暗号化するか(たとえば、Flux のガイドのように SOPS で)、シークレットマネージャーから同期してください。Collector は、マウントされたファイルを読み取る file: プロバイダー(${file:/path/to/secret})もサポートしており、ボリュームとしてマウントされ、プラットフォームによってローテーションされるシークレットに適しています。どのソースを使う場合でも、お使いのディストリビューションでそのプロバイダーが利用可能であることを確認してください。contrib のビルドにはいくつか含まれています。
ネットワークの露出
Collector は、クラスター内で動作することが多いため、そのデフォルトの姿勢が重要です。
- 意図的にバインドする。 最近のバージョンは、receiver のデフォルトを
localhostにしており、安全ですが、他のコンテナからは到達できません。0.0.0.0は、到達可能であるべきポートにのみ使い、NetworkPolicy、TLS、認証で保護します。 - 使わないものを無効にする。 使わない receiver と Service のポートを削除して、攻撃対象領域を小さく保ちます。
- デバッグ用のエンドポイントはオペレーター向け。
zpagesとpprofはlocalhostに保ち、決して公開しないでください。 - エクスポートの前にマスキングする。
attributesやtransformの processor を使って、認証情報、トークン、個人データを、ネットワークを出る前に削除します(本番対応のガイドを参照)。
アプリケーションの namespace だけが Collector に到達できるようにする NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-otlp-from-apps
namespace: observability
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: opentelemetry-collector
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
telemetry: "enabled"
ports:
- protocol: TCP
port: 4317
- protocol: TCP
port: 4318
確認する
otelcol validate --config=config.yamlを実行して、YAML とスキーマのミスを見つけます。- Collector を起動し、ログで exporter の接続や TLS のエラーを確認します。
- テスト用のスパンを送り、バックエンドで探します。届かない場合は、exporter のプロトコルとポートを、バックエンドが実際にリッスンしているものと比較します。
- Collector 自身のメトリクスで、バックエンドがデータを拒否すると増える
otelcol_exporter_send_failed_*のカウンターを確認します。
人気のガイド
-
OpenTelemetry を解説する:SDK、OTLP、Collector YAML を 1 行も書く前に、構成要素と、設定が存在する 3 つの場所を理解します。 -
Collector の設定モデル:コンポーネント、パイプライン、プロバイダー Collector の YAML のルールを学びます。命名、パイプライン、connector、ファイルのマージ、環境変数。 -
OTEL_* 環境変数で SDK を設定する 標準の変数を使って、任意の言語のサービス名、exporter、サンプリング、制限を設定します。 -
コードを変更せずにアプリを計装する:Java、Python、Node.js 環境変数とコマンドラインのフラグだけで、OpenTelemetry のエージェントをアタッチします。 -
Collector を本番対応にする:メモリ制限、バッチ処理、リトライ 過負荷や障害の間もテレメトリが生き残るように、processor、キュー、永続ストレージを設定します。 -
Helm で Kubernetes に Collector をデプロイする 公式チャートをインストールし、ログとメトリクスに preset を使い、values ファイルで設定を上書きします。 -
Collector と SDK のトラブルシューティング テレメトリが届かないときの体系的なチェックリスト:debug exporter、ヘルスチェック、内部メトリクス、よくある間違い。