OpenTelemetry Operator を Collector と自動計装に使う
Collector と計装を Kubernetes のリソースとして宣言し、Pod のアノテーションでエージェントを注入します。
OpenTelemetry Operator は、2 つのものを Kubernetes のリソースとして管理します。Collector(OpenTelemetryCollector オブジェクト)と、自動計装(Instrumentation オブジェクトと、Operator にエージェントを注入させる Pod のアノテーション)です。アプリケーションのチームは、Dockerfile を編集するのではなく、アノテーションを追加することでテレメトリを得られ、プラットフォームチームは設定を Git の 1 か所に保てます。
Operator をインストールする
Operator は admission webhook を使うため、TLS 証明書が必要です。最も簡単な方法は、チャートがデフォルトで想定している cert-manager です。cert-manager がない場合は、Helm に自己署名証明書を生成させます。
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm install my-opentelemetry-operator open-telemetry/opentelemetry-operator \
--namespace opentelemetry-operator-system --create-namespace \
--set "manager.collectorImage.repository=otel/opentelemetry-collector-k8s" \
--set admissionWebhooks.certManager.enabled=false \
--set admissionWebhooks.autoGenerateCert.enabled=true
cert-manager がすでにインストールされている場合は、証明書の設定をデフォルトのままにするか、admissionWebhooks.certManager.issuerRef で独自の issuer を参照できます。--version でチャートのバージョンを固定し、値は --set フラグではなく、ファイルまたは Flux の HelmRelease に置きます。
Collector を宣言する
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: demo
namespace: observability
spec:
mode: deployment # deployment、daemonset、statefulset、または sidecar
replicas: 2
config:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 80
spike_limit_percentage: 20
batch: {}
exporters:
debug: {}
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [debug]
config ブロックは、これまで書いてきたのと同じ Collector の YAML で、リソースに埋め込まれています。Operator は、ワークロードと、receiver が使うポートを公開する <name>-collector という名前の Service(ここでは demo-collector)を作成します。利用可能な mode の値は、デプロイのガイドのパターンに対応しています。エージェントには daemonset、ゲートウェイには deployment、アプリケーションの Pod に注入される Collector には sidecar です。リリース間で API バージョンが変わっているため、お使いのクラスターで利用可能な CRD のバージョンを確認してください(kubectl get crd opentelemetrycollectors.opentelemetry.io)。
計装の設定を宣言する
Instrumentation リソースは、アノテーションされた Pod に Operator が注入する SDK の設定を保持します。
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: demo-instrumentation
namespace: webapp
spec:
exporter:
endpoint: http://demo-collector.observability.svc.cluster.local:4318
propagators:
- tracecontext
- baggage
sampler:
type: parentbased_traceidratio
argument: "0.25"
java:
env:
- name: OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED
value: "true"
重要な詳細:
exporter.endpointは、省略するとデフォルトでhttp://localhost:4317になり、通常は何も届きません。常に Collector の Service に設定してください。- 別の namespace の Collector には、完全な DNS 名
<service>.<namespace>.svc.cluster.localを使います。 - 文書化された例は、.NET、Go、Java、Python にはポート
4318(HTTP)、Node.js には4317(gRPC)を使っています。ポートを、言語のエージェントが使うプロトコルに合わせてください。 - 言語固有の環境変数は、
spec.java.envやspec.python.envのように、spec.<language>.envの下に置きます。
アプリケーションより先に Instrumentation を作成してください。 Operator は、Pod が作成されるときにエージェントを注入します。リソースがまだ存在しないと、Pod は init コンテナなしで起動し、再起動する必要があります。
アノテーションでワークロードをオプトインする
Deployment の Pod テンプレートにアノテーションを追加します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: checkout
namespace: webapp
spec:
selector:
matchLabels: { app: checkout }
template:
metadata:
labels: { app: checkout }
annotations:
instrumentation.opentelemetry.io/inject-java: "true"
spec:
containers:
- name: checkout
image: myorg/checkout:1.4.2
言語ごとのアノテーション:
| 言語 | アノテーション |
|---|---|
| Java | instrumentation.opentelemetry.io/inject-java: "true" |
| Python | instrumentation.opentelemetry.io/inject-python: "true" |
| Node.js | instrumentation.opentelemetry.io/inject-nodejs: "true" |
| .NET | instrumentation.opentelemetry.io/inject-dotnet: "true" |
| Go | instrumentation.opentelemetry.io/inject-go: "true"(さらに、対象の実行ファイルのアノテーション) |
| SDK の設定のみ | instrumentation.opentelemetry.io/inject-sdk: "true" |
値は、"true"(この namespace の Instrumentation を使う)、その名前("my-instrumentation")、namespace で修飾された名前("other-ns/my-instrumentation")、または "false" にできます。namespace にアノテーションを付けると、その中のすべてのワークロードが計装されます。
使用する関連のアノテーション:
instrumentation.opentelemetry.io/container-names: "app,worker"は、どのコンテナを計装するかを選びます。デフォルトでは、最初のものだけが計装されます。resource.opentelemetry.io/service.name: checkoutは、サービス名などのリソース属性を設定します。他には、service.versionやdeployment.environment.nameがあります。instrumentation.opentelemetry.io/inject-sdk: "true"は、すでに SDK を含むアプリケーション向けに、環境変数だけを注入します。- 1 つのコンテナには、複数の言語を注入することはできません。マルチコンテナ、マルチ言語の構成には、
enable-multi-instrumentationの feature flag と、言語ごとのコンテナ名のアノテーションが必要です。 - Go には、
enable-go-instrumentationの feature gate、otel-go-auto-target-exeのアノテーション(またはOTEL_GO_AUTO_TARGET_EXEの設定)、特権のあるサイドカーが必要なので、先にセキュリティへの影響を確認してください。
適用して確認する
kubectl apply -f collector.yaml -f instrumentation.yaml
kubectl apply -f checkout-deployment.yaml
kubectl get opentelemetrycollectors,instrumentations -A
kubectl get pod -n webapp -l app=checkout -o jsonpath='{.items[0].spec.initContainers[*].name}'; echo
kubectl logs -n observability deploy/demo-collector | grep -i 'service.name'
アプリケーションの Pod に opentelemetry-auto-instrumentation という名前の init コンテナがあれば、注入が機能したことを意味します。トラフィックを生成すると、Collector の debug exporter が、サービス名を持つスパンを出力するはずです。
トラブルシューティング
Instrumentationリソースはありますか。kubectl describe otelinst -n <namespace>。- Operator のエラーは? Operator の namespace の
managerコンテナのログを読みます。 - アプリケーションより先に作成しましたか。 そうでなければ、Deployment を再起動して、Pod が再作成され注入されるようにします。init コンテナについては、
kubectl get events -n <namespace>を確認します。 - アノテーションは正しいですか。
spec.template.metadata.annotationsにある必要があり、言語がアプリケーションと一致している必要があります。 - エンドポイントは正しいですか。 間違ったプロトコルやポート、あるいは namespace をまたぐ短い Service 名では、黙って何も送られません。
Operator を優先する場合
多くのチームがクラスターにデプロイしており、設定を中央で管理しつつ、アノテーションでテレメトリをオプトインにしたい場合に使います。Collector だけが必要で、SDK の設定を各アプリケーション自身のマニフェストで処理する場合は、シンプルな Helm チャートを使います。Operator とチャートは共存できますが、同じ Collector を両方で管理しないでください。
人気のガイド
-
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、ヘルスチェック、内部メトリクス、よくある間違い。