本文へ移動

ホーム / SRE / 第5部 インフラ・セキュリティ・性能・コスト

第5部 インフラ・セキュリティ・性能・コスト・第10章

インフラ設計

★★★ 必須25トピック・面接 11問

SRE面接の中心領域。「なぜその構成にしたか」「何を諦めたか」とトレードオフを語れるかが見られる。AWSを例に整理する。

層主なサービス冗長化の方法単一障害点になりやすい箇所
DNSRoute 53マネージドで冗長。ヘルスチェックとフェイルオーバー外部DNSに依存している場合
CDN / エッジCloudFront、WAFグローバルに分散オリジンが1つしかない
ロードバランサALB / NLB複数AZに配置1AZにしかサブネットがない
アプリケーションECS、EKS、EC2 Auto Scaling複数AZに分散、最低2台以上1台構成、セッションをローカルに保持
キャッシュElastiCache(Redis)レプリカとマルチAZ自動フェイルオーバー単一ノード
データベースRDS / AuroraMulti-AZ、リードレプリカシングルAZ構成
非同期処理SQS、Lambda、ワーカーマネージドで冗長ワーカーが1台
外向き通信NAT GatewayAZごとに配置1つの NAT Gateway を全AZで共有(AZ障害で全滅)
ストレージS3マネージドで冗長(3AZ以上)-
片方のAZが止まっても、もう片方で処理を続けられるVPCアベイラビリティゾーン Aアベイラビリティゾーン CRoute 53 → CloudFront+WAFALB(両方のAZにまたがって配置)ECS タスク(アプリ)ステートレスで入れ替え可能ECS タスク(アプリ)ステートレスで入れ替え可能ElastiCacheプライマリRDS / AuroraプライマリRDS / AuroraスタンバイElastiCacheレプリカ同期
マルチAZ構成の例(AWS)

アプリは両AZで動かし、DBはプライマリとスタンバイを別AZに置く。AZ障害時はALBが残った側へ振り分け、DBはスタンバイにフェイルオーバーする。

10.2ロードバランサー

用語★★★ 必須
ひとことで

複数のサーバーに処理を振り分け、壊れたサーバーを自動で外す。振り分け方、ヘルスチェック、外すときの待ち方が運用の肝。

ロードバランサー(LB)は、利用者からは1つの窓口に見せながら、後ろの複数のサーバーにリクエストを振り分けます。定期的なヘルスチェックで応答しないサーバーを自動で外し、戻れば再び入れます。AWSでは、HTTPの中身を見て振り分けるALB(L7)、TCP・UDPを高速に転送するNLB(L4)、FWなどの機器に通信を通すGWLBがあります。

サービスの入口に立つので、設定の誤りがそのまま利用者に見える障害になります。デプロイのたびに数秒だけ 502 が出る、1台だけ負荷が高い、ヘルスチェックの失敗で全台が外れる、といった症状の多くは、下の表の設定で説明できます。

設定内容注意点
振り分け方式ラウンドロビン、最少未処理リクエスト、ハッシュ処理時間がばらつくなら最少未処理が向く
ヘルスチェックパス、間隔、成功・失敗の回数依存先DBまで見る重いチェックにすると連鎖して全台外れる
登録解除の遅延外すときに処理中のリクエストを待つ時間デプロイ時のエラーを防ぐ。長すぎるとデプロイが遅い
アイドルタイムアウト無通信の接続を切る時間バックエンドのKeep-Aliveより短くする(逆だと502)
スティッキーセッション同じ利用者を同じサーバーへ負荷が偏る。ステートレスにして使わないのが理想
クロスゾーン負荷分散AZをまたいで均等に配るAZごとの台数が違うときに偏りを防ぐ
スロースタート追加直後のサーバーに少しずつ流すJITやキャッシュが温まるまで守る
どう振り分けるか、壊れたサーバーをどう外すか、外すときにどう待つかロードバランサーヘルスチェックサーバー1サーバー2サーバー3×ヘルスチェック失敗で外す振り分け方ラウンドロビン:順番に最少接続:空いているところへハッシュ:同じ人は同じ先へ加重:性能に応じて比率を変える運用で効く設定・登録解除の遅延(コネクションドレイン):外すとき、処理中のリクエストが終わるまで待つ・スティッキーセッション:同じ利用者を同じサーバーへ。偏りやすいので、できればステートレスにして使わない・クロスゾーン負荷分散:AZをまたいで均等に配る・スロースタート:追加直後のサーバーに少しずつ流す(キャッシュが温まるまで)
ロードバランサーの仕組みと設定

デプロイ時の502は、登録解除の遅延とKeep-Aliveの設定を最初に疑う。

下の「ブラウザで試す」の図では、ラウンドロビンでサーバー1・2に順番に振り分ける様子から始まり、ヘルスチェック(/health)がタイムアウトしてしきい値の回数だけ続けて失敗したサーバーが自動で外され、復旧すると戻るまでを順に見られます。1台が外れたあと、残りのサーバーで全量を受け止められるか(N+1 の余力)に注目してください。

面接ではこう答える

ロードバランサーは複数のサーバーに処理を振り分け、ヘルスチェックで壊れたサーバーを外します。AWSではHTTPを見るALB、TCP・UDPを高速に流すNLBを使い分けます。運用では、ヘルスチェックを依存先まで見る重いものにしない、登録解除の遅延で処理中のリクエストを待つ、アイドルタイムアウトをバックエンドのKeep-Aliveより短くする、スティッキーセッションに頼らずステートレスにする、が重要です。

別のページで開く →

ネットワーク図を読み込んでいます…

10.3可用性設計

