✈️ 飛行機の機材変更で例えると超わかりやすい!
古い飛行機から新しい飛行機への乗客移動 = OSアップデート🛫
飛行中の飛行機(稼働中のサーバー)のOSをアップデートしたい!
でも、
乗客(ユーザー)には一切気づかれたくない
😱
どうする? →
新しい飛行機を用意して、乗客を徐々に移動させる!
✈️→✈️
これが今日学ぶ
「ダウンタイムゼロのOSアップデート戦略」
です。
7つのステップ
で完璧に実現できます✨
✈️ 飛行機の機材変更に例えると...
古い飛行機(旧OS)
• 20年前のモデル(古いOS)
• 100人の乗客が搭乗中(稼働中のサービス)
• セキュリティアップデートが必要
• でも飛行中に作業は不可能
❌ 悪い方法:
飛行中に空中でエンジンを交換?
→ 墜落します!(システムダウン)
🤔 どうすれば?
乗客を降ろさずに、新しい機体に移動させたい...
新しい飛行機(新OS)
• 最新モデル(新しいOS)
• 同じ100人の乗客(継続稼働)
• セキュリティ完璧
• 乗客は移動に気づかない
✅ 正しい方法:
1. 新しい飛行機を100機準備
2. 乗客を1人ずつ新しい機体へ
3. 古い機体は順次着陸
4. 最終的に全員が新機体に!
🎉 これで完璧な移行!
• Blue = 古い環境(古いOS)
• Green = 新しい環境(新しいOS)
• Rolling = 徐々に切り替え
Auto Scalingグループを 2倍に拡大 して、
古いインスタンスを 徐々に削除 していく手法です。
🎯 ダウンタイム: 完全にゼロ!
🎯 7つのステップで完璧なアップデート
Step 1
新しいAMI作成
最新の飛行機を設計
📋 実際の作業:
• 最新OSでEC2起動
• セキュリティパッチ適用
• 会社標準に準拠
• アプリインストール
• AMIとして保存
重要度: ★★★★★
Step 2
起動設定を更新
新機体の運航許可取得
📋 実際の作業:
• 新しいLaunch Configuration作成
• 新AMIを指定
• Auto Scalingグループに設定
• 古い設定は保持
💡 ポイント:
Launch Templateの使用推奨
重要度: ★★★★☆
Step 3
終了ポリシー設定
「古い機体から順に着陸」ルール
📋 実際の作業:
• Termination Policy設定
•
OldestLaunchConfiguration
• 古い設定のインスタンスから削除
• 新しいものは保護
🎯 これが超重要!
これで新旧を区別できる
重要度: ★★★★★
Step 4
グループを2倍に
新機体を100機追加
(合計200機に)
📋 実際の作業:
• Desired Capacity × 2
• 例: 10台 → 20台
• 新AMIで10台起動
• 古い10台はそのまま
💰 一時的にコスト2倍
でも短時間で済む
重要度: ★★★★★
Step 5
ヘルスチェック待機
新機体の離陸準備完了確認
📋 実際の作業:
• ELBヘルスチェック通過待ち
• InService状態確認
• アプリが正常起動
• 準備完了まで待機
⏱️ 待機時間:
通常5-10分程度
重要度: ★★★★☆
Step 6
元のサイズに戻す
古い機体を順次着陸させる
📋 実際の作業:
• Desired Capacity を元に戻す
• 例: 20台 → 10台
• Auto Scalingが自動削除
• OldestLaunchConfigurationから削除
• = 古いインスタンスが削除される
🎉 新しいインスタンスだけ残る!
重要度: ★★★★★
Step 7
セキュリティ強化
コックピットへの不正侵入防止
📋 実際の作業:
• EC2インスタンスコンソールアクセス無効
• Systems Manager Session Manager使用
• SSHキー不要に
• 監査ログ完全記録
🛡️ セキュリティ最強化!
直接ログイン禁止
重要度: ★★★★☆
🔄 詳細な実行フロー
• Auto Scalingグループ: 10インスタンス
• 全て古いAMI(例: ami-old-12345)
• Launch Configuration: lc-old-v1
• ユーザー: 1000人が利用中
• ダウンタイム許容: 0秒
🎯 目標: 全インスタンスを新OSに更新
# 1. 新しいAMI作成(既存インスタンスから) aws ec2 create-image \ --instance-id i-xxxxx \ --name "app-v2-2025-01-01" \ --description "Updated OS with security patches" # 2. 新しいLaunch Configuration作成 aws autoscaling create-launch-configuration \ --launch-configuration-name lc-new-v2 \ --image-id ami-new-67890 \ --instance-type t3.medium \ --security-groups sg-xxxxx # 3. Auto Scalingグループを更新 aws autoscaling update-auto-scaling-group \ --auto-scaling-group-name my-asg \ --launch-configuration-name lc-new-v2
aws autoscaling update-auto-scaling-group \ --auto-scaling-group-name my-asg \ --termination-policies "OldestLaunchConfiguration" # これで古いLaunch Configurationのインスタンスから削除される
• この設定がないと新インスタンスも削除される可能性
• 必ずOldestLaunchConfigurationを指定
• 他のポリシー(OldestInstance等)は不可
aws autoscaling set-desired-capacity \ --auto-scaling-group-name my-asg \ --desired-capacity 20 # 元は10台 # Auto Scalingが自動的に新しいLaunch Configで10台起動
1. Auto Scalingが不足を検出(10台足りない)
2. 新Launch Configuration(lc-new-v2)で起動
3. 新AMI(ami-new-67890)を使用
4. ELBに自動登録
5. ヘルスチェック開始
⏱️ 所要時間: 5-10分
# Auto Scalingグループのインスタンス状態確認 aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names my-asg \ --query "AutoScalingGroups[0].Instances[*].[InstanceId,HealthStatus,LifecycleState]" # 出力例: # i-old-001 Healthy InService ← 古いインスタンス # i-old-002 Healthy InService # ... # i-new-001 Healthy InService ← 新しいインスタンス # i-new-002 Healthy InService # ...
• 全20台がInService
• ELBヘルスチェック通過
• アプリケーション正常応答
• エラーログなし
💡 この時点で新旧両方が稼働中!
aws autoscaling set-desired-capacity \ --auto-scaling-group-name my-asg \ --desired-capacity 10 # 元に戻す # Auto Scalingが自動処理: # 1. 過剰な10台を削除対象に # 2. 終了ポリシー「OldestLaunchConfiguration」に従う # 3. 古いlc-old-v1のインスタンスを1台ずつ削除 # 4. ELBから登録解除してから削除 # 5. 新しいインスタンスはそのまま残る
1. ELBから登録解除(Deregister)
2. Connection Draining(既存接続の完了待ち)
3. インスタンス終了
4. 次のインスタンスへ
⏱️ 所要時間: 10-20分(10台削除)
🎉 完了後: 新OSの10台だけが稼働!
1. EC2インスタンスコンソールアクセス無効化:
• Security GroupからSSH(22)削除
• KeyPairを使用しない設定
• Systems Manager経由のみ許可
2. Systems Manager設定:
# IAMロールにSSM権限付与(インスタンスプロファイル) { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ssm:UpdateInstanceInformation", "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" }] } # これでAWSコンソールから安全にログイン可能 # セッションは全てCloudTrailに記録される
• Systems Manager Automationドキュメント作成
• 定期パッチ適用の自動化
• 障害時の自動復旧スクリプト
✅ セキュリティと運用性が大幅向上!
📊 ビジュアル図解: インスタンスの遷移
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
全て古いAMI(ami-old-12345)で稼働中
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
新しいAMI(ami-new-67890)で10台追加起動
一時的にコスト2倍だが、全てがInServiceで稼働中
削除中
削除中
削除中
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-old
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
OldestLaunchConfigurationポリシーにより
古いインスタンスから順次削除(ELBから登録解除後)
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
ami-new
🎉 全て新しいAMI(ami-new-67890)に更新完了!
ダウンタイム: 0秒 | ユーザーへの影響: なし
📊 他の更新手法との比較
| 手法 | ダウンタイム | リスク | コスト | 推奨度 |
|---|---|---|---|---|
| この手法(Blue/Green + Rolling) | 0秒 | 超低 | 一時的に2倍 | ★★★★★ |
| 全停止→更新→再起動 | 30-60分 | 高 | 増加なし | ★☆☆☆☆ |
| Rolling Update(1台ずつ) | 部分的 | 中 | 増加なし | ★★★☆☆ |
| インプレース更新(yum update) | 一時的 | 超高 | 増加なし | ★★☆☆☆ |
| Blue/Green(完全切替) | 0秒 | 低 | 常時2倍 | ★★★★☆ |
✅ メリット:
• ダウンタイム完全ゼロ
• リスク最小(問題あれば即ロールバック)
• コストは一時的のみ(15-30分程度)
• ユーザーへの影響なし
• 自動化が容易
⚠️ 注意点:
• 一時的にキャパシティが2倍必要
• 15-30分程度コストが増加
• でも本番環境ではこれが最適!
💡 実務では圧倒的にこれが推奨されます
• 開発環境で完全にテスト
• 新AMIの動作確認
• ヘルスチェック通過を確認
• タイミング(15-30分)を計測
2. メンテナンス時間帯を選ぶ
• ダウンタイムはゼロだが念のため
• 低トラフィック時間帯(深夜など)
• ビジネスアワーは避ける
• チーム全員が待機できる時間
3. モニタリングを強化
• CloudWatch Alarmsを設定
• エラー率、レスポンスタイムを監視
• 新旧両方のメトリクスを比較
• 異常があれば即座にロールバック
4. ロールバック手順を準備
• 古いLaunch Configurationを保持
• 問題発生時の切り戻し手順書
• ワンコマンドでロールバック可能に
• 5分以内に元に戻せるように
5. 段階的なロールアウト
• 最初は小規模環境で実施
• 問題なければステージング
• 最後に本番環境
• 複数リージョンある場合は1つずつ
6. 通知設定
• SNSトピック設定
• Auto Scaling イベントを通知
• Slackに自動投稿
• チーム全員が状況把握
7. コスト最適化
• 一時的な2倍期間を最小化
• Connection Draining時間を調整
• 不要な待機時間を削減
• 通常15-20分で完了するように調整
8. 自動化スクリプト化
• 全ステップをスクリプト化
• AWS CLI / Boto3 / Terraform
• 人的ミスを排除
• CI/CDパイプラインに組み込み
💻 完全な実装スクリプト例
#!/bin/bash # Auto Scaling安全なOSアップデートスクリプト set -e # エラーで停止 # 設定 ASG_NAME="my-auto-scaling-group" NEW_AMI="ami-new-67890" NEW_LC_NAME="lc-new-v2-$(date +%Y%m%d)" # 現在の設定を取得 echo "📊 現在の設定を取得中..." CURRENT_CAPACITY=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names ${ASG_NAME} \ --query "AutoScalingGroups[0].DesiredCapacity" \ --output text) echo "現在のCapacity: ${CURRENT_CAPACITY}" # Step 1: 新Launch Configuration作成 echo "🔧 Step 1: 新Launch Configuration作成..." aws autoscaling create-launch-configuration \ --launch-configuration-name ${NEW_LC_NAME} \ --image-id ${NEW_AMI} \ --instance-type t3.medium \ --security-groups sg-xxxxx \ --iam-instance-profile my-instance-profile \ --user-data file://userdata.sh # Step 2: Auto Scalingグループ更新 echo "🔄 Step 2: Auto Scalingグループ更新..." aws autoscaling update-auto-scaling-group \ --auto-scaling-group-name ${ASG_NAME} \ --launch-configuration-name ${NEW_LC_NAME} \ --termination-policies "OldestLaunchConfiguration" # Step 3: Desired Capacityを2倍に NEW_CAPACITY=$((${CURRENT_CAPACITY} * 2)) echo "📈 Step 3: Capacityを${CURRENT_CAPACITY}から${NEW_CAPACITY}に拡大..." aws autoscaling set-desired-capacity \ --auto-scaling-group-name ${ASG_NAME} \ --desired-capacity ${NEW_CAPACITY} # Step 4: 新インスタンスのInService待機 echo "⏳ Step 4: 新インスタンスの起動待機..." while true; do IN_SERVICE_COUNT=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names ${ASG_NAME} \ --query "length(AutoScalingGroups[0].Instances[?LifecycleState=='InService'])" \ --output text) echo " 現在InService: ${IN_SERVICE_COUNT}/${NEW_CAPACITY}" if [ ${IN_SERVICE_COUNT} -eq ${NEW_CAPACITY} ]; then break fi sleep 30 done echo "✅ 全インスタンスがInServiceになりました" # Step 5: 少し待機(安全のため) echo "⏱️ Step 5: 安定性確認のため2分待機..." sleep 120 # Step 6: Desired Capacityを元に戻す echo "📉 Step 6: Capacityを${CURRENT_CAPACITY}に戻す..." aws autoscaling set-desired-capacity \ --auto-scaling-group-name ${ASG_NAME} \ --desired-capacity ${CURRENT_CAPACITY} # Step 7: 旧インスタンス削除完了待機 echo "⏳ Step 7: 旧インスタンス削除待機..." while true; do CURRENT_COUNT=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names ${ASG_NAME} \ --query "length(AutoScalingGroups[0].Instances)" \ --output text) echo " 現在のインスタンス数: ${CURRENT_COUNT}" if [ ${CURRENT_COUNT} -eq ${CURRENT_CAPACITY} ]; then break fi sleep 30 done echo "🎉 完了!全インスタンスが新AMIに更新されました" # Step 8: 最終確認 echo "📊 最終状態:" aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names ${ASG_NAME} \ --query "AutoScalingGroups[0].Instances[*].[InstanceId,LaunchConfigurationName,HealthStatus]" \ --output table
1. AWS CLIがインストール済みであること
2. 適切なIAM権限があること
3. 変数(ASG_NAME, NEW_AMI)を環境に合わせて変更
4. テスト環境で動作確認
5. 本番環境で実行
⏱️ 実行時間:
• 10インスタンスの場合: 約15-20分
• 20インスタンスの場合: 約20-30分
• 50インスタンスの場合: 約30-45分
🎯 自動化のヒント:
• Jenkins / GitHub Actions / GitLab CIで実行
• 定期的なOSパッチ適用に使用
• Slack通知を追加してチーム共有
🎓 まとめ
✈️ 飛行機の乗客移動 = OSアップデート
新しい飛行機を用意して、乗客を徐々に移動させる🛫
これが
ダウンタイムゼロ
の秘訣!
7つのステップ
で完璧に実現できます✨
作成
更新
ポリシー
拡張
待機
戻す
強化
🎯 この手法の最大のメリット:
✅
ダウンタイム: 完全にゼロ
✅
リスク: 最小限
(問題あれば即ロールバック)
✅
ユーザー影響: なし
(気づかれない)
✅
自動化: 容易
(スクリプト化可能)
⚠️ 一時的にコスト2倍(15-30分)
でも
本番環境では絶対これ!
💡 覚えておくべき最重要ポイント:
「
OldestLaunchConfiguration
」
この終了ポリシーが全てのカギ🔑
これを設定するだけで、
Auto Scalingが賢く古いインスタンスだけを削除してくれます!
安全・確実・ダウンタイムゼロ!🚀✨