はじめに: 障害時にも動作する監視システムの重要性
監視システムは、障害発生時に「何が壊れているのか」「なぜ壊れているのか」を教えてくれる役割を担います。しかし、もし監視システム自体が障害を起こしたインフラに依存していたら? ダッシュボードは真っ暗になり、アラートは届かず、障害回復ツールが障害の一部になってしまいます。
Airbnbもこの問題に直面しました。数千のサービスが共有インフラ(Kubernetes、サービスメッシュ)上で動作する環境において、メトリクスパイプラインがまさにその共有インフラに依存していたのです。すなわち、循環依存(Circular Dependency) が存在していました。
本記事では、Airbnbがこの循環依存をどのように特定し、コンピューティング/ネットワーキング/メタモニタリングの各レイヤーで断ち切ったかを詳しく解説します。
参考: 本記事はAirbnbエンジニアリングブログの内容を基に、実務適用の観点から再構成しています。

循環依存の罠: 監視が監視対象に依存するとき
Airbnbのオブザーバビリティチームが直面した問題は明確でした。メトリクスパイプラインが同一のKubernetesクラスタとサービスメッシュ(Istio)上で動作しており、これはすなわち監視対象システムがダウンすると監視も同時にダウンする構造でした。
解決策: 3つのレイヤーでの依存関係排除
1. コンピューティングレイヤー: 専用Kubernetesクラスタ
Airbnbは2つの極端な選択肢の間で妥協点を探りました。
- 共有プロダクションクラスタの利用: 運用負荷は低いが循環依存が発生
- 自前Kubernetesクラスタの運用: 完全な分離は可能だが運用オーバーヘッド大
選択した解決策: オブザーバビリティワークロードのみの専用KubernetesクラスタをCloudチームが管理する形にしました。このクラスタは他のアプリケーションと共有されませんが、運用は引き続きCloudチームが担当します。分離性と管理効率を両立させました。
# 例: オブザーバビリティ専用ノードプール構成(概念コード)
# nodeSelectorを使用してメトリクス収集Podを専用ノードでのみ実行
apiVersion: v1
kind: Pod
metadata:
name: prometheus-server
spec:
nodeSelector:
dedicated: observability
containers:
- name: prometheus
image: prom/prometheus
2. ネットワーキングレイヤー: サービスメッシュからの独立
AirbnbはIstioサービスメッシュを使用していましたが、オブザーバビリティトラフィックはビジネストラフィックと性質が全く異なっていました。
- トラフィック規模: オブザーバビリティトラフィックはビジネストラフィックの数倍から数十倍
- 優先順位: 障害時にはメトリクスが最も重要だが、サービスメッシュはビジネストラフィックに最適化
- リスク: テレメトリー急増時に共有帯域幅を消費し、ビジネストラフィックに影響
解決策: EnvoyベースのカスタムL7ネットワークイングレスレイヤーを構築しました。このプロキシはサービスメッシュから完全に独立して動作し、以下の機能を提供します。
- ヘッダーベースルーティング: 各サービス名を特定のクラスタバックエンドにマッピング
- トラフィックミラーリング: テスト目的でメトリクスを代替宛先に複製
- 粒度の細かいアクセス制御: 外部ベンダーや特殊なユースケースに対する統制が可能
// Goによるカスタムロードバランサールーティングロジック(概念コード)
// 各リクエストのTenantヘッダーに基づいて適切なバックエンドクラスタにルーティング
func routeRequest(req *http.Request) *backend.Cluster {
tenant := req.Header.Get("X-Tenant-Id")
if cluster, ok := tenantClusterMap[tenant]; ok {
return cluster
}
// デフォルトクラスタにフォールバック
return defaultCluster
}
3. メタモニタリング: 監視を監視する
最後に、監視システム自体の状態を監視するレイヤーを追加しました。
- 専用Prometheusインスタンス: オブザーバビリティスタックとは異なるアベイラビリティゾーン、異なるノードに配置
- 高可用性構成: Prometheus-Alertmanagerペアが同一インフラに配置されないよう設計
- Dead Man's Switch: 継続的にシグナルを送信するメカニズム。シグナルが途絶えると外部(CloudWatch Alarm)がオンコールを呼び出し
# Dead Man's Switchアラートルール例(概念コード)
groups:
- name: deadmansswitch
rules:
- alert: DeadMansSwitch
expr: vector(1)
labels:
severity: none
annotations:
description: "このアラートは常に発生します。シグナルが途絶えると問題が発生しています。"
これにより、「監視を監視する」無限再帰に陥ることなく、監視スタックのサイレント障害を検出できます。

日本開発エコシステムにおける適用コンテキスト
日本のSIerやスタートアップ環境でこのアーキテクチャをそのまま導入するのは難しいかもしれません。しかし、核となる原則は十分に適用可能です。
- 小規模チーム: 専用クラスタの代わりに Namespace + NodeSelector レベルの分離から始めましょう。Cloudチームがなければ、運用負荷を最小化する方向で妥協する必要があります。
- サービスメッシュ未使用環境: サービスメッシュがなければ、むしろネットワーキングレイヤーの独立性は重要度が下がります。代わりにメトリクス収集パイプライン自体のSPOF(単一障害点) を排除することに集中しましょう。
- メタモニタリング: Dead Man's SwitchはAWS CloudWatch以外にも PagerDuty、Slack Webhook などで代替可能です。重要なのは「シグナルが途絶えたときに通知が届く」メカニズムを作ることです。
この技術の限界および注意点
- 運用複雑度の増加: 専用クラスタとカスタムプロキシレイヤーは確かに運用負荷を増やします。Airbnb規模でなければオーバーエンジニアリングになる可能性があります。
- コスト: 専用インフラは追加コストを発生させます。「可用性 vs コスト」のトレードオフを明確にする必要があります。
- Dead Man's Switchの限界: 外部サービス(AWS SNS、CloudWatch)自体に障害が発生すると通知が漏れる可能性があります。完全な解決策はなく、複数のチャネルを使用することが望ましいです。
合わせて読みたい記事
- NetflixがSpinnakerからTemporalに移行しクラウドデプロイ障害率を4%から0.0001%に削減した方法
- Spotifyが数千のリポジトリにPRを自動生成する方法: Context Engineeringのすべて

まとめ: 監視は観測対象よりも信頼性が高くなければならない
Airbnbの事例が教える核心的な教訓はシンプルです。
「監視システムは自身が観測するシステムよりも高い可用性を持つべきである。」
そのために必要なことは:
- 依存関係のマッピング: 監視パイプラインがどのインフラに依存しているかを明確に把握
- 意図的な障害ドメインの分離: 共有インフラに依存しない独立した経路を確保
- メタモニタリング: 監視自体の状態を監視するメカニズムの構築
障害時にも視界を失わない監視システムは、単なる便利さではなく、ビジネスの信頼性を守るための必須要素です。皆さんの組織でも、今すぐ「監視パイプラインの循環依存」をチェックしてみてください。
次のステップとしての学習方向
- 関連技術: Prometheus Operator、Thanos、Cortex、Grafana Mimir(大規模メトリクスパイプライン)
- 概念の深堀り: Observability: The New Wave、Google SRE Book
- 実践: 自分のプロジェクトで
kubectl topとPrometheusを使ってメトリクスパイプラインの依存関係をトレースしてみましょう。