★★★ 必須
観点設計の要点
単一障害点(SPOF)の排除LB、アプリ、DB、NAT Gateway、DNS それぞれが冗長か確認
マルチAZAZ障害に耐える基本形。ALB+複数AZのECS / EKS+Multi-AZ のRDS
マルチリージョンコストと複雑さが大きい。必要性をRTO / RPOとビジネス要件から判断
ステートレス化セッションを外部(Redis等)へ。インスタンスを自由に入れ替えられるようにする
依存先の障害外部SaaSやAPIが落ちたときの挙動(タイムアウト、フォールバック)を設計に含める
構成計算結果
99.9% のサーバー1台-99.9%
99.9% のサーバー2台で冗長化1 − (0.001)²99.9999%
LB 99.99% → アプリ 99.9% → DB 99.95%(直列)0.9999 × 0.999 × 0.9995約 99.84%

直列につながる依存先が増えるほど全体の可用性は下がる。外部SaaSへの依存も同じ計算に入る。

障害の単位例備え
プロセス・コンテナアプリのクラッシュ自動再起動、複数台構成
ホストEC2 のハードウェア障害Auto Scaling、複数台
AZデータセンターの電源・冷却障害マルチAZ
リージョンリージョン全体の障害、大規模災害マルチリージョン、別リージョンのバックアップ
依存サービス外部API、SaaS、認証基盤の停止タイムアウト、フォールバック、縮退運転
人・運用誤操作、誤った設定変更IaC、レビュー、段階的適用、権限の最小化

実際の障害の多くは「変更」が原因になる。デプロイや設定変更を安全にする仕組みは、ハードウェアの冗長化と同じくらい重要。

10.6スケーリング

★★★ 必須
方式特徴使いどころ
垂直スケールインスタンスを大きくする。簡単だが上限と停止を伴うDBなど分散が難しいもの
水平スケール台数を増やす。ステートレスが前提Web / APIサーバー
オートスケーリングCPU、リクエスト数、キュー長などで台数を自動調整変動のあるトラフィック
事前スケール予定されたスパイク(キャンペーン、TV放映)に先回り起動時間がスパイクに間に合わない場合

オートスケールの注意点:起動に時間がかかる、DBなど下流がボトルネックになる、スケールインで処理中の接続を切らない。

指標向いているワークロード注意点
CPU使用率CPUを使う処理が中心のAPII/O待ちが中心の処理では効かない
リクエスト数(1台あたり)Web / API 全般処理の重さがリクエストごとに違うと不正確
キューの滞留数非同期ワーカー1メッセージの処理時間を考慮する
レイテンシユーザー体験を直接守りたい場合原因がDBなら台数を増やしても改善しない
スケジュール時間帯で読めるトラフィック予測外のスパイクには別途対応が必要

第12章「パフォーマンスチューニング」:負荷試験とキャパシティ計画を図で詳しく

10.8DR(災害対策)

★★★ 必須

DR(Disaster Recovery、災害対策)は、データセンターやクラウドのリージョンがまるごと使えなくなるような大きな障害から、サービスを立て直すための備えです。ふだんの冗長化(複数台・複数AZ)では防げない規模の障害を想定します。

方式は、待機側にどこまで準備しておくかで分かれます。待機側をふだんから動かしておくほど早く復旧できますが、そのぶん費用がかかります。どれを選ぶかは、RTO と RPO という2つの目標(意味は表の下)から決めます。

方式RTORPOコスト
バックアップ&リストア数時間〜数時間低
パイロットライト数十分〜数分中
ウォームスタンバイ数分〜数秒〜数分中〜高
マルチサイト(アクティブ / アクティブ)ほぼゼロほぼゼロ高

RTO は復旧までにかかってよい時間、RPO は失ってよいデータの期間(どの時点まで戻ってよいか)です。面接では、DR訓練を実際にやっているかを聞かれやすいです。

復旧を速くするほどコストが上がる。要件で選ぶコスト →復旧の速さ(RTO短い)↑バックアップ&リストアRTO 数時間〜パイロットライトRTO 数十分〜ウォームスタンバイRTO 数分〜マルチサイトRTO ほぼゼロ
DR方式ごとの復旧時間とコスト

必要以上に速い復旧を求めるとコストが跳ね上がる。ビジネス要件から決める。

下の「ブラウザで試す」の図では、東京のリージョンが止まったときに、Route 53 のヘルスチェックが失敗を検知し、DNS の答えを大阪に切り替えるまでを順に見られます。TTL が切れるまでは古い東京の IP に接続しようとする人がいること(RTO に効く)と、DNS が切り替えるのは入口だけで、大阪のレプリカの DB は別に昇格させる必要があり、非同期だと東京で最後に書いた分が届いていないかもしれないこと(RPO に効く)に注目してください。

別のページで開く →

ネットワーク図を読み込んでいます…

ビジネス要件の例RTO / RPO の目安構成の例
社内ツール、多少止まってもよい1日 / 24時間日次バックアップから復元
一般的なWebサービス1時間 / 5分Multi-AZ+PITR、別リージョンへのバックアップコピー
決済・EC の主要機能数分 / ほぼゼロMulti-AZ+別リージョンのウォームスタンバイ(Aurora Global Database 等)
社会インフラ級ほぼゼロ / ゼロマルチリージョンのアクティブ / アクティブ

10.10デプロイ戦略

★★★ 必須
戦略仕組みメリットデメリット
ローリング少しずつ新バージョンに置き換え追加リソースが少ない新旧混在、ロールバックに時間
ブルー / グリーン新環境を丸ごと用意して切り替え即座に切り戻せる一時的に2倍のリソース
カナリア一部のトラフィックだけ新バージョンへ影響を限定して検証できるメトリクスでの判定の仕組みが必要
フィーチャーフラグコードは出して機能はフラグで制御デプロイとリリースを分離フラグの管理コスト

