By Grace Park, DevOps Engineer, STCLab SRE Team
課題
STCLab では、NetFUNNEL と BotManager という 2 つのプラットフォームを運用しています。
これらは、フラッシュセールやグローバル投票といった高負荷イベントにおいて、
200 か国以上・最大 350 万同時接続を処理する大規模なシステムです。
2023 年、私たちは 20 年以上運用してきたオンプレミス基盤を段階的に終了し、
NetFUNNEL 4.x を Kubernetes ネイティブなグローバル SaaS として、ゼロから再設計する決断をしました。
当時の課題は、単なるコストではありませんでした。
開発・検証環境では APM を完全に無効化せざるを得ず、
本番環境でも 5% 程度のトレースサンプリング に制限されていました。
その結果、パフォーマンス劣化は本番リリース後に初めて発覚するという、
いわゆる「事後対応型」の運用に陥っていました。
すべての環境を妥協なく、かつコスト効率よくモニタリングできる仕組みが必要でした。
移行の成果
OpenTelemetry による計装と、CNCF ネイティブな LGTM スタック(Loki / Grafana / Tempo / Mimir)への移行により、以下を実現しました。
-
旧ベンダー比で 72% のコスト削減
-
全環境で 100% の APM トレースカバレッジ
-
複数 Kubernetes クラスタを横断した統合 Observability
-
CNCF 支援のオープン標準に統一することで vendor lock-in を解消
本記事では、この移行プロジェクトの進め方、直面した技術的課題、
チューニング戦略、実際に有効だった構成を詳しく紹介します。
Observability アーキテクチャ概要
主要なアーキテクチャ設計判断
1. Centralized Backend と Distributed Collectors
すべてのクラスタに LGTM を展開するのではなく、
マルチテナンシーを活用して単一の管理クラスタにテレメトリーを集約しました。
実装内容
-
各クラスタには軽量な OTel Collector のみを配置
-
X-Scope-OrgIDヘッダーで tenant ID を付与(例:scp-dev,scp-prod) -
中央バックエンド(Mimir Loki Tempo)が tenant 単位でデータを分離
-
tenant ごとのレート制限で noisy neighbor 問題を防止
重要な効果として、開発環境のメトリクス急増が本番環境に影響することはありません。
2. OpenTelemetry をユニバーサルな受信レイヤーとして採用
OTel Collector はマルチテナンシー対応、バッチ処理、バッファリング、リトライ、
tail sampling を一括で担います。
Java と Node.js ワークロードでは auto instrumentation を活用し、
アプリケーションコードを変更せずにフル APM を実現しました。
最大の利点は、バックエンドを完全に疎結合にできる点です。
Tempo から Jaeger へ移行する場合も、設定変更は 1 行のみで、アプリ修正は不要です。
主要な設定パターン
マルチテナンシー注入(クラスタ単位 Collector)
exporters:
otlphttp/tempo:
headers:
X-Scope-OrgID: "scp-dev" # Unique ID for this environment
retry_on_failure:
enabled: true
sending_queue:
enabled: true
tenant ごとの制限設定(中央 Mimir)
runtimeConfig:
overrides:
scp-dev:
max_global_series_per_user: 1000000
ingestion_rate: 10000
Processor の実行順序
-
memory_limiterを最初に実行 -
Enrichment(
k8sattributes,resource) -
Filtering transformation(
filter,transform) -
batchを最後に実行
実運用で直面した主な課題
1. メトリクス数が 40 倍に膨張
DaemonSet で Collector を展開したことで、
14 ノード構成のクラスタでは Kubelet メトリクスが 14 回収集される状況になりました。
Target Allocator を per-node 戦略で有効化することで解決しました。
opentelemetryCollector:
mode: daemonset
targetAllocator:
enabled: true
allocationStrategy: per-node
ターゲット割当戦略
StatefulSet with consistent-hashing

監視すべき指標
-
otelcol_receiver_refused_metric_points_total:Non-zero = データ損失 -
opentelemetry_allocator_targets_per_collector:per-node モードでは、ノードごとのポッド数の違いにより、分布が不均一になることが想定されます
2. バージョン不整合
Operator Collector Target Allocator のバージョンが一致していないと
Prometheus スクレイピングが失敗します。
結論として、すべてのコンポーネントのバージョンを統一しました。
2025-06-27T05:31:27.578Z error error creating new scrape pool {"resource": {"service.instance.id": "bfa11ae0-f6ad-4d5b-97e8-088b8cd0a7f4", "service.name": "otelcol-contrib", "service.version": "0.128.0"}, "otelcol.component.id": "prometheus", "otelcol.component.kind": "receiver", "otelcol.signal": "metrics", "err": "invalid metric name escaping scheme, got empty string instead of escaping scheme", "scrape_pool": "otel-collector"}
根本原因: Prometheus のバージョン間で依存関係に破壊的変更(Breaking Change)が発生していたため。
-
v0.127.0:新しいエスケープ方式の設定を認識していなかったか、正しく実装されていません。
-
v0.128.0:新しい Prometheus 依存関係に基づいて構築され、エスケープ スキームの検証が強化され、古いスタイルの設定を受信したときに Prometheus 受信側が失敗する原因となりました。
ソリューション: すべてのコンポーネントバージョンを明示的に統合します:
opentelemetry-operator:
manager:
image:
repository: "otel/opentelemetry-operator"
tag: "0.131.0"
collectorImage:
repository: "otel/opentelemetry-collector-contrib"
tag: "0.131.0"
targetAllocatorImage:
repository: "otel/target-allocator"
tag: "0.131.0"
レッスン: Operator、Collector、および Target Allocator を常に一緒にバージョンロックします。
3. 小規模ノードでの OOM
2GB ノードでは、memory_limiter を設定しているにもかかわらず、Collector が OOM (Out Of Memory) を起こし、ノード全体がハングする事象が発生しました。
根本原因: グレースフルシャットダウンに必要なメモリヘッドルームが不足

ソリューション:nodeAffinityにより、小規模ノードへの配置を防止
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: karpenter.k8s.aws/instance-size
operator: NotIn
values:
- medium
- matchExpressions:
- key: karpenter.k8s.aws/instance-memory
operator: NotIn
values:
- "2048"
レッスン: Collector は 最低でも 4GB のメモリを持つノードにのみ配置すべきです。
結論
当初、この規模で OTel Collector を本番運用している事例は多くありませんでした。
私たちはオープンソースコミュニティに多くを学び、
同じ課題に直面するチームの参考になればと考えています。
今後の記事では、
-
マルチテナンシー実装の詳細
-
Grafana ダッシュボード設計
-
Span Metrics を活用したアラート戦略
-
本番環境でのトラブルシューティング
について紹介する予定です。
About STCLab
STCLab は、高負荷オンラインイベントにおけるトラフィック制御を専門とするソフトウェア企業です。
NetFUNNEL(Virtual Waiting Room)や BotManager(bot mitigation)などのプロダクトを提供しています。

