このドキュメントでは、マネージド インスタンス グループと永続ディスクのスナップショットを使用して、ウェブサーバーのコールド フェイルオーバー トポロジをデプロイする方法について説明します。このドキュメントは、運用チームと管理チームで作業するアーキテクトと担当者を対象としています。
データを格納する永続ディスクを持つ単一の VM を実行するマネージド インスタンス グループを作成します。永続ディスクの定期的なスナップショットを使用することにより、フェイルオーバーのシナリオでのデータ損失を最小限に抑えます。次の図に示すように、外部アプリケーション ロードバランサは、マネージド インスタンス グループで実行されている VM にユーザーを転送します。
インスタンスに障害が発生した場合、マネージド インスタンス グループが同じゾーンに VM の再作成を試みます。ゾーンレベルで障害が発生した場合、Cloud Monitoring などから問題の発生を通知して、別のゾーンまたはリージョンに別のマネージド インスタンス グループを手動で作成できます。どちらのフェイルオーバー シナリオでも、プラットフォームは最新の永続ディスクのスナップショットを使用して交換用ディスクを作成し、インスタンス グループ内の新しい VM にこのディスクをアタッチします。
このドキュメントでは、VM またはロードバランサの外部 IP アドレスを使用して、ウェブサーバーの基本ページを表示します。このアプローチでは、ドメイン名が登録されていない場合に、DNS の変更なしでコールド フェイルオーバーのパターンをテストできます。本番環境では、ロードバランサに割り当てられた外部 IP アドレスに解決される Cloud DNS ゾーンとレコードを作成して構成します。
このパターンでは、一定レベルのデータ保護を維持しながら、複数の VM またはリージョン永続ディスクを実行する費用の差のバランスを取ります。単一の VM と永続ディスクで実行すると、費用は抑えられますが、設定された間隔でのみ永続ディスクのスナップショットが取得されるため、データ損失のリスクがあります。データ損失の可能性を低減するには、代わりにリージョン永続ディスクを使用する復元可能なコールド ウェブサーバーをデプロイすることを検討してください。
次の表は、リージョン永続ディスクの場合と、永続ディスクのスナップショットを使用する復元可能なコールド アプローチの場合のデータ保護オプションの大まかな違いをまとめたものです。詳細については、永続ディスクを使用した高可用性オプションをご覧ください。
リージョン永続ディスク | 永続ディスクのスナップショット | |
---|---|---|
データ損失 - リカバリ ポイント目標(RPO) | 単一障害(ゾーンの継続的なサービス停止またはネットワークの切断など)の場合は 0。 | 最後のスナップショット取得(通常、1 時間以上)以降のデータ。 データ損失の可能性は、スナップショットの取得頻度を制御するスナップショット スケジュールによって異なります。 |
目標復旧時間(RTO) | 新しい VM のデプロイ時間とリージョン永続ディスクの再アタッチのかかる秒数。 | 新しい VM のデプロイ時間、および最新のスナップショットから新しい永続ディスクを作成する時間。 ディスクの作成時間は、スナップショットのサイズによって異なり、数十分から数時間かかることがあります。 |
費用 | リージョン永続ディスクが別のゾーンに継続的に複製されると、ストレージ費用が倍増します。 | 費用は、消費したスナップショットの容量に対してのみ発生します。 |
詳細については、ディスクとイメージの料金をご覧ください。 |
目標
- マネージド インスタンス グループを作成し、永続ディスクがアタッチされた VM を実行する。
- 永続ディスクのスナップショットを定期的に取得するように、スナップショットのスケジュールを構成する。
- インスタンス テンプレートと起動スクリプトを作成する。
- 外部アプリケーション ロードバランサを作成して構成する。
- 代わりのマネージド インスタンス グループで、コールド ウェブサーバーのフェイルオーバーをテストする。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Compute Engine API を有効にします。
- Google Cloud CLI をインストールします。
-
gcloud CLI を初期化するには:
gcloud init
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Compute Engine API を有効にします。
- Google Cloud CLI をインストールします。
-
gcloud CLI を初期化するには:
gcloud init
Google Cloud CLI をインストールせずに、Google Cloud コンソールで Google Cloud CLI を実行できます。Google Cloud コンソールで gcloud CLI を実行するには、Cloud Shell を使用します。
環境を準備する
このセクションでは、リソース名とロケーションの変数を定義します。これらの変数は、リソースをデプロイするときに Google Cloud CLI コマンドによって使用されます。
このドキュメントを通じて、特に断りのない限り、Cloud Shell またはローカル開発環境ですべてのコマンドを入力します。
PROJECT_ID
は実際のプロジェクト ID に置き換えます。必要に応じて、リソースに独自の名前の接尾辞を指定します(app
など)。リージョン(
us-central1
など)と、そのリージョン内の 2 つのゾーン(us-central1-a
やus-central1-f
など)を指定します。これらのゾーンにより、最初の永続ディスクと最初のマネージド インスタンス グループがデプロイされる場所と、必要に応じて手動でフェイルオーバーできる場所が定義されます。PROJECT_ID=PROJECT_ID NAME_SUFFIX=app REGION=us-central1 ZONE1=us-central1-a ZONE2=us-central1-f
VPC とサブネットの作成
VM へのネットワーク アクセスを許可するには、Virtual Private Cloud(VPC)とサブネットを作成します。マネージド インスタンス グループは、1 つのリージョン内にある複数のゾーン間で動作するため、作成されるサブネットは 1 つだけです。お客様の環境で使用されている IP アドレスの範囲を管理するためのカスタム サブネット モードの利点については、カスタムモードの VPC ネットワークを使用するをご覧ください。
カスタム サブネット モードで VPC を作成します。
gcloud compute networks create network-$NAME_SUFFIX \ --subnet-mode=custom
Cloud Shell プロンプトが表示された場合は、この最初のリクエストを承認して API 呼び出しを行います。
新しい VPC にサブネットを作成します。ネットワーク範囲に適した独自のアドレス範囲(
10.1.0.0/20
など)を定義します。gcloud compute networks subnets create subnet-$NAME_SUFFIX-$REGION \ --network=network-$NAME_SUFFIX \ --range=10.1.0.0/20 \ --region=$REGION
ファイアウォール ルールの作成
ロードバランサおよびマネージド インスタンス グループ用のウェブ トラフィックとヘルスチェックを許可するファイアウォール ルールを作成します。
gcloud compute firewall-rules create allow-http-$NAME_SUFFIX \ --network=network-$NAME_SUFFIX \ --direction=INGRESS \ --priority=1000 \ --action=ALLOW \ --rules=tcp:80 \ --source-ranges=0.0.0.0/0 \ --target-tags=http-server gcloud compute firewall-rules create allow-health-check-$NAME_SUFFIX \ --network=network-$NAME_SUFFIX \ --action=allow \ --direction=ingress \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=allow-health-check \ --rules=tcp:80
HTTP ルールでは、
http-server
タグが適用されている VM や、0.0.0.0/0
範囲を使用している送信元からのトラフィックを許可します。ヘルスチェック ルールでは、Google Cloud のデフォルトが設定されており、プラットフォームがリソースの健全性を正しくチェックできるようになっています。ベース VM イメージの初期設定で SSH トラフィックを許可するには、
--source-range
パラメータを使用してファイアウォール ルールを環境に合わせて適用します。組織で使用するソース範囲を決定するには、ネットワーク チームの協力が必要な場合があります。IP_ADDRESS_SCOPE
を独自の IP アドレス スコープに置き換えます。gcloud compute firewall-rules create allow-ssh-$NAME_SUFFIX \ --network=network-$NAME_SUFFIX \ --direction=INGRESS \ --priority=1000 \ --action=ALLOW \ --rules=tcp:22 \ --source-ranges=IP_ADDRESS_SCOPE
ファイアウォール ルールを作成したら、3 つのルールが追加されていることを確認します。
gcloud compute firewall-rules list \ --project=$PROJECT_ID \ --filter="NETWORK=network-$NAME_SUFFIX"
次の出力例は、3 つのルールが正しく作成されたことを示しています。
NAME NETWORK DIRECTION PRIORITY ALLOW allow-health-check-app network-app INGRESS 1000 tcp:80 allow-http-app network-app INGRESS 1000 tcp:80 allow-ssh-app network-app INGRESS 1000 tcp:22
ベース VM イメージの作成と構成
追加構成なしでデプロイする同じ VM を作成するには、カスタム VM イメージを使用します。このイメージは、OS と Apache の構成をキャプチャし、次のステップでマネージド インスタンス グループの各 VM を作成するために使用されます。
永続ディスクを使用してアプリケーション データを保存します。このドキュメントでは、アプリケーションの処理に基本の Apache ウェブサイトを使用します。このドキュメントの後半では、この永続ディスクに関連付けられたスナップショット スケジュールを作成して、自動ディスク スナップショットを作成します。
VM で、永続ディスク上に基本的な index.html
ファイルを作成し、/var/www/example.com
にマウントします。/etc/apache2/sites-available/example.com.conf
の Apache 構成ファイルは、マウントされた永続ディスクの場所からウェブ コンテンツを提供します。
次の図は、永続ディスクに保存されている、Apache が提供する基本の HTML ページを示しています。
この環境は次の手順で構築します。
10 GiB の SSD を作成します。ストレージの要件とそれに関連する費用(使用される容量ではなくプロビジョニングされる容量)を把握します。詳細については、永続ディスクの料金をご覧ください。
gcloud compute disks create disk-$NAME_SUFFIX \ --zone $ZONE1 \ --size=10 \ --type=pd-ssd
永続ディスクがアタッチされたベース VM を作成します。
gcloud compute instances create vm-base-$NAME_SUFFIX \ --zone=$ZONE1 \ --machine-type=n1-standard-1 \ --subnet=subnet-$NAME_SUFFIX-$REGION \ --tags=http-server \ --image=debian-10-buster-v20210721 \ --image-project=debian-cloud \ --boot-disk-size=10GB \ --boot-disk-type=pd-balanced \ --boot-disk-device-name=vm-base-$NAME_SUFFIX \ --disk=mode=rw,name=disk-$NAME_SUFFIX,device-name=disk-$NAME_SUFFIX
このドキュメントの冒頭で定義したパラメータを使用して VM に名前を付け、正しいサブネットに接続します。名前はブートディスクとデータディスクのパラメータからも割り当てられます。
シンプルなウェブサイトをインストールして構成するには、まず SSH を使用してベース VM に接続します。
gcloud compute ssh vm-base-$NAME_SUFFIX --zone=$ZONE1
VM への SSH セッションで、任意のエディタで VM を構成するスクリプトを作成します。次の例では、Nano をエディタとして使用しています。
nano configure-vm.sh
このファイルに次の構成スクリプトを貼り付けます。このドキュメントの冒頭で設定した値(app など)と一致するように
NAME_SUFFIX
変数を更新します。#!/bin/bash NAME_SUFFIX=app # Create directory for the basic website files sudo mkdir -p /var/www/example.com sudo chmod a+w /var/www/example.com sudo chown -R www-data: /var/www/example.com # Find the disk name, then format and mount it DISK_NAME="google-disk-$NAME_SUFFIX" DISK_PATH="$(find /dev/disk/by-id -name "${DISK_NAME}" | xargs -I '{}' readlink -f '{}')" sudo mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard $DISK_PATH sudo mount -o discard,defaults $DISK_PATH /var/www/example.com # Install Apache, additional utilities, and cloud-init sudo apt-get update && sudo apt-get -y install apache2 moreutils cloud-init # Write out a basic HTML file to the mounted persistent disk sudo tee -a /var/www/example.com/index.html >/dev/null <<'EOF' <!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>HA / DR example</title> </head> <body> <p>Welcome to a test web server with persistent disk snapshots!</p> </body> </html> EOF # Write out an Apache configuration file sudo tee -a /etc/apache2/sites-available/example.com.conf >/dev/null <<'EOF' <VirtualHost *:80> ServerName www.example.com ServerAdmin webmaster@localhost DocumentRoot /var/www/example.com ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> EOF # Enable the Apache configuration file and reload service sudo a2dissite 000-default sudo a2ensite example.com.conf sudo systemctl reload apache2
ファイルを書き出してエディタを終了します。たとえば、Nano では、
Ctrl-O
を使用してファイルを書き出してからCtrl-X
で終了します。構成スクリプトを実行可能にして、実行します。
chmod +x configure-vm.sh ./configure-vm.sh
インスタンスに障害が発生し、マネージド インスタンス グループがこのベース VM から交換用ディスクを作成する必要がある場合、アプリケーション データが利用可能である必要があります。新しい VM ごとに次の手順が自動的に実行されます。
- メタデータ サーバーから情報を取得する。
- 永続ディスクの最新のスナップショットを取得する。
- この最新のスナップショットからディスクを作成する。
- 新しいディスクを VM にアタッチする。
- ディスクを VM 内にマウントする。
VM で必要な手順を実行する
app-startup.sh
という名前の起動スクリプトを作成します。この起動スクリプトは、次のステップでインスタンス テンプレートに適用されます。sudo mkdir /opt/cloud-init-scripts sudo tee -a /opt/cloud-init-scripts/app-startup.sh >/dev/null <<'EOF' #!/bin/bash # Install jq and get an access token for API requests apt-get install -y jq OAUTH_TOKEN=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \ -H "Metadata-Flavor: Google" --silent | jq -r '.access_token') # Make a request against the metadata server to determine the project name, # instance name, and what zone it's running in ZONE_INFO=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone \ -H "Metadata-Flavor: Google" --silent) PROJECT_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone \ -H "Metadata-Flavor: Google" --silent | awk -v FS="/" '{print $2}') ZONE_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone \ -H "Metadata-Flavor: Google" --silent | sed 's:.*/::') INSTANCE_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/name \ -H "Metadata-Flavor: Google" --silent) # Get the latest snapshot of the app disk LATEST_SNAPSHOT=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \ https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/global/snapshots \ --silent | jq -s '.[].items[] | select(.name | contains("disk-$NAME")) | .name' \ | sort -r | head -n 1 | tr -d '"') # Create a persistent disk using the latest persistent disk snapshot curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json; charset=utf-8" \ https://compute.googleapis.com/compute/v1/$ZONE_INFO/disks \ --data '{"name":"'$LATEST_SNAPSHOT'-restored","sizeGb":"10","type":"zones/'$ZONE_NAME'/diskTypes/pd-ssd","sourceSnapshot":"https://www.googleapis.com/compute/v1/projects/'$PROJECT_NAME'/global/snapshots/'$LATEST_SNAPSHOT'"}' # Wait for the persistent disk to be created from the disk snapshot DISK_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \ https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/disks/$LATEST_SNAPSHOT-restored \ --silent | jq -r .status) while [ $DISK_STATUS != "READY" ] do sleep 2 DISK_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \ https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/disks/$LATEST_SNAPSHOT-restored \ --silent | jq -r .status) done # Attach the new persistent disk created from the snapshot to the VM curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json; charset=utf-8" \ https://compute.googleapis.com/compute/v1/$ZONE_INFO/instances/$INSTANCE_NAME/attachDisk \ --data '{ "source": "/compute/v1/'$ZONE_INFO'/disks/'$LATEST_SNAPSHOT'-restored"}' # Wait for the persistent disk to be attached before mounting ATTACH_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \ https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/instances/$INSTANCE_NAME \ --silent | jq '.disks[] | select(.source | contains("disk-"))') while [ -z "$ATTACH_STATUS" ] do sleep 2 ATTACH_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" GET \ https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/instances/$INSTANCE_NAME \ --silent | jq '.disks[] | select(.source | contains("disk-"))') done # With the disk attached, mount the disk and restart Apache echo UUID=`blkid -s UUID -o value /dev/sdb` /var/www/example.com ext4 discard,defaults,nofail 0 2 \ | tee -a /etc/fstab mount -a systemctl reload apache2 # Remove jq so it's not left on the VM apt-get remove -y jq EOF
app
などのドキュメントの開始時に定義したNAME_SUFFIX
変数を起動スクリプトに適用するには、envsubst
コマンドを使用します。export NAME=app envsubst '$NAME' < "/opt/cloud-init-scripts/app-startup.sh" \ | sudo sponge "/opt/cloud-init-scripts/app-startup.sh"
VM への SSH セッションを終了します。
exit
VM の IP アドレスを取得し、
curl
を使用して基本的なウェブページを表示します。curl $(gcloud compute instances describe vm-base-$NAME_SUFFIX \ --zone $ZONE1 \ --format="value(networkInterfaces.accessConfigs.[0].natIP)")
次の出力例に示すように、基本のウェブサイトが返されます。
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>HA / DR example</title> </head> <body> <p>Welcome to a test web server with persistent disk snapshots!</p> </body> </html>
このステップでは、Apache が正しく構成され、アタッチされた永続ディスクからページが読み込まれることを確認します。以降のセクションでは、このベース VM を使用してイメージを作成し、起動スクリプトでインスタンス テンプレートを構成します。
永続ディスクのスナップショット スケジュールの作成
マネージド インスタンス グループ内に作成された VM が、永続ディスクの最新データを常に保持するには、スナップショット スケジュールを作成します。このスケジュールは、定義された時点で永続ディスクのスナップショットを自動的に取得し、スナップショットを保持する期間を制御します。次の図は、このスナップショット プロセスの仕組みを示しています。
スナップショットの取得頻度に関して、アプリケーションのニーズとビジネス目標を検討します。たとえば静的なウェブサイトの場合、スナップショットを取得する必要がある頻度は、ディスクにデータを書き込むアクティブ アプリケーションと比較して低くなります。
お客様のアプリケーションに最適なアプローチを判断する方法と、どの復旧方法を使用するかについては、障害復旧計画ガイドをご覧ください。
このシナリオでは、スナップショット スケジュールを使用して、通常の永続ディスクのスナップショットを作成します。このスナップショット スケジュールはリソース ポリシーで定義します。リソース ポリシーを使用すると、実行するアクションを定義して、そのアクションを環境内のリソースにアタッチできます。
このリソース ポリシーでは、次の設定を使用して、スナップショットを作成するスケジュールを定義します。
- 22:00 UTC から 4 時間ごとにスナップショットを取得する
- スナップショットを 1 日間保持する
このスケジュールを、環境で必要に応じて構成します(開始時刻やスナップショットの取得頻度など)。
gcloud compute resource-policies create snapshot-schedule snapshot-schedule-$NAME_SUFFIX \ --description "Snapshot persistent disk every 4 hours" \ --max-retention-days 1 \ --start-time 22:00 \ --hourly-schedule 4 \ --region $REGION
詳細については、永続ディスクのスケジュールされたスナップショットを使用する方法をご覧ください。
スナップショット スケジュールを使用するには、リソース ポリシーを永続ディスクに接続します。永続ディスクの名前と、前の手順で作成したリソース ポリシーを指定します。
gcloud compute disks add-resource-policies disk-$NAME_SUFFIX \ --resource-policies snapshot-schedule-$NAME_SUFFIX \ --zone $ZONE1
最初のディスク スナップショットが作成されるまでは、このドキュメントの残りの部分を完了してマネージド インスタンス グループの動作を確認することはできません。この時点でディスク スナップショットを手動で作成し、リソース ポリシーのスナップショット スケジュールで定義どおりに追加のスナップショットが作成されるようにします。
gcloud compute disks snapshot disk-$NAME_SUFFIX \ --zone=$ZONE1 \ --snapshot-names=disk-$NAME_SUFFIX-$(date "+%Y%m%d%H%M%S")
サービス アカウントを作成する
次の手順で作成するマネージド インスタンス グループ内の各 VM は、起動スクリプトを実行する必要があります。この起動スクリプトは、スナップショットから永続ディスクを作成して VM にアタッチします。セキュリティのベスト プラクティスとして、これらのディスク オペレーションを実行するために必要な権限のみを持つ新しいサービス アカウントを作成します。その後、このサービス アカウントを VM に割り当てます。
マネージド インスタンス グループの VM で使用するサービス アカウントを作成します。
gcloud iam service-accounts create instance-sa-$NAME_SUFFIX \ --description="Service account for HA/DR example" \ --display-name="HA/DR for VM instances"
次にカスタムロールを作成し、ディスク管理タスクの実行に必要な権限のみを割り当てます。次の権限が必要です。
compute.snapshots.list
compute.snapshots.useReadOnly
compute.disks.get
compute.disks.create
compute.instances.get
compute.instances.attachDisk
compute.disks.use
gcloud iam roles create instance_snapshot_management_$NAME_SUFFIX \ --project=$PROJECT_ID \ --title="Snapshot management for VM instances" \ --description="Custom role to allow an instance to create a persistent disk from a snapshot and attach to VM." \ --permissions=compute.snapshots.list,compute.snapshots.useReadOnly,compute.disks.get,compute.disks.create,compute.instances.get,compute.instances.attachDisk,compute.disks.use \ --stage=GA
新しいサービス アカウントに必要なロール バインディングを追加します。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com" \ --role="projects/$PROJECT_ID/roles/instance_snapshot_management_$NAME_SUFFIX" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser"
VM イメージとインスタンス テンプレートの作成
追加の構成を必要とせずに自動的にデプロイ可能な同一の VM を作成するには、カスタム VM イメージを使用します。このイメージでは、OS と Apache の構成がキャプチャされます。このイメージは、次の手順でマネージド インスタンス グループに作成する各 VM によって使用されます。
イメージを作成する前に、VM を停止する必要があります。
gcloud compute instances stop vm-base-$NAME_SUFFIX --zone=$ZONE1
次に、前のセクションで構成したベース VM のイメージを作成します。
gcloud compute images create image-$NAME_SUFFIX \ --source-disk=vm-base-$NAME_SUFFIX \ --source-disk-zone=$ZONE1 \ --storage-location=$REGION
マネージド インスタンス グループの VM が初めて起動するときに、cloud-init を使用して以前の起動スクリプトを実行します。更新後に VM を再起動する場合など、VM を起動するたびに、VM に適用される通常の起動スクリプトが実行されます。
インスタンス テンプレートで使用する cloud-init 構成ファイルを作成します。
tee -a cloud-init.yaml >/dev/null <<'EOF' #cloud-config runcmd: - [ bash, /opt/cloud-init-scripts/app-startup.sh ] EOF
cloud-init 構成を適用して、スナップショットからディスクを作成しディスクを VM にアタッチおよびマウントする起動スクリプトを実行するインスタンス テンプレートを作成します。
gcloud compute instance-templates create template-$NAME_SUFFIX \ --machine-type=n1-standard-1 \ --subnet=projects/$PROJECT_ID/regions/$REGION/subnetworks/subnet-$NAME_SUFFIX-$REGION \ --tags=http-server \ --image=image-$NAME_SUFFIX \ --scopes cloud-platform \ --service-account="instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com" \ --metadata-from-file user-data=cloud-init.yaml
マネージド インスタンス グループを作成する
マネージド インスタンス グループが VM を実行します。このマネージド インスタンス グループは定義されたゾーンで実行され、VM の状態をモニタリングします。障害が発生し、VM が動作しなくなった場合、マネージド インスタンス グループは、同じゾーン内に別の VM を作成して最新のスナップショットから永続ディスクを作成しようとします。ゾーンレベルで障害が発生した場合は、コールド フェイルオーバーを手動で実行し、別のゾーンに別のマネージド インスタンス グループを作成する必要があります。同じカスタム イメージとインスタンス テンプレートを使用して、同じ方法で VM が自動的に構成されます。
マネージド インスタンス グループ内の VM をモニタリングするヘルスチェックを作成します。このヘルスチェックは、VM がポート 80 で応答していることを確認します。独自のアプリケーションの場合は、適切なポートをモニタリングして VM の状態を確認します。
gcloud compute health-checks create http http-basic-check-$NAME_SUFFIX --port 80
VM が 1 つだけのマネージド インスタンス グループを作成します。この単一の VM が起動すると、最新のスナップショットから永続ディスクが作成され、この永続ディスクがマウントされ、ウェブ トラフィックの処理が開始されます。
gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$ZONE1 \ --base-instance-name=instance-vm-$NAME_SUFFIX \ --template=template-$NAME_SUFFIX \ --size=1 \ --zone=$ZONE1 \ --health-check=http-basic-check-$NAME_SUFFIX
ロードバランサの作成と構成
ユーザーがお客様のウェブサイトにアクセスできるようにするには、マネージド インスタンス グループで実行されている VM へのトラフィックを許可する必要があります。また、マネージド インスタンス グループにゾーン障害がある場合、トラフィックを新しい VM に自動的にリダイレクトする必要もあります。
次のセクションでは、80 番ポートの HTTP トラフィック用のバックエンド サービスを備えた外部ロードバランサを作成し、前のステップで作成したヘルスチェックを使用して、外部 IP アドレスをバックエンド サービスにマッピングします。
詳細については、シンプルな外部 HTTP ロードバランサの設定方法をご覧ください。
アプリケーション用のロードバランサを作成して構成します
# Configure port rules for HTTP port 80 gcloud compute instance-groups set-named-ports \ instance-group-$NAME_SUFFIX-$ZONE1 \ --named-ports http:80 \ --zone $ZONE1 # Create a backend service and add the managed instance group to it gcloud compute backend-services create \ web-backend-service-$NAME_SUFFIX \ --protocol=HTTP \ --port-name=http \ --health-checks=http-basic-check-$NAME_SUFFIX \ --global gcloud compute backend-services add-backend \ web-backend-service-$NAME_SUFFIX \ --instance-group=instance-group-$NAME_SUFFIX-$ZONE1 \ --instance-group-zone=$ZONE1 \ --global # Create a URL map for the backend service gcloud compute url-maps create web-map-http-$NAME_SUFFIX \ --default-service web-backend-service-$NAME_SUFFIX # Configure forwarding for the HTTP traffic gcloud compute target-http-proxies create \ http-lb-proxy-$NAME_SUFFIX \ --url-map web-map-http-$NAME_SUFFIX gcloud compute forwarding-rules create \ http-content-rule-$NAME_SUFFIX \ --global \ --target-http-proxy=http-lb-proxy-$NAME_SUFFIX \ --ports=80
ウェブ トラフィックの転送ルールの IP アドレスを取得します。
IP_ADDRESS=$(gcloud compute forwarding-rules describe http-content-rule-$NAME_SUFFIX \ --global \ --format="value(IPAddress)")
curl
を使用するか、ウェブブラウザを開いて、前のステップで作成したロードバランサの IP アドレスを使用してウェブサイトを表示します。curl $IP_ADDRESS
ロードバランサがデプロイを完了し、バックエンドにトラフィックが正しく転送されるまでに数分かかります。ロードバランサがまだデプロイ中の場合は、HTTP 404 または 502 エラーが返されます。必要に応じて、数分待ってからもう一度ウェブサイトにアクセスしてください。
次の出力例に示すように、基本のウェブサイトが返されます。
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>HA / DR example</title> </head> <body> <p>Welcome to a Compute Engine website with warm failover to Cloud Storage!</p> </body> </html>
ゾーン障害と復旧をシミュレーションする
ゾーンレベルで障害をシミュレーションする前に、リソースのデプロイメントを確認します。すべてのリソースは、次の環境をサポートするために作成されました。
- 1 つの VM が、基本的なウェブサイトを格納しているアタッチされた永続ディスクを使用して、マネージド インスタンス グループで実行されます。
- スナップショットは、リソース ポリシーのスナップショット スケジュールを使用して定期的に永続ディスクから取得されます。
- 起動スクリプトがインスタンス テンプレートに適用されるため、マネージド インスタンス グループに作成された VM は、最後のディスク スナップショットから永続ディスクを作成してアタッチします。
- ヘルスチェックでは、マネージド インスタンス グループ内の VM のステータスがモニタリングされます。
- 外部アプリケーション ロードバランサは、マネージド インスタンス グループで実行されている VM にユーザーを転送します。
- VM に障害が発生すると、マネージド インスタンス グループは同じゾーンで VM の再作成を試みます。ゾーンレベルで障害が発生した場合は、別の作業ゾーンに代替のマネージド インスタンス グループを手動で作成する必要があります。
本番環境では、Cloud Monitoring または他のモニタリング ソリューションを使用して、問題発生時にアラートが表示されることがあります。このアラートは、別の作業ゾーンで代替マネージド インスタンス グループを手動で作成する前に、障害の範囲を理解するように促します。別の方法としては、モニタリング ソリューションを使用して、マネージド インスタンス グループの障害に自動的に対応する方法があります。
ユーザーまたはモニタリング ソリューションで、フェイルオーバーが最適なアクションと判断されると、代替マネージド インスタンス グループが作成されます。このドキュメントでは、この代替リソースを手動で作成します。
ゾーンレベルでの障害をシミュレートするには、ロードバランサのバックエンドとマネージド インスタンス グループを削除します。
gcloud compute backend-services remove-backend \ web-backend-service-$NAME_SUFFIX \ --instance-group=instance-group-$NAME_SUFFIX-$ZONE1 \ --instance-group-zone=$ZONE1 \ --global gcloud compute instance-groups managed delete instance-group-$NAME_SUFFIX-$ZONE1 \ --zone=$ZONE1
プロンプトが表示されたら、マネージド インスタンス グループの削除リクエストを確定します。
本番環境では、モニタリング システムによってコールド フェイルオーバーのアクションを直ちに促すアラートが生成されます。
curl
またはウェブブラウザを再度使用して、ロードバランサの IP アドレスにアクセスします。curl $IP_ADDRESS --max-time 5
ロードバランサ用の正常なターゲットがないため、
curl
リクエストは失敗します。コールド フェイルオーバーをシミュレートするには、別のゾーンにマネージド インスタンス グループを作成します。
gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$ZONE2 \ --template=template-$NAME_SUFFIX \ --size=1 \ --zone=$ZONE2 \ --health-check=http-basic-check-$NAME_SUFFIX
VM イメージ、インスタンス テンプレート、永続ディスクによって、アプリケーション インスタンスのすべての構成が保持されます。
ロードバランサを更新して、新しいマネージド インスタンス グループと VM を追加します。
gcloud compute instance-groups set-named-ports \ instance-group-$NAME_SUFFIX-$ZONE2 \ --named-ports http:80 \ --zone $ZONE2 gcloud compute backend-services add-backend \ web-backend-service-$NAME_SUFFIX \ --instance-group=instance-group-$NAME_SUFFIX-$ZONE2 \ --instance-group-zone=$ZONE2 \ --global
curl
またはウェブブラウザをもう一度使用して、マネージド インスタンス グループで実行されている VM にトラフィックを転送するロードバランサの IP アドレスにアクセスします。curl $IP_ADDRESS
VM がデプロイを完了して最新の永続ディスクのスナップショットからデータを復元するまでに数分かかります。VM がまだデプロイされている場合は HTTP 404 または 502 エラーが返され、まだデータを復元している場合はデフォルトの Apache が表示されます。必要に応じて、数分待ってからもう一度ウェブサイトにアクセスしてください。
次のレスポンス例は、再作成された VM で正しく動作しているウェブページを示しています。
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>HA / DR example</title> </head> <body> <p>Welcome to a test web server with persistent disk snapshots!</p> </body> </html>
マネージド インスタンス グループのヘルス ステータスを確認します。
gcloud compute instance-groups managed list-instances instance-group-$NAME_SUFFIX-$ZONE2 \ --zone $ZONE2
次の出力例では、VM のステータスとして
RUNNING
とHEALTHY
が示されています。NAME ZONE STATUS HEALTH_STATE ACTION instance-vm-app us-central1-f RUNNING HEALTHY NONE
アタッチされた永続ディスクがスナップショットから作成されたことを確認するには、ソースを確認します。前の
list-instances
コマンドで表示されたインスタンスNAME
を指定します。gcloud compute instances describe NAME \ --zone=$ZONE2 \ --format="value(disks.[1].source)"
次の出力例では、永続ディスクの名前が disk-app-us-central1-a-20210630165529-umopkt17-restored であることが示されています。起動スクリプトによって接尾辞 -restored が最新のディスク スナップショットの名前に追加されます。
https://www.googleapis.com/compute/v1/projects/project/zones/us-central1-f/disks/disk-app-us-central1-a-20210630165529-umopkt17-restored
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
このドキュメントで作成した個別のリソースを削除するには、次の手順を行います。
ロードバランサの構成を削除します。
gcloud compute forwarding-rules delete \ http-content-rule-$NAME_SUFFIX --global --quiet gcloud compute target-http-proxies delete \ http-lb-proxy-$NAME_SUFFIX --quiet gcloud compute url-maps delete web-map-http-$NAME_SUFFIX --quiet gcloud compute backend-services delete \ web-backend-service-$NAME_SUFFIX --global --quiet
マネージド インスタンス グループとヘルスチェックを削除します。
gcloud compute instance-groups managed delete instance-group-$NAME_SUFFIX-$ZONE2 \ --zone=$ZONE2 --quiet gcloud compute health-checks delete http-basic-check-$NAME_SUFFIX --quiet
インスタンス テンプレート、cloud-init 構成、イメージ、ベース VM、永続ディスク、スナップショット スケジュールを削除します。
gcloud compute instance-templates delete template-$NAME_SUFFIX --quiet rm cloud-init.yaml gcloud compute images delete image-$NAME_SUFFIX --quiet gcloud compute instances delete vm-base-$NAME_SUFFIX --zone=$ZONE1 --quiet gcloud compute disks delete disk-$NAME_SUFFIX --zone=$ZONE1 --quiet gcloud compute resource-policies delete \ snapshot-schedule-$NAME_SUFFIX --region $REGION --quiet
インスタンスによって作成されたスナップショットとディスクを一覧表示してから削除します。
gcloud compute disks list --filter="name:disk-$NAME_SUFFIX" \ --uri | xargs gcloud compute disks delete gcloud compute snapshots list --filter="name:disk-$NAME_SUFFIX" \ --uri | xargs gcloud compute snapshots delete
カスタムロールとサービス アカウントを削除します。
gcloud iam roles delete instance_snapshot_management_$NAME_SUFFIX \ --project=$PROJECT_ID --quiet gcloud iam service-accounts delete \ instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com --quiet
ファイアウォール ルールを削除します。
gcloud compute firewall-rules delete allow-health-check-$NAME_SUFFIX --quiet gcloud compute firewall-rules delete allow-ssh-$NAME_SUFFIX --quiet gcloud compute firewall-rules delete allow-http-$NAME_SUFFIX --quiet
サブネットと VPC を削除します。
gcloud compute networks subnets delete \ subnet-$NAME_SUFFIX-$REGION --region=$REGION --quiet gcloud compute networks delete network-$NAME_SUFFIX --quiet
次のステップ
- データの損失の可能性を低減する代替方法については、リージョン永続ディスクを使用する復元可能なコールド アプリケーションのデプロイをご覧ください。
- 独自のアプリケーションに最適なアプローチや、使用する復旧メソッドを決定する方法については、障害復旧計画ガイドをご覧ください。
- コールド フェイルオーバーやホット フェイルオーバーなど、アプリケーションのその他のパターンについて、アプリケーションの障害復旧シナリオで確認する。
- スケールと可用性を扱うその他の方法について、スケーラブルで復元性の高いアプリのパターンで確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センター をご覧ください。