DBマイグレーションは後方互換を保つ(Expand / Contract:列追加 → アプリ切り替え → 旧列削除)のが定番の答え。

切り戻しの速さとリソースのコストが違うローリング少しずつ置き換え新旧が混在する段階1v2v1v1v1段階2v2v2v1v1段階3v2v2v2v1ブルー / グリーン環境ごと切り替え即座に戻せるが2倍のリソースLBv1v1v2v2旧(待機)新(本番)カナリア一部だけ新版に流すメトリクスで判定して拡大LBv1v1v1v295%5%
デプロイ戦略の比較

どの方式でも、メトリクスを見て自動で戻せる仕組みとセットにする。

仕組み内容
自動ロールバックデプロイ後のエラー率やレイテンシの悪化を検知して自動で戻す
段階的展開1% → 10% → 50% → 100% のように広げ、各段階でメトリクスを確認
デプロイ凍結大型イベント前や年末などに変更を止める
ヘルスチェック連動新しいタスクが正常になるまで古いタスクを残す
マイグレーションの分離スキーマ変更とアプリのデプロイを別々に行う
段階作業状態
1 Expand新しい列を追加(NULL許容)旧アプリはそのまま動く
2 二重書き込みアプリが旧列と新列の両方に書くロールバックしても安全
3 データ移行既存データを新列へコピーバッチで小分けに
4 読み取り切り替えアプリが新列から読む問題があれば戻せる
5 Contract旧列への書き込みを止め、旧列を削除最後に実施
どの段階でもアプリを1つ前に戻せるように、小さく進める1 列を追加新列はNULL可旧アプリも動く2 両方に書く旧列と新列に二重書き込み3 データ移行既存行を小分けにコピー4 新列を読む問題あれば読み取りを戻す5 旧列を削除最後に実施戻れない操作
Expand / Contractの5段階

5段目以外はいつでも戻せる。戻れない操作は最後に回す。

10.13IaC と CI/CD

★★★ 必須
テーマ要点
Terraform の stateリモート(S3+ロック)で管理。state の分割単位、drift の検知
モジュール設計環境差分は変数で吸収。共通化しすぎると変更の影響範囲が広がる
plan のレビューCIで plan を出してPRでレビュー、apply は承認後
Terraform と Ansible の違いTerraform は宣言的なリソース構築、Ansible は構成管理(サーバー内の設定)
CI/CD パイプラインテスト、静的解析、イメージスキャン、段階的デプロイ、自動ロールバック
GitOpsGit を唯一の正とし、Argo CD などがクラスタを同期
ひとことで

変更の履歴を残し、壊れたら戻せるようにする道具と、その使い方の決まり。変更の入口を Git にそろえると、障害の原因の特定と切り戻しが速くなる。

Git は、ソースコードやインフラの定義(Terraform・Kubernetes のマニフェスト)の変更の履歴を残す道具です。SRE にとって大事なのは、「いつ・誰が・何を・なぜ変えたか」が追えること、そして壊れたら戻せることです。障害の多くは変更がきっかけなので、変更の入口を Git にそろえておくと、原因の特定と切り戻しが速くなります。

ブランチ戦略やり方向いている場面
GitHub Flowmain から短いブランチを切り、PR で main に戻してデプロイWeb サービス全般。シンプル
トランクベース開発ブランチは数時間〜1日。未完成の機能は Feature Flag で隠すデプロイ頻度を上げたい。DORA の調査でも成果と結びつく実践として挙げられている
Git Flowdevelop・release・hotfix など複数の長命ブランチリリースの版を並行して保守する(パッケージ・アプリ)。Web サービスには重いことが多い
トランクベース開発:短いブランチをすぐ main に戻すmainPR(数時間〜1日)PR+CI+レビューデプロイデプロイ未完成の機能はFeature Flag で隠す
短命なブランチを小さく main に戻し、main をいつでもデプロイできる状態に保つ
操作結果使いどころ
merge2つの履歴をそのまま合流(マージコミットができる)共有ブランチ。履歴を書き換えない
rebase自分のコミットを相手の先頭に付け直す(履歴が一直線)自分だけのブランチを最新にする。共有ブランチでは使わない
squash mergePR のコミットを1つにまとめて main へmain の履歴を「1 PR=1コミット」に。切り戻しは revert 1回
revert打ち消すコミットを新しく作る本番で問題が出た変更を、履歴を残したまま戻す

SRE として決めておくこと:main への直接 push を禁止(ブランチ保護)、PR に CI の合格とレビューを必須に、コミットに課題番号を入れる、秘密情報を入れない(入れてしまったら履歴から消すより先に鍵を無効化して作り直す。履歴は複製されている前提で)、タグでリリースの版を残す。

CI/CDとGitHub Actions・ビルド・CIの高速化

面接ではこう答える

Git の運用で大事にしているのは、変更を小さく・追えるようにして、壊れたらすぐ戻せることです。ブランチは短命にしてトランクベースに近い形で main に戻し、main へのマージには CI の合格とレビューを必須にしています。本番で問題が出たら、まず revert で戻してから原因を調べます。秘密情報を誤って入れたときは、履歴を消すより先に鍵を無効化します。

ひとことで

あるべき姿を Git に宣言し、同期の仕組み(Argo CD・Flux)がクラスタを合わせ続けるやり方。

GitOps は、インフラやアプリの「あるべき姿」を Git に宣言として書き、Argo CD や Flux のような仕組みが、クラスタの実際の状態をそれに合わせ続けるやり方です。本番を変える入口が PR だけになるので、変更のレビュー・履歴・切り戻し(revert)がすべて Git でできます。

