Skip to content

課題19: 配車サービスの統合監視基盤構築

難易度: 🟡 中級


1. 分類情報

項目内容
難易度中級
カテゴリオブザーバビリティ・監視
処理タイプリアルタイム
使用IaCCloudFormation
想定所要時間4-5時間

2. ビジネスシナリオ

企業プロファイル

  • 企業名: 〇〇株式会社
  • 業種: モビリティ・配車サービス
  • 規模: 従業員200名、エンジニア40名
  • サービス規模: 月間配車100万件、15個のマイクロサービス
  • 現状インフラ: AWS上でEKS + マイクロサービスアーキテクチャ

現状の課題

〇〇株式会社は、急成長する配車サービスを15個のマイクロサービスで構成しています。しかし、システムの複雑化に伴い、以下の問題が深刻化しています:

  1. 障害検知の遅延

    • ユーザーからの問い合わせで障害に気づくことが多い
    • どのサービスが原因か特定に時間がかかる
    • 夜間・休日の検知が特に遅い
  2. トラブルシュートの困難さ

    • 分散トレーシングがなく、リクエストの流れが追えない
    • ログが各サービスに分散し、相関分析ができない
    • パフォーマンス問題のボトルネック特定が困難
  3. 監視の属人化

    • 各チームが独自の監視ツールを使用
    • アラートルールが統一されていない
    • SLI/SLO が定義されていない

ビジネス要件

機能要件:
- 全マイクロサービスのメトリクス統合監視
- 分散トレーシングによるリクエスト追跡
- 統合ログ管理と検索
- SLI/SLO ダッシュボードの構築

非機能要件:
- 障害検知から通知まで1分以内
- メトリクス保持期間:15ヶ月
- ログ検索レスポンス:5秒以内
- ダッシュボードリフレッシュ:10秒間隔

成功指標(KPI)

指標現状目標
平均検知時間(MTTD)30分1分
平均復旧時間(MTTR)2時間15分
障害原因特定時間45分5分
SLO 達成率測定なし99.9%
アラート精度(真陽性率)40%90%

3. 学習目標

本課題で習得するスキル

1. メトリクス監視(理解度:詳細)
   - CloudWatch メトリクス・アラーム設定
   - Amazon Managed Prometheus(AMP)
   - カスタムメトリクスの設計

2. 分散トレーシング(理解度:実装)
   - AWS X-Ray によるトレース収集
   - サービスマップの活用
   - パフォーマンス分析

3. 統合ダッシュボード(理解度:実装)
   - Amazon Managed Grafana(AMG)
   - CloudWatch ダッシュボード
   - SLI/SLO 可視化

4. ログ管理(理解度:基礎)
   - CloudWatch Logs Insights
   - ログの構造化と相関付け

GCPエンジニア向け補足

GCP → AWS マッピング:
- Cloud Monitoring → CloudWatch
- Cloud Trace → X-Ray
- Cloud Logging → CloudWatch Logs
- Google Cloud Managed Prometheus → Amazon Managed Prometheus
- (Grafana Cloud) → Amazon Managed Grafana

主な違い:
1. CloudWatch: メトリクス・ログ・トレースの統合サービス
   (GCPは3つの別サービス)

2. X-Ray: AWS サービスとの深い統合
   (Lambda, API Gateway, ECS などの自動計装)

3. AMP/AMG: オープンソース互換のマネージドサービス
   (既存の Prometheus/Grafana 資産を活用可能)

4. Container Insights: EKS/ECS の包括的な監視
   (GKE のモニタリングに相当)

4. 使用するAWSサービス

メインサービス

サービス役割使用機能
Amazon CloudWatchメトリクス・ログ監視Metrics, Alarms, Logs Insights, Container Insights
AWS X-Ray分散トレーシングトレース収集、サービスマップ、分析
Amazon Managed Grafanaダッシュボード可視化、アラート、データソース統合
Amazon Managed Prometheusメトリクス収集Prometheus互換メトリクス

サポートサービス

