イミュータブルインフラストラクチャ

サーバーを変更せず、新しいイメージで丸ごと置き換えるインフラ運用手法

インフラDevOps

イミュータブルインフラストラクチャとは

イミュータブルインフラストラクチャは、デプロイ済みのサーバーに変更を加えず、新しいイメージ (AMI、コンテナイメージ) で丸ごと置き換えるインフラ運用手法である。「サーバーに SSH してパッチを当てる」のではなく「新しいサーバーを作って古いサーバーを捨てる」。

ミュータブル vs イミュータブル

分かれ目は「更新のときにサーバーへ手を入れるか」の一点である。ここが変わると、状態の揃い方・再現性・ロールバックのしやすさまで連鎖して変わる。

観点ミュータブルイミュータブル
更新方法SSH でパッチ適用新イメージで置き換え
状態サーバーごとに異なる同じイメージから起動した台は揃う
再現性低い (手動変更の蓄積)高い (イメージから再現)
ロールバック困難 (変更を戻す)旧イメージに戻すだけ (データ形式の変更を伴う場合は別途対処)
構成ドリフト発生する起動後に手を入れなければ発生しない

構成ドリフト

ミュータブルなサーバーでは、手動変更が蓄積して「本番サーバー A と B で設定が微妙に違う」状態 (構成ドリフト) が発生する。

ミュータブル:
  サーバー A: OS パッチ適用済み、設定ファイル手動変更
  サーバー B: OS パッチ未適用、設定ファイルは元のまま
  → 「A では動くが B では動かない」

イミュータブル:
  サーバー A: イメージ v1.2.3 から起動
  サーバー B: イメージ v1.2.3 から起動
  → 完全に同一

置き換えの最中は、新しいイメージの台と古いイメージの台が同時に動く時間が必ずある。どちらに振り分けられても壊れないこと (アプリケーションの前後互換) が、この運用の隠れた前提になる。

AWS での実装

「置き換え」の単位はサービスによって違う。

パターン方法
Lambdaコードを更新すると、次の呼び出しから新しい実行環境が使われる
ECS / Fargate新しいコンテナイメージでタスクを置き換え
EC2 + ASG新しい AMI を指定した Launch Template のバージョンを作り、インスタンスリフレッシュで順次入れ替える (既定の方式は稼働台数を保ちながらバッチで置き換える)
S3 + CloudFront内容ごとに別のファイル名 (ハッシュ付き) で追加し、参照する HTML を差し替える。同じキーへの上書きは変更操作なので、この運用からは外れる

コンテナとイミュータブルインフラ

コンテナはこの運用と相性が良い。Dockerfile でイメージをビルドし、実行中のコンテナには変更を加えない。厳密には、コンテナには書き込み可能な層があるので中で変更はできるが、その変更はコンテナを破棄した時点で消える。残したい変更は次のイメージに入れるしかない、という規律が自然に効く。

Dockerfile → docker build → イメージ (イミュータブル)
                              ↓
                           コンテナ起動 → 問題があれば破棄して新しいコンテナを起動

前提条件

サーバーをいつでも捨てられるようにするには、捨てても困らない状態を先に作っておく必要がある。

前提理由
IaC (SAM, CloudFormation)インフラをコードで再現可能にする
CI/CD パイプラインイメージのビルド・デプロイを自動化
外部ストレージ置き換えで消えないよう、データは S3 や DynamoDB などサーバーの外に置く
ログの外部送信インスタンスを破棄するとローカルのログも一緒に消えるため、CloudWatch Logs などへ送り出しておく

サーバーレスとの関係

Lambda では、サーバーを自分で置き換える作業そのものがなくなる。コードを更新すれば、次の呼び出しから新しい実行環境が使われる。

ただし「呼び出しごとに真っ新」ではない。実行環境は同じ関数バージョンの複数の呼び出しで再利用され、グローバル変数に持った値や /tmp に書いたファイルは環境が壊されるまで残る。持ち越したくないデータは自分で消すか、そもそも書かないのが安全側である。

イミュータブルインフラストラクチャの背景や設計思想は関連書籍に詳しい。

この記事は役に立ちましたか?

関連用語

関連する記事