GitOps:Git の内容を「あるべき姿」として、クラスタ側が合わせに行く開発者PR を出すGit リポジトリマニフェスト(宣言)同期の仕組みArgo CD・Fluxクラスタ実際の状態差分を見つけたら Git の内容に戻す(ドリフトの修正)変更の履歴・レビュー・ロールバックは Git で
本番を変える唯一の入口を Git にする(手で kubectl apply しない)
プッシュ型(CI から kubectl apply)プル型(GitOps)
本番の認証情報CI が持つ(漏れると危ない)クラスタの中の同期の仕組みだけが持つ
手作業の変更(ドリフト)気づきにくい差分として検出し、Git の内容に戻せる
切り戻しもう一度パイプラインを流すGit で revert すれば戻る
注意—秘密情報は Git にそのまま置かない(Sealed Secrets・外部のシークレット管理を使う)

IaCのデプロイフロー戦略

面接ではこう答える

GitOps は、Kubernetes などのあるべき状態を Git に宣言として置き、Argo CD のような仕組みがクラスタの状態をそれに合わせ続けるやり方です。本番を変える入口が PR だけになるので、変更のレビューと履歴が残り、切り戻しは revert で済みます。手作業の変更も差分として検出できます。CI に本番の認証情報を持たせなくてよいのも利点です。

10.16CI/CDとGitHub Actions

用語★★★ 必須
ひとことで

PRで自動検証し、マージ後に段階的にデプロイする。AWSへの認証はOIDCで鍵を持たない。ワークフロー自体もセキュリティの対象。

CI(継続的インテグレーション)は、変更のたびに自動でビルド・テスト・検査をすることで、CD(継続的デリバリー・デプロイ)は、検証済みの成果物を自動でステージングや本番に届けることです。GitHub Actionsでは、リポジトリの .github/workflows にYAMLでワークフローを書き、PRやpushなどのイベントで実行します。

name: deploy
on:
  push:
    branches: [main]
permissions:
  id-token: write   # OIDCでAWSに認証するため
  contents: read
concurrency: deploy-production   # 同時に2つ走らせない
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production       # 承認者ルールを適用
    steps:
      - uses: actions/checkout@<コミットSHA>
      - uses: aws-actions/configure-aws-credentials@<コミットSHA>
        with:
          role-to-assume: arn:aws:iam::123456789012:role/deploy
          aws-region: ap-northeast-1
      - run: ./scripts/deploy.sh
安全に運用するポイント内容
OIDCで認証長期のアクセスキーをシークレットに置かない。ロールの信頼ポリシーでリポジトリ・ブランチ・環境を限定
permissionsを最小にGITHUB_TOKENの権限を必要なものだけに
アクションをSHAで固定タグは書き換えられるので、外部のアクションはコミットSHAで指定(更新はRenovateで)
Environmentsと承認本番は承認者を必須にし、本番用のシークレットは本番の環境にだけ置く
フォークからのPR外部からのPRでシークレットが読めないようにする(pull_request_targetの扱いに注意)
同時実行の制御concurrencyで、同じ環境へのデプロイが重ならないようにする
成果物の一貫性同じイメージ(コミットSHAのタグ)をステージングから本番へ昇格させ、作り直さない
GitHub ActionsでのCI/CDの基本形PRで検証し、マージ後に段階的にデプロイする1 PR作成lint・テスト・ビルドを並列で2 セキュリティ依存・イメージのスキャン・秘密情報検出3 レビュー・マージ必須チェックと承認をブランチ保護で4 イメージ作成コミットIDでタグ付けしてECRへ5 ステージング自動デプロイ・E2Eテスト6 本番の承認Environmentsの承認者ルール7 本番デプロイOIDCでAWSに認証・カナリアで段階的に8 監視・自動で戻すエラー率が悪化したら戻す
GitHub ActionsでのCI/CDの流れ

「ビルドは1回、同じ成果物を環境ごとに昇格」が基本。

面接ではこう答える

PRでlint、テスト、ビルド、セキュリティスキャンを並列に実行し、マージ後はコミットSHAでタグ付けしたイメージを作って、ステージングで検証し、承認を経て本番に段階的にデプロイします。AWSへの認証はOIDCでロールを引き受け、長期のキーを持ちません。ワークフロー自体も攻撃対象なので、permissionsの最小化、外部アクションのSHA固定、本番環境の承認、同時実行の制御を行います。

ひとことで

ランナーはCIのジョブを実際に動かすマシン。手間・速さ・社内ネットワークへの到達・安全性・コストのバランスで選ぶ。

種類特徴向く用途
GitHubホストの標準ランナー管理不要で毎回まっさら。性能は控えめ一般的なテスト・ビルド
GitHubホストのLarger runners高性能・ARM・GPU、固定IPなども選べる。単価は高い重いビルドやテストだけ
セルフホスト(EC2、Kubernetes上のActions Runner Controller)VPC内の資源に届き、大量に回すと安い。運用が必要DBを使う統合テスト、社内のみのデプロイ先
マネージドの使い捨てランナー(AWS CodeBuildのランナーなど)AWS内で毎回使い捨て。IAMロールやVPCに接続できるAWS中心の組織で、運用を軽くしたい場合
安全に運用するポイント内容
使い捨てにするジョブごとに新しい環境で動かし、前のジョブの成果物や秘密情報が残らないようにする
公開リポジトリでセルフホストを使わない外部からのPRで、社内ネットワーク上で任意のコードを実行される危険がある
権限を分ける本番にデプロイできるランナーと、PRのテスト用のランナーを分ける
ランナーのイメージを更新OSやツールの更新をコード化し、定期的に作り直す
キャッシュと成果物セルフホストではキャッシュをS3などに置き、使い捨てでも速くする
コストを見る分単位の課金と、セルフホストのインスタンス費用・運用工数を比べる。ジョブの所要時間も計測
ランナーは「手間・速さ・社内への到達・安全性」で選ぶGitHubホスト標準ランナー○ 管理不要・毎回まっさら○ すぐ使える× 性能は控えめ× VPC内に直接届かない× 分単位の課金(私的リポ)GitHubホストLarger runners○ 管理不要で高性能○ ARM・GPUも選べる○ 固定IPやVNet連携も× 単価が高い→ 重いビルドだけに使うセルフホストEC2・ARC(K8s)○ VPC内の資源に届く○ 大量に回すと安い× 運用・更新・スケール× 使い回すと汚染の危険→ 毎回使い捨てにするマネージドCodeBuildのランナー等○ AWS内で使い捨て○ IAMロール・VPCに接続○ 運用が軽い× AWS側の設定が必要→ AWS中心の組織向け公開リポジトリでセルフホストランナーを使うと、外部からのPRで任意のコードを社内ネットワークで実行される危険がある
CIランナーの選択肢