サービス用途
Amazon EKSマイクロサービス実行基盤
AWS Distro for OpenTelemetryテレメトリ収集
Amazon SNSアラート通知
AWS Lambdaアラートアクション
Amazon S3ログアーカイブ

アーキテクチャ図


5. 前提条件と事前準備

必要な環境

bash
# AWS CLI v2
aws --version  # 2.x以上

# kubectl
kubectl version --client

# Helm
helm version  # 3.x以上

# eksctl
eksctl version

# jq
jq --version

AWSアカウント要件

- EKS クラスターが作成済み、または作成可能
- IAM 権限:EKS管理、CloudWatch管理、Prometheus管理、Grafana管理
- SSO/IAM Identity Center(Grafana認証用、オプション)

事前準備スクリプト

bash
#!/bin/bash
# setup-observability-baseline.sh

# 変数設定
CLUSTER_NAME="rideshare-cluster"
REGION="ap-northeast-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

# ディレクトリ構造の作成
mkdir -p rideshare-observability/{kubernetes,grafana,alerting,sample-app}
cd rideshare-observability

# EKS クラスターの確認(存在しない場合は作成)
echo "=== Checking EKS Cluster ==="
if ! eksctl get cluster --name $CLUSTER_NAME --region $REGION 2>/dev/null; then
    echo "Creating EKS cluster..."
    cat > cluster-config.yaml << EOF
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: ${CLUSTER_NAME}
  region: ${REGION}

managedNodeGroups:
  - name: ng-1
    instanceType: t3.medium
    desiredCapacity: 3
    minSize: 2
    maxSize: 5
    iam:
      withAddonPolicies:
        cloudWatch: true
        xRay: true

cloudWatch:
  clusterLogging:
    enableTypes: ["api", "audit", "authenticator", "controllerManager", "scheduler"]

iam:
  withOIDC: true
EOF
    eksctl create cluster -f cluster-config.yaml
fi

# kubeconfig の更新
aws eks update-kubeconfig --name $CLUSTER_NAME --region $REGION

# 現在のコンテキスト確認
kubectl config current-context
kubectl get nodes

6. アーキテクチャ設計

監視設計(Three Pillars of Observability)

yaml
# observability-design.yaml
observability:
  metrics:
    sources:
      - cloudwatch_container_insights  # インフラメトリクス
      - prometheus_scraping            # アプリケーションメトリクス
      - custom_metrics                 # ビジネスメトリクス
    storage:
      - amazon_managed_prometheus      # 長期保存(13ヶ月)
      - cloudwatch_metrics             # AWS統合メトリクス
    key_metrics:
      # RED メトリクス(サービス)
      - request_rate          # リクエストレート
      - error_rate            # エラー率
      - duration              # レイテンシ
      # USE メトリクス(リソース)
      - utilization           # CPU/Memory使用率
      - saturation            # キュー長/スレッドプール
      - errors                # リソースエラー

  traces:
    collector: aws_xray
    sampling:
      default: 0.05           # 5% サンプリング
      errors: 1.0             # エラーは100%収集
      slow_requests: 1.0      # 遅いリクエストは100%収集
    correlation:
      - trace_id → logs
      - trace_id → metrics

  logs:
    collector: fluent_bit
    storage: cloudwatch_logs
    structure:
      format: json
      fields:
        - timestamp
        - level
        - service
        - trace_id
        - span_id
        - message
        - metadata
    retention:
      hot: 7_days
      warm: 30_days
      cold: 365_days

SLI/SLO 定義

yaml
# sli-slo-definitions.yaml
services:
  rider_service:
    slis:
      availability:
        description: "サービスが正常にリクエストを処理できる割合"
        metric: "sum(rate(http_requests_total{status!~'5..'}[5m])) / sum(rate(http_requests_total[5m]))"
        unit: percentage
      latency:
        description: "リクエストのP99レイテンシ"
        metric: "histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))"
        unit: seconds
      error_rate:
        description: "エラーリクエストの割合"
        metric: "sum(rate(http_requests_total{status=~'5..'}[5m])) / sum(rate(http_requests_total[5m]))"
        unit: percentage
    slos:
      availability:
        target: 99.9%
        window: 30d
        budget: 43.2min  # 月間ダウンタイム許容
      latency_p99:
        target: 500ms
        window: 30d
      error_rate:
        target: 0.1%
        window: 30d

  matching_service:
    slis:
      availability:
        metric: "..."
      latency:
        metric: "..."
      match_success_rate:
        description: "配車マッチング成功率"
        metric: "sum(rate(matching_success_total[5m])) / sum(rate(matching_attempts_total[5m]))"
    slos:
      availability:
        target: 99.95%
      latency_p99:
        target: 200ms
      match_success_rate:
        target: 95%

