クラウドソリューションの運用管理 — SRE・監視・ロギング・障害対応を詳細解説
クラウドソリューションの正常なオペレーションの確保(≈ 22%)
Site Reliability Engineering の基本概念と SLI/SLO/SLA の関係
【SRE の核心概念】
SLI(Service Level Indicator)= 測定値
例: 「過去 30 日間のリクエスト成功率は 99.95% だった」
SLO(Service Level Objective)= 目標
例: 「リクエスト成功率を 99.9% 以上に保つ」
SLA(Service Level Agreement)= 契約
例: 「99.9% を下回った場合、料金を返金する」
エラーバジェット(Error Budget)= 許容できる失敗量
例: SLO が 99.9% なら
エラーバジェット = 0.1% = 月間約 43.8 分のダウンタイム許容VM の状態管理・基本操作・スタートアップスクリプト・デバッグ
# ===== VM の起動・停止・再起動 ===== # VM を停止(ディスクデータ保持・課金一部停止) gcloud compute instances stop VM_NAME \ --zone=asia-northeast1-a # VM を起動 gcloud compute instances start VM_NAME \ --zone=asia-northeast1-a # VM を再起動 gcloud compute instances reset VM_NAME \ --zone=asia-northeast1-a # VM を一時停止(メモリ状態保持) gcloud compute instances suspend VM_NAME \ --zone=asia-northeast1-a # ===== VM の情報確認 ===== # VM の一覧表示 gcloud compute instances list # 特定プロジェクトの全リージョンの VM を表示 gcloud compute instances list --project=PROJECT_ID # VM の詳細情報 gcloud compute instances describe VM_NAME \ --zone=asia-northeast1-a \ --format=json # ===== VM の設定変更 ===== # VM のマシンタイプを変更(停止中のみ可能) gcloud compute instances set-machine-type VM_NAME \ --machine-type=n2-standard-8 \ --zone=asia-northeast1-a # VM にラベルを追加 gcloud compute instances add-labels VM_NAME \ --labels=env=production,team=backend \ --zone=asia-northeast1-a # VM のメタデータを更新 gcloud compute instances add-metadata VM_NAME \ --metadata=startup-script-url=gs://my-bucket/startup.sh \ --zone=asia-northeast1-a
# スタートアップスクリプト(VM 起動時に実行) #!/bin/bash # startup.sh apt-get update -y apt-get install -y nginx systemctl start nginx systemctl enable nginx echo "Startup complete: $(date)" >> /var/log/startup.log # スタートアップスクリプトを VM に設定 gcloud compute instances create VM_NAME \ --metadata-from-file startup-script=startup.sh \ --zone=asia-northeast1-a # GCS からスタートアップスクリプトを読み込む gcloud compute instances create VM_NAME \ --metadata=startup-script-url=gs://my-bucket/startup.sh \ --zone=asia-northeast1-a
# シャットダウンスクリプト(VM 停止前に実行、最大 90 秒) #!/bin/bash # shutdown.sh echo "Shutdown initiated: $(date)" >> /var/log/shutdown.log # 処理中のデータをバックアップ gsutil cp /var/app/data/*.json gs://my-backup-bucket/$(date +%Y%m%d%H%M%S)/ # アプリを graceful に停止 systemctl stop my-app echo "Shutdown complete: $(date)" >> /var/log/shutdown.log
SSH でアクセスできない障害時のデバッグ手段。OS ブート中の問題やネットワーク障害時に活用します。
# シリアルコンソールへのアクセスを有効化 gcloud compute instances add-metadata VM_NAME \ --metadata=serial-port-enable=TRUE \ --zone=asia-northeast1-a # シリアルコンソールに接続 gcloud compute connect-to-serial-port VM_NAME \ --zone=asia-northeast1-a # シリアルポートのログを確認(最後の 100 行) gcloud compute instances get-serial-port-output VM_NAME \ --zone=asia-northeast1-a \ --port=1 \ --start=0 | tail -100
パブリック IP を持たない VM へのセキュアなアクセス手段。IAM 権限(roles/iap.tunnelResourceAccessor)を確認してトンネルを構築します。
# IAP トンネル経由で SSH(VM にパブリック IP 不要) gcloud compute ssh VM_NAME \ --tunnel-through-iap \ --zone=asia-northeast1-a # IAP トンネルの権限を付与 gcloud projects add-iam-policy-binding PROJECT_ID \ --member="user:alice@example.com" \ --role="roles/iap.tunnelResourceAccessor"
増分バックアップ・整合性レベル・スケジュール・復元・コスト管理
【スナップショットの仕組み】
時刻 T1: スナップショット A(完全バックアップ)
↓ 差分データだけ保存
時刻 T2: スナップショット B(増分バックアップ)
↓ さらに差分データだけ保存
時刻 T3: スナップショット C(増分バックアップ)
【増分バックアップの特徴】
✓ 初回以降は差分のみ → ストレージコストが少ない
✓ どのスナップショットからでも完全復元が可能
✓ 古いスナップショットを削除しても
依存する新しいスナップショットは引き続き有効【クラッシュ整合性スナップショット(Crash-Consistent)】 アプリを停止せず、そのままスナップショットを取得 メリット: ✓ アプリを停止する必要がない(無停止で取得) ✓ 取得が素早い デメリット: ✗ メモリ上のデータ(未書き込みバッファ)はキャプチャされない ✗ 復元後、OS がクラッシュ後の起動と同じプロセスを実行する 適切なユースケース: ├── OS ディスク(Linux / Windows ともに対応) └── ステートレスなアプリのディスク
【アプリケーション整合性スナップショット(Application-Consistent)】 1. アプリに「書き込みを一時停止して」と指示(Freeze) 2. メモリ上のデータをディスクにフラッシュ 3. スナップショットを取得 4. アプリの書き込みを再開(Thaw) メリット: ✓ メモリ上のデータも含めた完全な整合性 ✓ 復元後のデータ整合性が保証される デメリット: ✗ アプリ側のサポートが必要(VSS、fsfreeze など) ✗ 取得中に書き込み I/O が一時停止される 適切なユースケース: ├── データベース(MySQL、PostgreSQL など) └── トランザクション処理をしているアプリ
# 基本的なスナップショット取得(手動) gcloud compute disks snapshot DISK_NAME \ --snapshot-names=my-snapshot-$(date +%Y%m%d%H%M%S) \ --zone=asia-northeast1-a \ --description="Manual backup before maintenance" # 別リージョンに保存(DR 対策) gcloud compute disks snapshot DISK_NAME \ --snapshot-names=my-snapshot-cross-region \ --zone=asia-northeast1-a \ --storage-location=us-central1 # 複数ディスクを同時にスナップショット gcloud compute disks snapshot DISK1 DISK2 DISK3 \ --zone=asia-northeast1-a
# ===== スナップショットスケジュール(定期自動取得)===== # 1時間ごとのスナップショットスケジュールを作成 gcloud compute resource-policies create snapshot-schedule hourly-backup \ --region=asia-northeast1 \ --max-retention-days=7 \ --start-time=00:00 \ --hourly-schedule=1 \ --on-source-disk-delete=keep-auto-snapshots # ディスクにスケジュールを適用 gcloud compute disks add-resource-policies DISK_NAME \ --resource-policies=hourly-backup \ --zone=asia-northeast1-a
# 毎日深夜 2 時にスナップショットを取得(日次バックアップ) gcloud compute resource-policies create snapshot-schedule daily-backup \ --region=asia-northeast1 \ --max-retention-days=30 \ --start-time=17:00 \ --daily-schedule
# スナップショット取得前に fstrim を実行 # 効果: スナップショットのサイズ削減 + 作成速度向上 sudo fstrim -v / # 出力例: /: 50 GiB (53687091200 bytes) trimmed # マウントオプションで定期的に discard を有効化 # /etc/fstab: # /dev/sdb /data ext4 defaults,discard 0 0
# アプリケーション整合性スナップショット(Linux / fsfreeze) # ステップ1: ファイルシステムをフリーズ(書き込み停止) sudo fsfreeze --freeze /data # ステップ2: スナップショット取得 gcloud compute disks snapshot DISK_NAME \ --zone=asia-northeast1-a \ --snapshot-names=app-consistent-snap # ステップ3: フリーズ解除(必ず実行!忘れると書き込み不可になる) sudo fsfreeze --unfreeze /data # MySQL でのアプリケーション整合性スナップショット mysql -u root -e "FLUSH TABLES WITH READ LOCK;" gcloud compute disks snapshot DISK_NAME --zone=asia-northeast1-a mysql -u root -e "UNLOCK TABLES;"
# スナップショットの一覧確認 gcloud compute snapshots list # スナップショットの詳細確認 gcloud compute snapshots describe SNAPSHOT_NAME # スナップショットから新しいディスクを作成 gcloud compute disks create new-disk-from-snapshot \ --source-snapshot=SNAPSHOT_NAME \ --zone=asia-northeast1-a \ --size=100GB \ --type=pd-balanced # 作成したディスクを VM にアタッチ gcloud compute instances attach-disk VM_NAME \ --disk=new-disk-from-snapshot \ --zone=asia-northeast1-a
【スナップショットの料金】
ストレージ料金: $0.026/GB/月(マルチリージョン)
$0.020/GB/月(リージョン)
【コスト最適化】
├── 増分スナップショット活用(初回以降は差分のみ)
├── 保持期間を適切に設定(古いスナップショットを自動削除)
├── fstrim でスナップショットサイズを削減
└── DR 要件がなければ同一リージョン内に保存ローリングアップデート・カナリアデプロイ・自動ヒーリング・スケーリング
【ローリングアップデートの流れ】
現在の状態: [v1][v1][v1][v1][v1][v1] (6台)
Step 1: 1台を v2 に更新
[v2][v1][v1][v1][v1][v1]
↓ ヘルスチェック通過を確認
Step 2: さらに 1 台を更新
[v2][v2][v1][v1][v1][v1]
↓ ...
Step N: 全台更新完了
[v2][v2][v2][v2][v2][v2]
キーパラメータ:
--max-surge=2 → 同時に追加できる新バージョンの台数
--max-unavailable=0 → 同時に停止できる台数(0 = ゼロダウンタイム)# インスタンステンプレートを v2 に更新(ローリング) gcloud compute instance-groups managed rolling-action start-update my-mig \ --version=template=my-template-v2 \ --max-surge=1 \ --max-unavailable=0 \ --region=asia-northeast1 # アップデートの進捗を確認 gcloud compute instance-groups managed describe my-mig \ --region=asia-northeast1 # アップデートをキャンセル(進行中の場合) gcloud compute instance-groups managed rolling-action stop-proactive-update my-mig \ --region=asia-northeast1
# v2 を 10% のインスタンスだけに適用 gcloud compute instance-groups managed rolling-action start-update my-mig \ --version=template=my-template-v1,name=stable \ --canary-version=template=my-template-v2,target-size=10%,name=canary \ --region=asia-northeast1 # 問題なければ v2 を 100% に拡大 gcloud compute instance-groups managed rolling-action start-update my-mig \ --version=template=my-template-v2 \ --region=asia-northeast1 # 問題があれば v1 にロールバック gcloud compute instance-groups managed rolling-action start-update my-mig \ --version=template=my-template-v1 \ --region=asia-northeast1
# MIG のサイズを手動で変更 gcloud compute instance-groups managed resize my-mig \ --size=10 \ --region=asia-northeast1 # 特定のインスタンスを再作成(問題のある VM をリフレッシュ) gcloud compute instance-groups managed recreate-instances my-mig \ --instances=my-mig-abc1,my-mig-def2 \ --region=asia-northeast1 # 特定のインスタンスを MIG から削除(スケールイン) gcloud compute instance-groups managed delete-instances my-mig \ --instances=my-mig-abc1 \ --region=asia-northeast1 # オートスケーリングの一時無効化(メンテナンス時) gcloud compute instance-groups managed set-autoscaling my-mig \ --mode=off \ --region=asia-northeast1 # オートスケーリングを再有効化 gcloud compute instance-groups managed set-autoscaling my-mig \ --mode=on \ --region=asia-northeast1
# HTTP ヘルスチェックの作成 gcloud compute health-checks create http my-health-check \ --port=8080 \ --request-path=/healthz \ --check-interval=30s \ --timeout=10s \ --healthy-threshold=1 \ --unhealthy-threshold=3 # MIG に自動ヒーリングを設定 gcloud compute instance-groups managed set-autohealing my-mig \ --health-check=my-health-check \ --initial-delay=300s \ --region=asia-northeast1 # ヘルスチェックの状態を確認 gcloud compute backend-services get-health my-backend-service \ --global
バージョン管理・ノード管理・kubectl 操作・オートスケーリング
GKE のバージョン形式: MAJOR.MINOR.PATCH-gke.N 例: 1.29.3-gke.1200 サポートポリシー: ├── GKE は常に 3 つのマイナーバージョンをサポート │ 例: 1.27, 1.28, 1.29 ├── サポート終了バージョンは自動アップグレードされる └── リリースチャンネルで自動アップグレードを管理 リリースチャンネル: ├── Rapid: 最新版(プレビュー機能あり)→ テスト環境向け ├── Regular: バランス型 → 本番推奨 └── Stable: 安定版(遅め)→ ミッションクリティカル向け
# クラスタのバージョンを確認 gcloud container clusters describe my-cluster \ --region=asia-northeast1 \ --format="value(currentMasterVersion,currentNodeVersion)" # クラスタのコントロールプレーンをアップグレード gcloud container clusters upgrade my-cluster \ --master \ --cluster-version=1.29 \ --region=asia-northeast1 # ノードプールをアップグレード gcloud container clusters upgrade my-cluster \ --node-pool=default-pool \ --cluster-version=1.29 \ --region=asia-northeast1
# ノードプールの一覧確認 gcloud container node-pools list \ --cluster=my-cluster \ --region=asia-northeast1 # ノードプールのサイズ変更(手動スケーリング) gcloud container clusters resize my-cluster \ --node-pool=default-pool \ --num-nodes=5 \ --region=asia-northeast1 # ノードのドレイン(安全に Pod を退避してからメンテナンス) kubectl drain NODE_NAME \ --ignore-daemonsets \ --delete-emptydir-data # メンテナンス後にノードを再稼働 kubectl uncordon NODE_NAME
# ===== Pod の管理 ===== # Pod の一覧確認 kubectl get pods -n my-namespace -o wide # Pod の詳細確認(障害調査) kubectl describe pod POD_NAME -n my-namespace # Pod のログ確認 kubectl logs POD_NAME -n my-namespace kubectl logs POD_NAME -n my-namespace -c CONTAINER_NAME # 複数コンテナ時 kubectl logs POD_NAME -n my-namespace --previous # 前回クラッシュのログ # Pod 内でコマンド実行(デバッグ) kubectl exec -it POD_NAME -n my-namespace -- /bin/bash # Pod の強制削除(Terminating で止まった場合) kubectl delete pod POD_NAME -n my-namespace --grace-period=0 --force # ===== Deployment の管理 ===== # Deployment の状況確認 kubectl get deployments -n my-namespace kubectl rollout status deployment/my-app -n my-namespace # Deployment のスケーリング kubectl scale deployment/my-app --replicas=5 -n my-namespace # Deployment のイメージ更新(ローリングアップデート) kubectl set image deployment/my-app \ my-container=gcr.io/PROJECT/my-app:v2 \ -n my-namespace # アップデートのロールバック kubectl rollout undo deployment/my-app -n my-namespace # 特定バージョンにロールバック kubectl rollout undo deployment/my-app \ --to-revision=2 \ -n my-namespace # ロールアウト履歴の確認 kubectl rollout history deployment/my-app -n my-namespace
# クラスタ全体のリソース使用状況
kubectl top nodes
kubectl top pods -n my-namespace
# イベントの確認(障害の手がかり)
kubectl get events -n my-namespace --sort-by=.lastTimestamp
# Pod の再起動回数を確認(クラッシュループの検出)
kubectl get pods -n my-namespace \
-o jsonpath='{range .items[*]}{.metadata.name}{" "}{.status.containerStatuses[0].restartCount}{"
"}{end}'リビジョン管理・トラフィック分割・スケーリング設定・カナリアリリース
# Cloud Run サービスの一覧確認 gcloud run services list --region=asia-northeast1 # サービスの詳細確認 gcloud run services describe my-service \ --region=asia-northeast1 # サービスのリビジョン(バージョン)一覧 gcloud run revisions list \ --service=my-service \ --region=asia-northeast1 # トラフィック分割の確認・変更 gcloud run services describe my-service \ --region=asia-northeast1 \ --format="value(status.traffic)" # リビジョン v2 に 100% 切り替え gcloud run services update-traffic my-service \ --to-revisions=my-service-v2=100 \ --region=asia-northeast1 # 前のリビジョンにロールバック gcloud run services update-traffic my-service \ --to-latest \ --region=asia-northeast1
# 最小・最大インスタンス数の設定 gcloud run services update my-service \ --min-instances=1 \ --max-instances=100 \ --region=asia-northeast1 # 同時実行数の設定(1インスタンスあたりの最大リクエスト数) gcloud run services update my-service \ --concurrency=80 \ --region=asia-northeast1 # タイムアウトの設定 gcloud run services update my-service \ --timeout=300s \ --region=asia-northeast1
# Cloud Functions の一覧確認 gcloud functions list --region=asia-northeast1 # 関数のデプロイ gcloud functions deploy my-function \ --runtime=python311 \ --trigger-http \ --entry-point=main \ --region=asia-northeast1 \ --memory=256MB \ --timeout=60s \ --set-env-vars=ENV=production # 関数のログ確認 gcloud functions logs read my-function \ --region=asia-northeast1 \ --limit=50 # 関数の削除 gcloud functions delete my-function \ --region=asia-northeast1
オブジェクト操作・バケットロック・バージョニング・OLM・署名付きURL
# ===== オブジェクト操作 ===== # バケットの一覧 gcloud storage buckets list # オブジェクトのコピー gcloud storage cp local-file.txt gs://my-bucket/path/ # ディレクトリ全体をコピー(再帰的) gcloud storage cp -r ./local-dir/ gs://my-bucket/backup/ # オブジェクトの移動(別バケットへ) gcloud storage mv gs://source-bucket/file.txt gs://dest-bucket/file.txt # オブジェクトの削除 gcloud storage rm gs://my-bucket/old-file.txt # バケット内全オブジェクトの削除 gcloud storage rm -r gs://my-bucket/** # オブジェクトのメタデータ確認 gcloud storage objects describe gs://my-bucket/file.txt # ===== アクセス制御 ===== # バケットの IAM ポリシー確認 gcloud storage buckets get-iam-policy gs://my-bucket # ユーザーに読み取り権限を付与 gcloud storage buckets add-iam-policy-binding gs://my-bucket \ --member="user:alice@example.com" \ --role="roles/storage.objectViewer"
【保持ポリシーとは?】
例: 金融規制により「7年間はログを削除・変更禁止」
バケットにポリシーを設定:
gcloud storage buckets update gs://my-compliance-bucket \
--retention-period=7y
効果:
├── バケット内のすべてのオブジェクトが
│ 7 年間(設定日から)削除・上書き不可になる
└── 新しくアップロードしたオブジェクトも
アップロード時点から 7 年間保護される
【バケットロック(取り消し不可!)】
保持ポリシーを永久に変更できないようにロック
gcloud storage buckets lock gs://my-compliance-bucket
⚠️ バケットロックは一度かけると絶対に解除できません!
本当に必要な場合のみ実行してください。# オブジェクト単位での保持ロック設定 gcloud storage objects update gs://my-bucket/important-file.txt \ --retain-until=2031-12-31T23:59:59Z \ --retention-mode=LOCKED
# バージョニングの有効化 gcloud storage buckets update gs://my-bucket --versioning # 非最新バージョンの一覧確認 gcloud storage objects list gs://my-bucket --all-versions # 特定バージョンを最新バージョンとして復元 gcloud storage cp gs://my-bucket/file.txt#GENERATION \ gs://my-bucket/file.txt # ライフサイクルポリシーを適用 gcloud storage buckets update gs://my-bucket \ --lifecycle-file=lifecycle.json
自動バックアップ・PITR・リードレプリカ・Spannerバックアップ
# 自動バックアップの有効化(新規インスタンス作成時) gcloud sql instances create my-postgres \ --database-version=POSTGRES_15 \ --tier=db-n1-standard-4 \ --region=asia-northeast1 \ --backup-start-time=02:00 \ --backup-location=asia-northeast1 \ --retained-backups-count=14 \ --retained-transaction-log-days=7 # 既存インスタンスの自動バックアップを更新 gcloud sql instances patch my-postgres \ --backup-start-time=02:00 \ --retained-backups-count=30
# 手動バックアップを即時作成 gcloud sql backups create \ --instance=my-postgres \ --description="Pre-maintenance backup $(date +%Y%m%d)" # バックアップ一覧の確認 gcloud sql backups list --instance=my-postgres # バックアップから同じインスタンスに復元 gcloud sql backups restore BACKUP_ID \ --restore-instance=my-postgres # バックアップから別インスタンスに復元(本番データを壊さずテスト) gcloud sql backups restore BACKUP_ID \ --restore-instance=my-postgres-restore-test # PITR(ポイントインタイムリカバリ) gcloud sql instances clone my-postgres my-postgres-pitr \ --point-in-time=2024-01-15T10:30:00Z
# リードレプリカの作成 gcloud sql instances create my-postgres-replica \ --master-instance-name=my-postgres \ --region=us-central1 \ --tier=db-n1-standard-4 # リードレプリカのプロモート(プライマリに昇格) # 障害時や計画的な移行時に使用 gcloud sql instances promote-replica my-postgres-replica # レプリカのラグ(遅延)確認 gcloud sql instances describe my-postgres-replica \ --format="value(replicaConfiguration.mysqlReplicaConfiguration.masterHeartbeatPeriod)"
# Spanner のバックアップ作成 gcloud spanner backups create my-backup \ --instance=my-spanner-instance \ --database=my-database \ --expiration-date=2024-04-01T00:00:00Z # バックアップ一覧確認 gcloud spanner backups list \ --instance=my-spanner-instance # バックアップから復元 gcloud spanner databases restore \ --destination-instance=my-spanner-instance \ --destination-database=my-database-restored \ --source-backup=projects/PROJECT/instances/my-spanner-instance/backups/my-backup
自動収集メトリクス・カスタムダッシュボード・MQL・Ops Agent との違い
【Cloud Monitoring でできること】
メトリクスの収集:
├── GCP サービスのメトリクス(自動収集)
│ 例: CPU 使用率、ネットワーク I/O、HTTP リクエスト数
├── VM 内部のメトリクス(Ops Agent が必要)
│ 例: メモリ使用量、ディスク使用率、プロセス数
└── カスタムメトリクス(アプリが送信)
例: キューの長さ、ビジネスKPI
可視化:
└── カスタムダッシュボードでグラフを作成
アラート:
└── 閾値超過時に Email / PagerDuty / Slack / Pub/Sub に通知
SLO モニタリング:
└── サービスレベル目標の達成状況を可視化・管理compute.googleapis.com/instance/cpu/utilization はエージェントなしで取得可能ですが、 agent.googleapis.com/memory/percent_used は Ops Agent が必要です。
# gcloud でダッシュボードを作成(JSON定義) gcloud monitoring dashboards create \ --config-from-file=dashboard.json # ダッシュボードの一覧確認 gcloud monitoring dashboards list
// ダッシュボードの JSON 定義例
{
"displayName": "My Application Dashboard",
"gridLayout": {
"columns": "2",
"widgets": [
{
"title": "CPU Utilization",
"xyChart": {
"dataSets": [
{
"timeSeriesQuery": {
"timeSeriesFilter": {
"filter": "metric.type=\"compute.googleapis.com/instance/cpu/utilization\" resource.type=\"gce_instance\"",
"aggregation": {
"alignmentPeriod": "60s",
"perSeriesAligner": "ALIGN_MEAN"
}
}
}
}
]
}
}
]
}
}# 基本構文 fetch リソースタイプ | metric 'メトリクス名' | filter フィルタ条件 | align アライメント | every 集計間隔 | group_by グループキー, 集計関数 # 例1: プロジェクト内の全 VM の平均 CPU 使用率 fetch gce_instance | metric 'compute.googleapis.com/instance/cpu/utilization' | align mean_aligner() | every 1m | group_by [], mean(val()) # 例2: HTTP 5xx エラー率 fetch https_lb_rule | metric 'loadbalancing.googleapis.com/https/request_count' | filter (metric.labels.response_code_class == '500') | align rate(1m) | every 1m # 例3: GKE ノードのメモリ使用率(Ops Agent 経由) fetch k8s_node | metric 'kubernetes.io/node/memory/used_bytes' | align mean_aligner() | every 1m
インストール方法・config.yaml・PodMonitoring・Managed Prometheus
【Ops Agent の内部構成】
Ops Agent
├── Fluent Bit(ログ収集コンポーネント)
│ └── ログを Cloud Logging に転送
└── OpenTelemetry Collector(メトリクス収集コンポーネント)
└── メトリクスを Cloud Monitoring に転送
【Ops Agent が収集するもの(旧エージェントとの違い)】
従来の Stackdriver エージェント:
└── メモリ・ディスクなどの基本システムメトリクス
Ops Agent(現在の推奨):
├── メモリ使用量(%)
├── ディスク使用率(%)
├── ネットワーク接続数
├── プロセスごとの CPU・メモリ
├── アプリケーションログ(nginx, mysql, apache など)
└── カスタムログファイル# ===== 方法 1: VM に SSH して手動インストール ===== # インストールスクリプトをダウンロードして実行 curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh sudo bash add-google-cloud-ops-agent-repo.sh --also-install # インストール確認 sudo systemctl status google-cloud-ops-agent
# ===== 方法 2: gcloud でリモートインストール(SSH 不要)===== gcloud compute instances ops-agents policies create my-ops-agent-policy \ --agent-rules="type=ops-agent,version=current-major,package-state=installed,enable-autoupgrade=true" \ --os-types=short-name=debian,version=11 \ --instances=zones/asia-northeast1-a/instances/my-vm
# ===== 方法 3: VM 作成時にスタートアップスクリプトでインストール ===== #!/bin/bash # startup.sh curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh sudo bash add-google-cloud-ops-agent-repo.sh --also-install
# /etc/google-cloud-ops-agent/config.yaml
logging:
receivers:
nginx_access_log:
type: files
include_paths:
- /var/log/nginx/access.log
nginx_error_log:
type: files
include_paths:
- /var/log/nginx/error.log
my_app_log:
type: files
include_paths:
- /var/log/my-app/*.log
processors:
parse_json:
type: parse_json
field: message
time_key: timestamp
time_format: '%Y-%m-%dT%H:%M:%S.%L%Z'
exporters:
google:
type: google_cloud_logging
service:
pipelines:
nginx_pipeline:
receivers: [nginx_access_log, nginx_error_log]
exporters: [google]
app_pipeline:
receivers: [my_app_log]
processors: [parse_json]
exporters: [google]
metrics:
receivers:
hostmetrics:
type: hostmetrics
collection_interval: 60s
mysql:
type: mysql
endpoint: localhost:3306
username: monitoring_user
password: ${MYSQL_MONITORING_PASSWORD}
exporters:
google:
type: google_cloud_monitoring
service:
pipelines:
host_pipeline:
receivers: [hostmetrics]
exporters: [google]
mysql_pipeline:
receivers: [mysql]
exporters: [google]# 設定ファイルの検証 sudo google-cloud-ops-agent \ --config=/etc/google-cloud-ops-agent/config.yaml \ --check # Ops Agent を再起動して設定を反映 sudo systemctl restart google-cloud-ops-agent # ログで動作確認 sudo journalctl -u google-cloud-ops-agent -n 50
【なぜ Managed Service for Prometheus?】 通常の Prometheus: ├── Prometheus サーバーを自分でデプロイ・管理 ├── ストレージの管理が必要 └── スケーリングを手動で対応 Google Cloud Managed Service for Prometheus: ├── Prometheus 互換の API(既存の設定を流用可能) ├── ストレージは Cloud Monitoring が管理 ├── 自動スケーリング └── PodMonitoring / ClusterPodMonitoring CRD で設定
# PodMonitoring - 特定の Pod のメトリクスを収集
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: my-app-monitoring
namespace: my-app
spec:
selector:
matchLabels:
app: my-app
endpoints:
- port: metrics
interval: 30s
path: /metrics# Managed Service for Prometheus を有効化 gcloud container clusters update my-cluster \ --enable-managed-prometheus \ --region=asia-northeast1
アラート設計・通知チャネル・SLO 定義・バーンレートアラート
【良いアラートの条件】
1. 重要なものだけアラートにする
→ アラートが多すぎると「アラート疲れ」になり
本当に重要な通知を見逃す
2. ユーザーへの影響を基準にする
→ CPU 90% より「エラーレート 1% 超過」の方が重要
3. アクションできるアラートだけにする
→ 通知を受けたエンジニアが何か対応できるものだけ# alert-policy.yaml(CPU 使用率アラート)
displayName: "High CPU Utilization - Compute Engine"
conditions:
- displayName: "CPU utilization over 80%"
conditionThreshold:
filter: >
metric.type="compute.googleapis.com/instance/cpu/utilization"
AND resource.type="gce_instance"
comparison: COMPARISON_GT
thresholdValue: 0.8
duration: 300s
aggregations:
- alignmentPeriod: 60s
perSeriesAligner: ALIGN_MEAN
alertStrategy:
notificationRateLimit:
period: 3600s
notificationChannels:
- projects/PROJECT_ID/notificationChannels/CHANNEL_ID
documentation:
content: "CPU使用率が80%を超えています。スケールアップまたはオートスケール設定を確認してください。"
mimeType: text/markdown# HTTP 5xx エラーレートアラート
displayName: "High HTTP Error Rate - Load Balancer"
conditions:
- displayName: "HTTP 5xx error rate > 1%"
conditionThreshold:
filter: >
metric.type="loadbalancing.googleapis.com/https/request_count"
AND metric.labels.response_code_class="500"
comparison: COMPARISON_GT
thresholdValue: 0.01
duration: 60s
alertStrategy:
autoClose: 1800s
notificationChannels:
- projects/PROJECT_ID/notificationChannels/CHANNEL_ID# CLI でアラートポリシーを作成 gcloud alpha monitoring policies create \ --policy-from-file=alert-policy.yaml # アラートポリシーの一覧確認 gcloud alpha monitoring policies list # メンテナンス時に一時無効化 gcloud alpha monitoring policies update POLICY_ID --no-enabled
# メール通知チャネルの作成 gcloud alpha monitoring channels create \ --display-name="Ops Team Email" \ --type=email \ --channel-labels=email_address=ops-team@example.com # Slack 通知チャネルの作成 gcloud alpha monitoring channels create \ --display-name="#alerts Slack Channel" \ --type=slack \ --channel-labels=channel_name=#alerts,url=https://hooks.slack.com/... # PagerDuty 通知チャネルの作成 gcloud alpha monitoring channels create \ --display-name="PagerDuty On-call" \ --type=pagerduty \ --channel-labels=service_key=YOUR_PAGERDUTY_SERVICE_KEY # 通知チャネルの確認 gcloud alpha monitoring channels list
SLO の設計プロセス: Step 1: SLI(測定指標)を定義 └── リクエスト成功率、レイテンシ p99、可用性 Step 2: SLO(目標値)を設定 └── 99.9% のリクエストが成功する Step 3: エラーバジェットを計算 月間の許容ダウン時間 = (1 - SLO) × 月間時間 └── 99.9% SLO = 43.8 分/月 Step 4: Cloud Monitoring に SLO を設定して監視
// SLO の定義例(Cloud Monitoring API)
{
"displayName": "99.9% Availability SLO",
"goal": 0.999,
"rollingPeriod": "2592000s",
"requestBased": {
"goodTotalRatio": {
"goodServiceFilter": "metric.type=\"loadbalancing.googleapis.com/https/request_count\" AND metric.labels.response_code_class!=\"500\"",
"totalServiceFilter": "metric.type=\"loadbalancing.googleapis.com/https/request_count\""
}
}
}【SLO バーンレートアラートの種類】
バーンレートアラート(Burn Rate Alert):
エラーバジェットの消費速度を監視
バーンレート = 1.0 → エラーバジェットを通常速度で消費中
バーンレート = 2.0 → 2倍の速度でエラーバジェットを消費中
→ このままでは SLO を達成できない!
推奨アラート設定:
Fast Burn(高速消費): バーンレート > 14.4、1時間
Slow Burn(低速消費): バーンレート > 1.0、6時間データフロー・保持期間・ログクエリ・構造化ログ・アプリケーションから送信
【Cloud Logging のデータフロー】
ログの発生源:
├── GCP サービス(自動収集)
│ 例: GKE、Cloud SQL、Cloud Run、Load Balancer
├── Compute Engine VM(Ops Agent 経由)
│ 例: syslog、アプリケーションログ
└── アプリケーション(Cloud Logging API / ライブラリ)
例: Python の google-cloud-logging ライブラリ
↓
Cloud Logging(受信・保存・インデックス作成)
↓
Log Router(ルーティング)
├── Cloud Logging バケット(デフォルト 30 日保持)
├── BigQuery(長期保存・SQL 分析)
├── Cloud Storage(アーカイブ保存)
└── Pub/Sub(リアルタイムストリーミング)_Required バケットには管理アクティビティ監査ログと Data Access 監査ログが含まれ、削除・変更不可。
# 基本構文 resource.type = "リソースタイプ" resource.labels.instance_id = "VM_ID" severity >= ERROR textPayload: "エラーメッセージ" timestamp >= "2024-01-01T00:00:00Z" # 例1: 特定 VM の ERROR 以上のログ resource.type = "gce_instance" AND resource.labels.zone = "asia-northeast1-a" AND severity >= ERROR # 例2: Cloud SQL の接続エラー resource.type = "cloudsql_database" AND severity = ERROR AND textPayload =~ "connection" # 例3: HTTP 5xx エラーのアクセスログ resource.type = "http_load_balancer" AND httpRequest.status >= 500 # 例4: GKE の特定 Pod のログ resource.type = "k8s_container" AND resource.labels.namespace_name = "production" AND resource.labels.pod_name =~ "my-app-.*" AND severity = ERROR # 例5: IAM 権限変更が行われたログ(管理者調査用) resource.type = "project" AND proto_payload.method_name = "SetIamPolicy" AND timestamp >= "2024-01-01T00:00:00Z"
import google.cloud.logging
import logging
# Cloud Logging クライアントの初期化
client = google.cloud.logging.Client()
# Python の標準 logging と統合(推奨)
client.setup_logging()
# 使用例
logger = logging.getLogger(__name__)
logger.info("Application started")
logger.warning("Low memory: %d MB remaining", free_memory)
logger.error("Database connection failed", extra={
"json_fields": {
"database": "production-db",
"error_code": "CONNECTION_TIMEOUT",
"retry_count": 3
}
})# 構造化ログ(JSON ログ)の活用
import json
import sys
def log_structured(severity, message, **fields):
entry = {
"severity": severity,
"message": message,
**fields
}
print(json.dumps(entry), file=sys.stdout)
# 使用例
log_structured(
"INFO",
"Order processed",
order_id="ORD-12345",
user_id="USER-67890",
amount=15000,
payment_method="credit_card"
)
# → Cloud Logging で jsonPayload として自動パース3 種類の監査ログ・データアクセス有効化・セキュリティ調査・GKE 監査ログ
# 組織レベルで BigQuery のデータアクセスログを有効化
cat > policy.json <<EOF
{
"auditConfigs": [
{
"service": "bigquery.googleapis.com",
"auditLogConfigs": [
{"logType": "DATA_READ"},
{"logType": "DATA_WRITE"},
{"logType": "ADMIN_READ"}
]
}
]
}
EOF
gcloud organizations set-iam-policy ORG_ID policy.json【セキュリティインシデント調査】 「昨夜 AM 2 時頃、Cloud Storage バケットが削除された。誰がやったか?」 → 管理アクティビティ監査ログで調査: resource.type = "gcs_bucket" AND proto_payload.method_name = "storage.buckets.delete" AND timestamp >= "2024-01-15T17:00:00Z" # UTC 17:00 = JST 02:00 AND timestamp < "2024-01-15T18:00:00Z" → principal_email: "malicious-user@example.com" が記録されている! → このユーザーの操作履歴を追跡できる
【GKE の特別なルール】 GKE の監査ログは無効化できません! → セキュリティ上の強制仕様 Container-Optimized OS (COS) での auditd: GKE の COS ノードでは Linux auditd を有効化することで ・バイナリの実行履歴 ・ファイルシステムへのアクセス ・ネットワーク接続の詳細 などを記録できる 有効化方法: GKE Standard クラスタのノードプールで設定 → セキュリティインシデントの詳細調査に不可欠
シンク設定・BigQuery/Cloud Storage/Pub/Sub へのエクスポート・BigQuery ログ分析
【Log Router の仕組み】
すべてのログが Cloud Logging に到達
↓
Log Router(シンクのフィルタで振り分け)
│
├── _Default バケット(デフォルト 30 日保持)
│ └── フィルタに一致しないすべてのログ
│
├── BigQuery データセット
│ └── フィルタ: 長期保存・SQL 分析が必要なログ
│
├── Cloud Storage バケット
│ └── フィルタ: アーカイブ保存が必要なログ
│
└── Pub/Sub トピック
└── フィルタ: リアルタイム処理が必要なログ
└── SIEM ツール、Cloud Functions など# 1. BigQuery データセットを作成 bq mk --location=asia-northeast1 --dataset PROJECT_ID:logging_archive # 2. BigQuery シンクを作成(監査ログのみエクスポート) gcloud logging sinks create bigquery-audit-sink \ bigquery.googleapis.com/projects/PROJECT_ID/datasets/logging_archive \ --log-filter='protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"' \ --description="Export audit logs to BigQuery for analysis" # 3. シンクのサービスアカウントに BigQuery への書き込み権限を付与 SINK_SA=$(gcloud logging sinks describe bigquery-audit-sink \ --format="value(writerIdentity)") bq add-iam-policy-binding \ --project=PROJECT_ID \ --dataset=logging_archive \ --member="$SINK_SA" \ --role="roles/bigquery.dataEditor"
# 1. ログアーカイブ用バケットを作成 gcloud storage buckets create gs://my-log-archive-bucket \ --location=asia-northeast1 \ --storage-class=coldline # 2. Cloud Storage シンクを作成 gcloud logging sinks create storage-long-term-sink \ storage.googleapis.com/my-log-archive-bucket \ --log-filter='severity >= WARNING' \ --description="Archive WARNING+ logs to Cold Storage for 7 years" # 3. シンクのサービスアカウントに書き込み権限を付与 SINK_SA=$(gcloud logging sinks describe storage-long-term-sink \ --format="value(writerIdentity)") gcloud storage buckets add-iam-policy-binding gs://my-log-archive-bucket \ --member="$SINK_SA" \ --role="roles/storage.objectCreator"
# 1. Pub/Sub トピックを作成 gcloud pubsub topics create security-events-topic # 2. Pub/Sub シンクを作成(セキュリティ関連ログのみ) gcloud logging sinks create pubsub-security-sink \ pubsub.googleapis.com/projects/PROJECT_ID/topics/security-events-topic \ --log-filter='protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog" AND severity >= WARNING' \ --description="Stream security events to SIEM" # 3. 権限付与 SINK_SA=$(gcloud logging sinks describe pubsub-security-sink \ --format="value(writerIdentity)") gcloud pubsub topics add-iam-policy-binding security-events-topic \ --member="$SINK_SA" \ --role="roles/pubsub.publisher"
# シンクの一覧確認 gcloud logging sinks list # シンクの詳細確認 gcloud logging sinks describe SINK_NAME # シンクの更新(フィルタを変更) gcloud logging sinks update SINK_NAME \ --log-filter='severity >= ERROR' # シンクの削除 gcloud logging sinks delete SINK_NAME
-- 過去 7 日間の管理アクティビティ上位 10 操作
SELECT
proto_payload.auth_info[0].principal AS user_email,
proto_payload.method_name AS operation,
COUNT(*) AS operation_count
FROM
`my_project.logging_archive.cloudaudit_googleapis_com_activity_*`
WHERE
_TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
GROUP BY
user_email, operation
ORDER BY
operation_count DESC
LIMIT 10;-- 特定ユーザーの操作履歴(セキュリティ調査) SELECT timestamp, proto_payload.auth_info[0].principal AS user_email, proto_payload.method_name AS operation, proto_payload.resource_name AS resource FROM `my_project.logging_archive.cloudaudit_googleapis_com_activity_*` WHERE _TABLE_SUFFIX >= '20240101' AND proto_payload.auth_info[0].principal = 'suspicious@example.com' ORDER BY timestamp DESC;
-- HTTP 5xx エラーの時系列分析
SELECT
TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
COUNT(*) AS error_count,
http_request.request_url AS url
FROM
`my_project.logging_archive.requests_*`
WHERE
_TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
AND http_request.status >= 500
GROUP BY
hour, url
ORDER BY
hour, error_count DESC;分散トレーシング・継続プロファイリング・エラー自動集計・4 シグナル
【Cloud Trace の目的】 マイクロサービス環境での問題: ユーザーのリクエストが遅い!でもどのサービスが原因? User → API Gateway → Service A → Service B → Database → 全体で 3 秒かかっているが、どのステップが遅いか不明 Cloud Trace の効果: User → API Gateway(50ms) → Service A(200ms) → Service B(2500ms!) → Database(150ms) → Service B に問題があることを特定!
# Python での Cloud Trace 設定(OpenTelemetry)
from opentelemetry import trace
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
provider = TracerProvider()
cloud_trace_exporter = CloudTraceSpanExporter()
provider.add_span_processor(BatchSpanProcessor(cloud_trace_exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
# スパン(処理区間)を計測
with tracer.start_as_current_span("process-order"):
with tracer.start_as_current_span("validate-payment"):
validate_payment(order)
with tracer.start_as_current_span("save-to-database"):
save_order(order)【Cloud Profiler の目的】 「どのコードがCPU/メモリを消費しているか?」を 本番環境で継続的に測定する 特徴: ├── 本番環境に影響を与えずに継続プロファイリング ├── CPU 時間・ヒープメモリ・スレッド使用量を可視化 ├── フレームグラフ(Flame Graph)で視覚化 └── Go, Java, Python, Node.js に対応 典型的な発見: ├── 不要なデータベースクエリがループ内で実行されている ├── JSON シリアライズが想定外に重い └── メモリリークの原因関数を特定
# Python での Cloud Profiler 設定
import googlecloudprofiler
# アプリ起動時に初期化するだけで自動プロファイリング開始
googlecloudprofiler.start(
service='my-service',
service_version='1.0.0',
verbose=3,
)【Error Reporting の目的】 アプリケーションで発生した例外・エラーを 自動集計して重要なものを通知する 機能: ├── Cloud Logging に記録された例外・エラーを自動検出 ├── 同じエラーをグループ化(重複を排除) ├── 新しいエラーが出たら即時通知 ├── エラーの発生頻度・傾向を表示 └── スタックトレースで原因箇所を特定
# Python アプリでエラーを Error Reporting に送信
from google.cloud import error_reporting
client = error_reporting.Client()
try:
result = process_order(order_id)
except Exception:
# エラーを Error Reporting に送信(スタックトレース付き)
client.report_exception()
raise根本原因分析・IaC 自動生成・FinOps 提案・全リソース検索・IAM ポリシー分析
【Gemini Cloud Assist とは?】 Google Cloud の AI アシスタント → Cloud Console の右上「?」ボタンから利用 できること: ├── 自然言語で GCP の操作をサポート ├── アーキテクチャ図を自動生成 ├── Terraform テンプレートを自動生成 ├── 障害の根本原因(RCA)分析 └── コスト最適化の提案
【Gemini によるトラブルシューティング例】 エンジニアが入力: 「us-central1 の Cloud Run サービスが今朝 9 時から 503 エラーを返しています。原因を調べてください。」 Gemini が自動分析: ┌── Cloud Logging のエラーログを横断分析 ├── Cloud Monitoring のメトリクスを確認 │ (CPU 急上昇、メモリ不足など) ├── Cloud Asset Inventory の設定変更履歴を確認 │ (デプロイ・設定変更がなかったか) └── 分析結果を自然言語で提示 Gemini の回答例: 「8:55 AM に新しいリビジョンがデプロイされました。 そのリビジョンから OOMKilled(メモリ不足)が多発しています。 メモリ上限を 256MB から 512MB に増やすことを推奨します。」
【Cloud Asset Inventory の目的】 「組織全体に何があるか、誰がアクセスできるか」を一元的に把握 機能: ├── 全リソースの検索・エクスポート ├── IAM ポリシーの変更履歴 ├── リソースへのアクセス権分析 └── 組織ポリシーとの整合性確認
# 組織内の全 GKE クラスタを検索 gcloud asset search-all-resources \ --asset-types='container.googleapis.com/Cluster' \ --scope='organizations/ORG_ID' \ --format="table(name,location,displayName)" # 外部 IP を持つ VM を検索(セキュリティ監査) gcloud asset search-all-resources \ --asset-types='compute.googleapis.com/Instance' \ --scope='organizations/ORG_ID' \ --query='networkInterfaces.accessConfigs.natIP:*'
# IAM ポリシーの変更履歴を確認 gcloud asset list \ --organization=ORG_ID \ --asset-types='iam.googleapis.com/Policy' \ --content-type=iam-policy \ --snapshot-time=$(date -d '1 day ago' -u +%Y-%m-%dT%H:%M:%SZ) # 特定のリソースにアクセスできる全 Identity を分析 gcloud asset analyze-iam-policy \ --organization=ORG_ID \ --full-resource-name='//storage.googleapis.com/projects/_/buckets/my-sensitive-bucket'
頻出パターン・重要用語チェックリスト・推奨学習リソース
【パターン①】メモリメトリクスに関する問題 問題文: 「Compute Engine VM のメモリ使用量を監視したい。どうすればよいか?」 正解: Ops Agent をインストールして設定する よくある不正解: 「Cloud Monitoring コンソールで自動的に確認できる」 → ❌ メモリ使用量はデフォルトでは取得されない CPU/ネットワーク I/O は自動取得だが、メモリは Ops Agent が必要
【パターン②】スナップショットの整合性に関する問題
問題文: 「MySQL データベースが動作している VM のディスクの
完全な整合性を保ったバックアップを取得したい。」
正解: アプリケーション整合性スナップショット
→ MySQL で FLUSH TABLES WITH READ LOCK を実行してから
スナップショットを取得
クラッシュ整合性との違い:
クラッシュ整合性: アプリ無停止、メモリのフラッシュなし
アプリケーション整合性: 書き込みを停止してからスナップショット【パターン③】監査ログの種類に関する問題 問題文 1: 「IAM ポリシーの変更を記録したい。どのログを使うか?」 → 管理アクティビティ監査ログ(常に有効) 問題文 2: 「Cloud Storage バケットのオブジェクト読み取りを監査したい。どうすればよいか?」 → データアクセス監査ログを有効化(デフォルトは無効) 3 種類の使い分け: 管理アクティビティ: リソースの作成・変更・削除(常に有効・無料) データアクセス: データの読み書き(手動で有効化・有料) システムイベント: Google の自動操作(常に有効・無料)
【パターン④】ログのエクスポート先に関する問題 問題文: 「ログを 7 年間保持してコンプライアンス要件を満たしたい。 コストを最小化する方法は?」 正解: Cloud Storage の Coldline ストレージへのシンクを設定 → 低コストな長期アーカイブ 各エクスポート先の使い分け: BigQuery: 長期保存 + SQL で柔軟な分析 Cloud Storage: 純粋なアーカイブ(コスト最安) Pub/Sub: リアルタイムで SIEM や外部システムに連携
Domain 3 は「デプロイ後の運用・監視」がテーマです。
最頻出トピック TOP 5:
このドメインの学習にあたって参考にした公式ドキュメントおよび技術リソース