迷ったら標準ランナーから始め、重いジョブとVPC内に届く必要があるジョブだけ別のランナーにする。

面接ではこう答える

ランナーは、管理不要なGitHubホストの標準ランナー、高性能なLarger runners、VPC内に届き大量実行で安いセルフホスト、AWS内で使い捨てにできるCodeBuildのランナーなどから選びます。セルフホストは使い捨てにして前のジョブの痕跡を残さず、公開リポジトリでは使わず、本番デプロイ用とPRのテスト用を分けます。費用は分単位の課金とインスタンス費用・運用工数で比べます。

10.18ビルド・CIの高速化

用語★★★ 必須
ひとことで

CIの待ち時間は、開発の速さと障害時の復旧の速さに直結する。キャッシュ・並列化・やらなくてよいことをやめる、の3つで縮める。

手段内容
依存のキャッシュactions/cache や setup-node などの cache オプションで、ロックファイルが変わらない限り再利用
DockerのレイヤーキャッシュBuildKitのキャッシュ(cache-from/cache-to)をGitHub Actionsのキャッシュやレジストリに保存
Dockerfileの順番変わりにくい依存のインストールを先、変わりやすいコードのコピーを後に。マルチステージで最終イメージを小さく
テストの並列化matrix や分割実行で複数のランナーに分ける。遅いテストを計測して改善
必要なものだけ動かすpaths フィルタで、変更のないサービスのジョブを動かさない(モノレポで効果大)
古い実行を止めるconcurrency と cancel-in-progress で、同じPRの古い実行を止める
ランナーを強くする重いジョブだけ大きいランナーやセルフホストランナー(ARMも検討)
計測するジョブごとの所要時間とキャッシュのヒット率を記録し、遅くなったら気づく

CIの時間は、障害時に修正をデプロイするまでの時間(MTTR)にも含まれます。「緊急時は承認を省略できる」よりも、「普段から速い」ことの方が大事です。

キャッシュと並列化で「毎回ゼロから」をやめるあるCIの所要時間(秒・例)改善前(直列)依存インストールDockerビルドテスト9分改善後Dockerテスト1/3テスト2/3テスト3/3約3分依存のキャッシュ(actions/cache)、Dockerのレイヤーキャッシュ(BuildKit)、テストの分割実行(matrix)変更のない所は動かさない(paths)、重いジョブは大きいランナー、古い実行は concurrency で止めるDockerfileは「変わりにくいもの(依存)を先、変わりやすいもの(コード)を後」に書く
ビルド高速化の効果(例)

まず計測し、一番長いジョブから手をつける。考え方はパフォーマンスチューニングと同じ。

面接ではこう答える

CIの時間は、依存とDockerレイヤーのキャッシュ、テストの並列化、変更のない部分を動かさないpathsフィルタ、古い実行の自動停止で縮めます。Dockerfileは変わりにくいものを先に書いてキャッシュを効かせます。まずジョブごとの時間を計測し、一番長いところから改善します。CIの速さは障害時の復旧時間にも効きます。

論点回答の要点
state の管理S3 に保存し、DynamoDB(または S3 のネイティブロック)で排他制御。暗号化とバージョニング
state の分割環境ごと、ライフサイクルごと(ネットワーク、DB、アプリ)に分けて変更の影響範囲を小さくする
drift手動変更との差分。定期的な plan で検知し、手動変更を禁止する
既存リソースの取り込みimport ブロックで管理下に入れる
秘密情報state に平文で残ることがあるため state へのアクセスを絞る
危険な変更の防止prevent_destroy、plan の差分レビュー、本番 apply の承認フロー
モジュールのバージョン管理バージョンを固定し、段階的に更新する
ひとことで

インフラの変更も、アプリと同じく「PRでレビューし、仕組みで適用する」。人が手元からapplyしない。

Terraformなどで書いたインフラは、変更の影響が大きく、間違えるとリソースを削除してしまいます。そのため、PRを作るとCIがplanを実行して差分をコメントし、レビューと承認を経て、CIだけがapplyする流れを仕組みで強制します。人の端末から本番にapplyできる権限は持たせません。

設計の選択肢内容トレードオフ
マージ前にapplyPRの上でapplyし、成功したらマージ(Atlantis型)mainと実環境が常に一致。同時に複数のPRを扱う工夫が必要
マージ後にapplymainにマージされたらapply流れが単純。applyが失敗するとmainと実環境がずれる
環境の昇格同じモジュールを開発→ステージング→本番の順に適用本番だけの差分を作らない
stateの分け方ネットワーク・DB・アプリなど、変更頻度と影響範囲で分ける細かすぎると依存関係の管理が大変
ポリシーの自動検査OPA、Checkov、tfsecなどで危険な設定を拒否ルールの保守が必要
実行基盤GitHub Actions、Atlantis、HCP Terraform、Spaceliftなどロック、承認、監査ログの機能で選ぶ