7. トラブルシューティング課題

課題1: Prometheus メトリクスが AMP に書き込まれない

症状:

Grafana で AMP をデータソースとして設定したが、
メトリクスが表示されない。Prometheus Pod のログには
"remote_write" 関連のエラーが出ている。

調査コマンド:

bash
# Prometheus Pod のログ確認
kubectl logs -n prometheus deployment/prometheus-server | grep -i "remote"

# Service Account の確認
kubectl get sa prometheus-server -n prometheus -o yaml

# IAM ロールの確認
aws iam get-role --role-name amp-prometheus-role

原因と解決:

解答を見る

原因: IRSA(IAM Roles for Service Accounts)の設定が正しくない

解決手順:

bash
# 1. OIDC プロバイダーの確認
aws eks describe-cluster --name rideshare-cluster \
    --query "cluster.identity.oidc.issuer" --output text

# 2. OIDC プロバイダーが IAM に登録されているか確認
aws iam list-open-id-connect-providers

# 3. OIDC プロバイダーが未登録の場合、登録
eksctl utils associate-iam-oidc-provider \
    --cluster rideshare-cluster \
    --approve

# 4. Service Account のアノテーション確認
kubectl get sa prometheus-server -n prometheus -o yaml | grep -A 5 annotations

# 5. アノテーションが不足している場合、更新
kubectl annotate sa prometheus-server -n prometheus \
    eks.amazonaws.com/role-arn=arn:aws:iam::ACCOUNT_ID:role/amp-prometheus-role \
    --overwrite

# 6. Prometheus Pod を再起動
kubectl rollout restart deployment prometheus-server -n prometheus

# 7. Pod が新しい認証情報を取得したか確認
kubectl exec -n prometheus deployment/prometheus-server -- \
    cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token | cut -d '.' -f 2 | base64 -d

追加確認事項:

  • IAM ロールの信頼ポリシーで OIDC の subject が正しいか
  • AMP ワークスペースが正しいリージョンにあるか
  • remote_write の URL が正しいか

課題2: X-Ray トレースが表示されない

症状:

アプリケーションで X-Ray SDK を使用しているが、
X-Ray コンソールにトレースが表示されない。
サービスマップも空のまま。

調査コマンド:

bash
# X-Ray Daemon Pod の状態確認
kubectl get pods -l app=xray-daemon

# X-Ray Daemon のログ確認
kubectl logs daemonset/xray-daemon

# アプリケーション Pod からの接続確認
kubectl exec -it deployment/rider-service -- \
    nc -vz xray-service.default 2000

原因と解決:

解答を見る

原因: 複数の原因が考えられる

パターン1: X-Ray Daemon への接続失敗

bash
# アプリケーションの環境変数確認
kubectl get deployment rider-service -o yaml | grep -A 5 AWS_XRAY

# 環境変数が設定されていない場合
kubectl set env deployment/rider-service \
    AWS_XRAY_DAEMON_ADDRESS=xray-service.default:2000

パターン2: IAM 権限不足

bash
# Service Account の IAM ロール確認
kubectl get sa xray-daemon -o yaml

# 必要な権限があるか確認
aws iam simulate-principal-policy \
    --policy-source-arn arn:aws:iam::ACCOUNT_ID:role/xray-daemon-role \
    --action-names xray:PutTraceSegments xray:PutTelemetryRecords

パターン3: サンプリングルールの問題

bash
# デフォルトサンプリングルールの確認
aws xray get-sampling-rules