planのレビューでは、特に削除(destroy)と置き換え(replace)を確認します。DBやボリュームの置き換えはデータの消失につながるので、prevent_destroyで守ります。手動で変更された差分(drift)は定期的なplanで検知し、コードに取り込むか元に戻します。

IaCは「PRでplanを見て、承認後にapply」を仕組みで強制する1 ブランチで変更モジュール・変数を修正2 PRでplanCIがplanを実行し結果をPRにコメント3 レビュー差分(特に削除・置き換え)を確認4 ポリシー検査OPA・Checkov等で危険な設定を拒否5 apply承認後にCIだけが実行(人は直接しない)6 環境を順に開発→ステージング→本番7 driftの検知定期的にplanして手動変更を見つける8 ロールバック前のコミットに戻してapply
IaCのデプロイフロー

「planを見ずにapply」と「手元からapply」をなくすのが最初の一歩。

面接ではこう答える

インフラの変更はPRで行い、CIがplanを実行して差分をPRに表示し、レビューと承認の後にCIだけがapplyします。人の端末から本番にapplyする権限は持たせません。マージ前にapplyするかマージ後かを決め、環境は開発から本番へ順に適用し、stateは影響範囲で分けます。planでは削除と置き換えを重点的に確認し、ポリシー検査とdriftの検知を自動化します。

10.21コンテナの仕組み

用語★★★ 必須
ひとことで

コンテナは「特別な見え方と制限をつけた普通のプロセス」。仮想マシンのようにOSを丸ごと動かしているわけではない。

コンテナの中のプロセスも、ホストのLinuxカーネルの上で動く普通のプロセスです。違いは、namespaceで見える範囲を分け(自分のプロセスしか見えない、独自のネットワークやファイルシステムを持つ)、cgroupsで使えるCPUやメモリの量を制限していることです。OSを起動しないので軽く速く起動しますが、カーネルを共有しているので、カーネルの脆弱性は全コンテナに影響します。

仕組み役割例
PID namespaceプロセス番号を分けるコンテナ内では自分がPID 1に見える
NET namespaceネットワークを分けるコンテナごとに別のIPとポート
MNT namespaceファイルシステムを分けるイメージの中身だけが見える
cgroups(CPU)CPU時間を制限上限を超えるとスロットリングで遅くなる
cgroups(メモリ)メモリ量を制限上限を超えるとOOMKilled
VMはOSごと分け、コンテナはカーネルを共有してプロセスを分ける仮想マシンアプリアプリアプリゲストOSゲストOSゲストOSハイパーバイザーホストのハードウェアコンテナアプリアプリアプリコンテナランタイムホストのLinuxカーネル(共有)ホストのハードウェアコンテナを分ける仕組みnamespace:見えるものを分ける(PID・NET・MNT)cgroups:使える量を制限(CPU・メモリ)VM:隔離が強い、起動は数十秒〜分、重いコンテナ:軽く速い、カーネルの脆弱性は全体に影響
仮想マシンとコンテナの違い

コンテナのメモリ上限はcgroupsで決まるので、ホストに空きがあってもOOMKilledになる。

面接ではこう答える

コンテナは、namespaceで見える範囲を、cgroupsで使える資源の量を制限した普通のプロセスです。ホストのカーネルを共有するので軽く速い反面、隔離は仮想マシンより弱くなります。

項目コンテナ仮想マシン
隔離の仕組みnamespace(PID、ネットワーク、マウント等)と cgroupsハイパーバイザー
カーネルホストと共有ゲストごとに独立
起動時間秒以下〜数秒数十秒〜分
隔離の強さ弱め(カーネルの脆弱性の影響を受ける)強い
補足Fargate は Firecracker(軽量VM)でタスクを隔離

コンテナは、アプリと必要なライブラリを1つにまとめ、どのサーバーでも同じように動かせる形にしたものです。Kubernetes(k8s)は、たくさんのコンテナを複数のサーバー(ノード)に配置し、落ちたら作り直し、負荷に応じて数を増減させる仕組みです。コンテナは Pod という単位で動かし、Pod への入口として、変わらない名前と IP を持つ Service を置きます。

SRE は「アプリが動く土台」として、Pod の状態の見方や、リソースの設定・ヘルスチェック(Probe)の設計を問われます。設定を誤ると、正常な Pod が再起動を繰り返したり、リクエストを取りこぼしたりします。

テーマ要点
Probeliveness(再起動判断)、readiness(Serviceから外す判断)、startup(起動の遅いアプリ用)
requests / limitsrequests はスケジューリング、limits は上限。メモリ超過は OOMKilled、CPU超過はスロットリング
HPA / Cluster AutoscalerPod 数の自動調整とノード数の自動調整
PodDisruptionBudgetメンテナンス時に同時に落ちる Pod 数を制限
よくある障害CrashLoopBackOff、ImagePullBackOff、Pending(リソース不足)の調べ方(describe、logs、events)
ECS と EKS の選択ECS(Fargate)は運用が軽い。EKS は柔軟だがクラスタ運用・アップグレードの負担

第11章「セキュリティ」:コンテナセキュリティを図で詳しく

下の「ブラウザで試す」の図では、クラウドの LB から Ingress を通って Pod に届き、その Pod が別のサービスを Service の名前(CoreDNS で引く)と仮想の IP(kube-proxy の規則で本物の Pod の IP に書き換える)で呼ぶまでを順に見られます。表の Probe に関係するのは後半で、readiness probe に失敗した Pod が再起動されずに振り分け先から外されるところに注目してください(再起動するのは liveness probe です)。

別のページで開く →

ネットワーク図を読み込んでいます…

Kubernetes で Pod がうまく動かないとき、kubectl get pods の STATUS 欄に Pending・CrashLoopBackOff のような状態の名前が出ます。名前を見れば、ノードへの配置(スケジューリング)・イメージの取得・起動後のアプリ・通信のどこで止まっているかの見当がつきます。

障害対応では、まず状態の名前で段階を絞り、次に kubectl describe の Events や kubectl logs で原因を確かめる、という順番が基本です。面接でも「CrashLoopBackOff になったらどう調べるか」はよく聞かれます。

症状意味主な原因調べ方
PendingPod がノードに配置されないリソース不足、nodeSelector / taint の不一致、PVC が作れないkubectl describe pod の Events
CrashLoopBackOff起動しては落ちるを繰り返すアプリのエラー、設定の誤り、liveness probe の失敗kubectl logs --previous
ImagePullBackOffイメージを取得できないイメージ名・タグの誤り、レジストリの認証describe の Events
OOMKilledメモリ上限を超えて強制終了limits が小さい、メモリリークdescribe の Last State
Evictedノードのリソース不足で退避ノードのディスクやメモリの逼迫kubectl get events、ノードの状態
Service に繋がらない通信が届かないselector の不一致、readiness 失敗、NetworkPolicykubectl get endpoints

下の「ブラウザで試す」の図は Pod の通信の流れなので、表のうち関係するのは最後の「Service に繋がらない」です。Pod が Service の名前を CoreDNS で引き、kube-proxy の規則で Ready な Pod の IP に書き換えられて届くまでと、readiness probe に失敗した Pod が振り分け先から外れるところを見られます。kubectl get endpoints が空になるのは、selector が Pod に一致していないか、Ready な Pod が1つもないときだ、と結び付けて見てください。

別のページで開く →

ネットワーク図を読み込んでいます…

項目ECS(Fargate)EKS
運用負荷小さい(ノード管理不要)大きい(クラスタ・アドオンのアップグレード)
柔軟性AWS の範囲内高い(エコシステム、Operator、Helm)
学習コスト低い高い
移植性AWS に依存他のクラウドやオンプレにも持っていきやすい
向いている組織少人数のSREで運用したい専任チームがあり、高度な制御が必要

この章のまとめ

🖨 まとめシート(印刷・PDF)
  • 単一障害点をなくし、マルチAZを基本形にする
  • RTO・RPOのビジネス要件から構成とコストを選ぶ
  • 障害の多くは変更が原因。デプロイと設定変更を安全にする仕組みが重要
  • ロードバランサー:複数のサーバーに処理を振り分け、壊れたサーバーを自動で外す。振り分け方、ヘルスチェック、外すときの待ち方が運用の肝。
  • Git の運用(ブランチ戦略・マージ・切り戻し):変更の履歴を残し、壊れたら戻せるようにする道具と、その使い方の決まり。変更の入口を Git にそろえると、障害の原因の特定と切り戻しが速くなる。
  • GitOps(Git を本番の唯一の入口にする):あるべき姿を Git に宣言し、同期の仕組み(Argo CD・Flux)がクラスタを合わせ続けるやり方。
  • CI/CDとGitHub Actions:PRで自動検証し、マージ後に段階的にデプロイする。AWSへの認証はOIDCで鍵を持たない。ワークフロー自体もセキュリティの対象。
  • CIランナーの選び方と運用:ランナーはCIのジョブを実際に動かすマシン。手間・速さ・社内ネットワークへの到達・安全性・コストのバランスで選ぶ。
  • ビルド・CIの高速化:CIの待ち時間は、開発の速さと障害時の復旧の速さに直結する。キャッシュ・並列化・やらなくてよいことをやめる、の3つで縮める。
  • IaCのデプロイフロー戦略:インフラの変更も、アプリと同じく「PRでレビューし、仕組みで適用する」。人が手元からapplyしない。
  • コンテナの仕組み:コンテナは「特別な見え方と制限をつけた普通のプロセス」。仮想マシンのようにOSを丸ごと動かしているわけではない。

この章のクイズ

面接ではこう聞かれる

まず答えを見ずに声に出して答え、そのあと開いて比べる。

Q1可用性の高いWebサービスの構成をAWSで設計してください。

模範回答

DNSはRoute 53、前段にCloudFrontとWAFを置き、ALBを複数AZに配置します。アプリはECSやEKSで複数AZに最低2台以上、セッションは外部に持ってステートレスにします。DBはMulti-AZのRDSかAuroraで、読み取りが多ければリードレプリカとキャッシュを使います。NAT GatewayもAZごとに置き、AZ障害で外向き通信が全滅しないようにします。そのうえで、要件次第でバックアップを別リージョンへコピーします。

深掘りされたら

  • マルチリージョンにすべきかはどう判断しますか?
  • この構成の単一障害点はどこですか?

見られているポイント単一障害点の洗い出しと要件からの判断

Q2デプロイ戦略をどう選びますか?

模範回答

リソースを抑えたいならローリング、即座に切り戻したいならブルー/グリーン、影響を限定して検証したいならカナリアです。どれを選んでも、デプロイ後のエラー率やレイテンシを見て自動で戻す仕組みと、DB変更を後方互換に保つExpand/Contractの手順をセットにすることが大事です。

深掘りされたら

  • カナリアの成功判定はどう決めますか?
  • DBのスキーマ変更とアプリのデプロイはどちらを先にしますか?

見られているポイント切り戻しを前提にした考え方