# サンプリングレートが低すぎる場合、調整
aws xray update-sampling-rule --sampling-rule-update '{
    "RuleName": "Default",
    "FixedRate": 0.1,
    "ReservoirSize": 10
}'

パターン4: アプリケーションコードの問題

python
# X-Ray SDK の初期化を確認
from aws_xray_sdk.core import xray_recorder

# 明示的にサービス名を設定
xray_recorder.configure(
    service='rider-service',
    sampling=False,  # デバッグ時は全トレース収集
    daemon_address='xray-service.default:2000'
)

課題3: Grafana アラートが発火しない

症状:

SLO 違反が発生しているはずなのに、Grafana のアラートが
発火しない。ダッシュボードではメトリクスが正常に表示されている。

調査手順:

bash
# Grafana のアラート状態確認(API経由)
curl -H "Authorization: Bearer $GRAFANA_API_KEY" \
    "https://your-grafana.grafana.net/api/v1/alerts"

# アラートルールの確認
curl -H "Authorization: Bearer $GRAFANA_API_KEY" \
    "https://your-grafana.grafana.net/api/v1/provisioning/alert-rules"

原因と解決:

解答を見る

原因: アラートルールの評価設定の問題

確認・解決手順:

  1. アラートルールの for 期間を確認
yaml
# for が長すぎる場合、アラートが発火しにくい
for: 2m  # 2分間継続して条件を満たす必要がある
  1. データソースの設定確認
yaml
# データソース UID が正しいか確認
datasourceUid: prometheus  # 実際のデータソース UID と一致しているか
  1. 評価間隔の確認
yaml
# interval が長すぎるとアラートの遅延が発生
interval: 1m  # 1分間隔で評価
  1. クエリの検証
bash
# Grafana の Explore で直接クエリを実行して結果を確認
# アラート条件と同じクエリを実行
sum(rate(http_requests_total{status!~'5..'}[5m])) / sum(rate(http_requests_total[5m])) * 100
  1. 通知チャネルの確認
yaml
# Contact Point が正しく設定されているか
# Slack/PagerDuty の Webhook URL が有効か
  1. Grafana Alerting のデバッグログ有効化
bash
# AMG ではログレベルの変更はサポートされていないため、
# CloudWatch Logs で Grafana のログを確認
aws logs filter-log-events \
    --log-group-name "/aws/grafana/rideshare-dashboard" \
    --filter-pattern "alert"

8. 設計課題

設計課題: 大規模マイクロサービスのオブザーバビリティ戦略

シナリオ: 配車サービス社は事業拡大に伴い、マイクロサービスが15個から50個に増加する計画です。 以下の要件を満たすオブザーバビリティ戦略を設計してください。

要件:

1. サービス規模
   - マイクロサービス:50個
   - 月間リクエスト:10億件
   - 開発チーム:15チーム

2. 機能要件
   - 全サービスの統合監視
   - チーム単位でのダッシュボード分離
   - サービス間依存関係の可視化
   - カスタムビジネスメトリクス対応

3. 非機能要件
   - メトリクス保持:13ヶ月(コンプライアンス要件)
   - ログ検索:リアルタイム〜30日前
   - アラート遅延:1分以内
   - コスト効率:現状の2倍以内

設計すべき項目:

1. メトリクス収集・保存戦略
2. トレーシング戦略(サンプリング設計)
3. ログ管理戦略(保持・検索)
4. ダッシュボード・アラート設計
5. チーム間の責任分界
設計例を見る

大規模オブザーバビリティアーキテクチャ

コンポーネント役割
Rider/Driver/Payment Teamマイクロサービス群
OTel CollectorOpenTelemetry Collector(Gateway Pattern)
Sampling/Filteringデータの抽出・フィルタリング
X-Ray Traces分散トレース(Head 5%, Tail 100%)
AMP MetricsPrometheus メトリクス(13ヶ月保持)
CloudWatch Logsログ管理(Hot/Warm/Cold階層)
Managed Grafana可視化・ダッシュボード
Platform/Team/Business Dashチーム別ダッシュボード
PagerDuty/Slackアラート通知先