Q3RTOとRPOとは?どう構成に反映しますか?

模範回答

RTOは復旧までに許される時間、RPOは失ってよいデータの期間です。ビジネス側と、止まると1時間あたりどれだけ損失が出るかを確認して決めます。数時間でよければバックアップからの復元、数分ならウォームスタンバイ、ほぼゼロならマルチサイトと、要件が厳しいほどコストが上がります。決めたら実際に復元訓練をして、目標を満たせるか確かめます。

深掘りされたら

  • バックアップがあっても復旧できないのはどんなとき?

見られているポイント要件とコストの釣り合い

Q4Terraformのstateをチームでどう管理しますか?

模範回答

S3にリモート保存し、ロックで同時実行を防ぎ、暗号化とバージョニングを有効にします。stateは環境やライフサイクルごとに分割して、一度のapplyの影響範囲を小さくします。CIでplanを出してレビューし、本番のapplyは承認後に行います。手動変更は禁止し、定期的なplanでdriftを検知します。

深掘りされたら

  • stateが壊れたらどう復旧しますか?

見られているポイント安全に変更する仕組み

Q5Podが CrashLoopBackOff になっています。どう調べますか?

模範回答

kubectl describe pod でイベントと直前の終了理由を確認し、kubectl logs --previous で落ちる直前のログを見ます。OOMKilledならメモリの上限、設定値や環境変数の誤り、依存先への接続失敗、livenessプローブが厳しすぎて再起動されている、などを順に疑います。直前の変更があれば戻すことも検討します。

深掘りされたら

  • Pending のままの場合は?

見られているポイント調べる順序

Q6クラウドコストをどう下げましたか?

模範回答

まずタグでサービスやチームごとにコストを見える化し、大きいものから手をつけます。使っていないリソースの削除、サイズの見直し、Savings Plansやスポットの活用、Gravitonへの移行、NAT Gateway経由の通信の削減などです。信頼性を落とさない範囲で行い、削減額を数字で報告します。

深掘りされたら

  • 信頼性とコストがぶつかったらどう判断しますか?

見られているポイント見える化から始めているか

Q7デプロイのたびに一瞬502エラーが出ます。何を疑いますか?

模範回答

LBから古いタスクを外すときに、処理中のリクエストを待たずに止めている可能性を疑います。登録解除の遅延が短すぎないか、アプリがSIGTERMを受けたあとに新しい受付を止めて処理中のものを終えるグレースフルシャットダウンをしているかを確認します。また、LBのアイドルタイムアウトよりアプリのKeep-Aliveのタイムアウトが短いと、閉じた接続にLBが送って502になるので、その設定も確認します。新しいタスクがヘルスチェックに合格する前にトラフィックが流れていないかも見ます。

深掘りされたら

  • ヘルスチェックのパスでは何を確認させますか?

見られているポイントLBとアプリの両方の設定を結びつけて考えられるか

Q8CIが遅いと開発チームから相談されました。どう改善しますか?

模範回答

まずジョブごとの所要時間を計測し、一番長いところから手をつけます。依存のインストールはロックファイルをキーにキャッシュし、DockerビルドはBuildKitのキャッシュを使い、Dockerfileを依存→コードの順にしてキャッシュを効かせます。テストは分割して並列に実行し、モノレポならpathsフィルタで変更のないサービスを動かしません。同じPRの古い実行はconcurrencyで止めます。それでも重いジョブには大きいランナーを使います。

深掘りされたら

  • CIの速さはSREにとってなぜ重要ですか?

見られているポイント計測から始める改善

Q9Terraformの変更はどういうフローで本番に反映していますか?

模範回答

PRを作るとCIがplanを実行して差分をPRにコメントし、レビューでは特に削除と置き換えを確認します。ポリシー検査も自動で行い、承認後にCIだけがapplyします。人の端末からは本番にapplyできないようにしています。同じモジュールを開発、ステージング、本番の順に適用し、stateは影響範囲で分けています。定期的にplanを実行して、手動の変更(drift)を検知しています。

深掘りされたら

  • applyが途中で失敗したらどうしますか?

見られているポイントレビューと権限の仕組み化

Q10CIのランナーはどう選びますか?

模範回答

基本はGitHubホストの標準ランナーで、管理不要で毎回まっさらな環境なので安全です。重いビルドだけLarger runnersを使い、VPC内のDBなどに届く必要があるジョブは、セルフホストかCodeBuildのランナーのような使い捨ての環境で動かします。セルフホストを使う場合は、ジョブごとに使い捨てにし、本番にデプロイできるランナーとPRのテスト用を分け、公開リポジトリでは使いません。費用は分単位の課金と、インスタンス費用・運用工数を合わせて比べます。

深掘りされたら

  • セルフホストランナーが乗っ取られると何が起きますか?

見られているポイント速さ・到達性・安全性・コストのバランス

Q11本番で障害が起きたとき、Git の運用はどう役に立ちますか?

模範回答

まず「直前に何が変わったか」を Git の履歴とデプロイの記録で確かめます。障害の多くは変更がきっかけなので、変更が小さく、コミットやPRに理由と課題番号が残っていれば、原因の候補をすぐ絞れます。怪しい変更があれば、原因を調べ切る前に revert で戻して影響を止めます。squash merge で「1 PR=1コミット」にしておくと、戻すのも1回で済みます。インフラも GitOps や Terraform で同じ流れに乗せておけば、手作業の変更による見えない差分も防げます。

深掘りされたら

  • merge と rebase はどう使い分けますか?
  • 秘密情報を誤ってコミットしたらどうしますか?

見られているポイント変更の追跡と素早い切り戻し・ブランチ保護・インフラも同じ流れ