1. メトリクス収集・保存戦略

yaml
metrics_strategy:
  collection:
    method: pull  # Prometheus スタイル
    interval: 15s
    timeout: 10s

  labeling_guidelines:
    required_labels:
      - service    # サービス名
      - team       # 担当チーム
      - env        # 環境
    cardinality_control:
      # 高カーディナリティラベルの制限
      forbidden_labels:
        - user_id
        - request_id
        - trace_id
      max_label_values: 1000

  storage:
    primary: amazon_managed_prometheus
    retention: 13_months
    estimated_series: 80000  # 50サービス × 1600シリーズ/サービス

  aggregation:
    # 長期保存用に集約
    raw_retention: 15_days
    5m_aggregation: 90_days
    1h_aggregation: 13_months

2. トレーシング戦略

yaml
tracing_strategy:
  sampling:
    head_based:
      default_rate: 0.05  # 5%
      rules:
        - service: payment-*
          rate: 0.1  # 決済は10%
        - service: matching-*
          rate: 0.1  # マッチングは10%

    tail_based:
      enabled: true
      policies:
        - type: always_sample
          conditions:
            - status_code >= 500
            - latency > 2s
        - type: probabilistic
          rate: 0.5
          conditions:
            - latency > 500ms

  storage:
    service: aws_xray
    retention: 30_days
    groups:
      - name: errors
        filter: "fault = true"
      - name: slow_requests
        filter: "responsetime > 1"

  service_map:
    refresh_interval: 1m
    depth: 5  # 依存関係の深さ

3. ログ管理戦略

yaml
log_strategy:
  structure:
    format: json
    required_fields:
      - timestamp
      - level
      - service
      - team
      - trace_id
      - message
    optional_fields:
      - user_id  # マスキング必須
      - request_path

  storage:
    primary: cloudwatch_logs
    log_groups:
      pattern: /rideshare/{team}/{service}
    retention_policy:
      hot: 7_days     # CloudWatch Logs
      warm: 30_days   # CloudWatch Logs (Infrequent Access)
      cold: 365_days  # S3 Glacier

  export:
    destination: s3
    format: parquet  # Athena でクエリ可能
    schedule: daily
    bucket: rideshare-logs-archive

  search:
    tool: cloudwatch_logs_insights
    max_scan_range: 30_days
    query_timeout: 30s

4. チーム責任分界

yaml
responsibility_matrix:
  platform_sre:
    owns:
      - 全体 SLO ダッシュボード
      - インフラメトリクス
      - 共通アラートルール
      - オンコールエスカレーション
    maintains:
      - AMP/AMG インフラ
      - OpenTelemetry Collector
      - 共通ライブラリ

  application_teams:
    owns:
      - チームダッシュボード
      - サービス固有アラート
      - ビジネスメトリクス定義
      - トラブルシューティング
    maintains:
      - アプリケーション計装
      - ログ出力

  access_control:
    grafana:
      - role: Viewer (全社員)
      - role: Editor (チームメンバー) - チームフォルダのみ
      - role: Admin (SRE)

推定コスト

サービス使用量月額コスト
AMP80K series, 13M samples/month$800
AMG1 workspace, 50 users$250
CloudWatch Logs500GB/month$250
CloudWatch MetricsContainer Insights$150
X-Ray10M traces/month$50
S3 (ログアーカイブ)1TB$25
合計$1,525/月

9. 発展課題

発展課題1: OpenTelemetry への移行(難易度:中級)

課題内容: 現在の X-Ray SDK から OpenTelemetry に移行し、ベンダーロックインを回避しつつ 同等以上のオブザーバビリティを実現してください。

要件:

  • 既存の X-Ray トレースとの互換性維持
  • メトリクス・ログ・トレースの統合収集
  • Kubernetes 環境での自動計装
yaml
# ヒント: AWS Distro for OpenTelemetry の設定
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: adot-collector
spec:
  mode: deployment
  config: |
    receivers:
      otlp:
        protocols:
          grpc:
            endpoint: 0.0.0.0:4317
          http:
            endpoint: 0.0.0.0:4318

    processors:
      batch:
        timeout: 1s
        send_batch_size: 50

    exporters:
      awsxray:
        region: ap-northeast-1
      awsprometheusremotewrite:
        endpoint: https://aps-workspaces.ap-northeast-1.amazonaws.com/...
      awscloudwatchlogs:
        log_group_name: /rideshare/otel

    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [batch]
          exporters: [awsxray]
        metrics:
          receivers: [otlp]
          processors: [batch]
          exporters: [awsprometheusremotewrite]

発展課題2: AIOps の導入(難易度:上級)

課題内容: Amazon DevOps Guru を導入し、ML ベースの異常検知と インシデント予測を実現してください。

要件:

  • CloudWatch メトリクスの異常検知
  • インシデントの自動分類と優先度付け
  • 推奨アクションの自動生成

発展課題3: カオスエンジニアリング統合(難易度:上級)

課題内容: AWS Fault Injection Simulator を使用して、 オブザーバビリティ基盤の有効性を検証するカオス実験を設計・実行してください。

要件:

  • サービス障害時の検知時間測定
  • アラート精度の検証
  • ダッシュボードの有用性評価

10. 学習のポイント

学習のまとめ

本課題で学んだこと:
□ CloudWatch Container Insights による EKS 監視
□ AWS X-Ray による分散トレーシング
□ Amazon Managed Prometheus/Grafana の設定
□ SLI/SLO の設計と可視化
□ アラート設計のベストプラクティス
□ 構造化ログと相関分析

GCP との主な違い:
- CloudWatch は統合サービス(メトリクス・ログ・トレース)
- X-Ray は AWS サービスとの深い統合
- AMP/AMG はオープンソース互換のマネージドサービス
- Container Insights は EKS 専用の包括的監視

GCP経験者向けポイント

観点GCPAWS移行時の注意
メトリクス監視Cloud MonitoringCloudWatch Metricsメトリクス名・ラベル命名規則が異なる
分散トレーシングCloud TraceX-Rayトレースフォーマットが異なる(W3C vs X-Ray)
ログ管理Cloud LoggingCloudWatch Logsクエリ言語が異なる(LogQL vs Insights)
PrometheusManaged PrometheusAMPほぼ同等、remote_write 設定のみ異なる
Grafana(Grafana Cloud)AMGデータソース設定が異なる

推奨される次のステップ

1. AWS Certified DevOps Engineer の学習
   - オブザーバビリティの深い理解
   - CI/CD との統合

2. OpenTelemetry の習得
   - ベンダー中立なテレメトリ
   - 将来性のある技術スタック

3. SRE プラクティスの導入
   - SLO ベースのアラート設計
   - エラーバジェットの運用

4. 関連課題への挑戦
   - 課題27: セキュリティ監視
   - 課題29: コスト最適化

11. 想定コストと削減方法

本課題の推定コスト

サービス使用量推定コスト(演習時)
EKS1クラスター、3ノード$75
CloudWatchContainer Insights$5-10
X-Ray10万トレース$5
AMP1万シリーズ$5-10
AMG1ワークスペース$9
合計$100-110

コスト最適化のヒント

1. EKS のコスト削減
   - Spot インスタンスの活用
   - 演習後はクラスター削除

2. CloudWatch のコスト削減
   - 不要なメトリクスの除外
   - ログ保持期間の短縮

3. X-Ray のコスト削減
   - サンプリングレートの調整
   - 不要なサービスの除外

4. AMP のコスト削減
   - カーディナリティの管理
   - 不要なメトリクスの除外

注意事項

⚠️ EKS クラスター
- クラスターは課金が継続するため、演習後は削除を推奨
- eksctl delete cluster コマンドで削除可能

⚠️ マネージドサービス
- AMP/AMG は有効化すると課金開始
- 使用しない場合はワークスペースを削除

⚠️ データ保持
- 本番環境でのログ・メトリクス保持期間は要件に応じて設定
- コンプライアンス要件がある場合は適切な保持期間を設定