高可用性を確保する為のデザイン パターン

本デザイン パターンのユースケース

ほとんどのワークロードで可用性を考慮した設計は重要ですが、求められる要件はワークロードによって異なるため、ワークロードのアーキテクチャを考える上で、そのワークロードがどのレベルの可用性を実現する必要があるかを考えることが重要となります。Google Cloud では可用性を高めるためのソリューションをいくつか提供しており、これらを適切に採用し、各ワークロードに適した構成を選択すること可能です。

本節では自然災害によるリージョンやゾーン障害などを前提にした高可用性設計について、 Compute Engine などによるアプリケーション サーバと DB を組み合わせた一般的な ウェブサービスのワークロードを想定したアーキテクチャについて解説します。また、 Google Cloud の各ソリューションの網羅的な高可用性構成の解説については対象外のため、必要に応じてそれぞれのソリューションのドキュメントを参照ください。

Google Cloud において可用性を高めるには、ゾーンとリージョン、グローバル リソースの違いを意識する必要があります。各リージョンには 1 つ以上のゾーンがあり、ほとんどのリージョンには 3 つ以上のゾーンがあります。たとえば、asia-northeast1 リージョンは東京に位置し、asia-northeast1-a 、 asia-northeast1-b 、 asia-northeast1-c の 3 つのゾーンがあります。

仮想マシン インスタンスやゾーン永続ディスクなど、特定のゾーンに閉じたリソースはゾーンリソースと呼ばれます。静的外部 IP アドレスなど、同じリージョン内であれば、ゾーンをまたいで使用できるリソースは、リージョンリソースと呼ばれます。グローバル リソースは、場所を問わずすべての他のリソースで使用できるリソースです。詳細は リージョンとゾーン | Compute Engine ドキュメント など、利用しようとするサービスのページを確認してください。

また、Compute Engine のメンテナンス イベントでは、ホスト メンテナンスと呼ばれるホストカーネルのアップグレード、ハードウェアの修理またはアップグレードのような通常 VM の再起動を伴うような作業が行われますが、インスタンス 可用性ポリシーでこのようなメンテナンス イベントが発生した場合は、デフォルトでインスタンスをライブ マイグレーションするように構成されており、このようなメンテナンス イベントにおいても VM を再起動する事なく稼働を続ける事が可能です。

参考ドキュメント : アーキテクチャ フレームワーク | 信頼性


信頼性の要件を定義する

高可用性を確保する為の構成を検討する際は、まず最初に各ワークロードにそれぞれどのレベルの可用性が求められるかを特定することが重要となります。この要件定義は、障害発生時に許容可能なビジネスへの影響の分析から着手します。この分析で主要な指標は以下の 2 つです

  • 復旧時間目標( RTO )
    アプリケーションがオフラインである状態が許容される最大時間です。通常、この値はサービスレベル契約(SLA)の一部として定義されます

  • 復旧時点目標( RPO )
    重大なインシデントが原因でアプリケーションからデータが失われている状態が許容される最大時間です。この指標はデータの用途によって異なります。たとえば、頻繁に変更されるユーザーデータの場合、 RPO はわずか数分になる可能性があります。対照的に、重要度が低く、変更頻度が低いデータの場合、 RPO は数時間になることもあります(この指標は、失われたデータの量や質ではなく時間の長さのみを表します)

通常、RTO と RPO の値が小さいほど(つまり、アプリケーションを中断状態から復旧する時間が急がれるほど)、アプリケーションの実行コストは高くなります。次のグラフは RTO / RPO に対するコストの割合を示しています。

RTO と RPO の値が小さいと構成の複雑性が増す傾向にあるため、それに伴う管理コストも同様の曲線を描きます。高可用性のアプリケーションを維持するには、地理的に離れた 2 つのデータセンターへの分散やレプリケーションなどを実施したりすることが求められるためです。また、 RTO と RPO にビジネス上求められる要件を正しく把握し、必要以上に要件を厳しくしすぎて複雑な構成を採用したり、コストを上げすぎないことが信頼性の要件を定義する上で重要なことの一つです。

参考ドキュメント : 障害復旧計画ガイド

また、信頼性の要件の一環として、自然災害等の大規模災害などによるリージョンの障害を前提とするかどうかも重要となります。例えば後述するマルチゾーン ウォーム スタンバイの構成パターンでは、リージョン内の異なるゾーンにリソースを配置する事になり、物理インフラストラクチャやハードウェア や ソフトウェアで障害が発生した場合に、短い時間でワークロードを復旧することができますが、大規模災害時にリージョンで障害が発生した際にはワークロードを復旧することができません。この場合、マルチリージョンのストレージ ロケーションにスナップショットを取得するバックアップ & リストアと組み合わせることで、リージョンで障害が発生した際にも別のリージョンでワークロードを復元し、ワークロードの稼働を継続させることが可能となります。ただし、この場合リージョンの障害に備えるための追加のコストが必要となるため、コストとビジネス上要求される信頼性要件のバランスを最適化する必要があります

RTO や RPO 、大規模災害の考慮などの具体的な整理の方法は本稿では省略しますが、 IPA が公開している非機能要求グレードなどを参考にして整理するのも良いでしょう。

信頼性の要件を満たすことの出来るソリューション、構成パターンを選択する

可用性を高める構成パターンを決める場合は、整理した信頼性の要件に基づき以下の表を参照して検討するのが良いでしょう。また、前述の通りゾーン障害からの短時間の復旧のためにマルチゾーン ウォーム スタンバイの構成と、リージョンの障害からの復旧のためにバックアップ & リストアの構成を組合わせて構成することも可能ですが、あくまで RTO と RPO に関してはぞれぞれの定義となるため注意が必要です

※1 記載の時間については構成、運用体制などにより変動する為、あくまで目安です。

※2 リージョン永続ディスクに保管されたデータのみ、書き込み前のデータについてはデータが失われます。

以下それぞれの構成パターンについて考慮点やアーキテクチャなどを解説します。 ※ 未記載の構成パターンについては今後追加予定です。

マルチゾーン ウォーム スタンバイ

マルチゾーン ウォーム スタンバイとは、Compute Engine 上に構築したワークロードなどに対し、ゾーン障害が発生した際に HA クラスタ ソフトウェアでフェイルオーバーを管理し、別ゾーンのウォーム スタンバイのインスタンスにて処理を引き継ぐ構成で、主にステートフルなデータベース サービス(MySQL 、 Postgres など)向けの HA ソリューションを構築する際など用いられる構成です。Compute Engine で利用可能な HA クラスタ ソフトウェアとしては、次のようなソリューションが使用できます

また、Google Cloud 上でこの構成を検討する際には以下が考慮点となります

  • マルチゾーン構成の採用
    Google Cloud において、各ゾーンは 1 つ以上のクラスタ内でホストされ、クラスタごとに、独立したソフトウェア インフラストラクチャ、電源、冷却、ネットワーク、セキュリティ インフラストラクチャがあり、コンピューティング リソースとストレージ リソースのプールが含まれています。リージョン内の異なるゾーンにウォーム スタンバイを配置する事により、この物理インフラストラクチャやハードウェア ソフトウェアで障害が発生した場合に、正常稼働している他のゾーンで処理を引き継ぐことが可能となります。また、マルチゾーン構成を採用する際は単一障害点が存在しないよう、片方のゾーン障害の際に、もう片方のゾーンで必要なリソースにアクセス出来るよう、必要に応じて冗長構成を採用する必要があります。具体的な指針としては、リージョナルリソースであれば単一ゾーンの障害の際に影響を受けることはない為、特別な考慮は不要ですが、 Compute Engine のインスタンスなど、ゾーンリソースはマルチゾーンへ冗長配置するなど、考慮が必要となります。

    参考ドキュメント : ゾーンとクラスタゾーンとリージョン、グローバル リソース

  • マネージド インスタンス グループの活用
    ステートレスなウェブサイト フロントエンドやアプリケーション サーバなどに関しては、マネージド インスタンス グループ( MIG )を採用することで、高可用性だけではなく、スケーラビリティやインスタンス テンプレートの利用による運用負荷の軽減など、様々なメリットが有るため、可能な限り採用を検討することをおすすめします

    参考ドキュメント : フローティング IP アドレスのおすすめの方法

    • 内部 TCP / UDP 負荷分散を使用したフェイルオーバー
      稼働系、待機系のインスタンスを内部 TCP / UDP 負荷分散のバックエンドとしてマネージド インスタンス グループに配置し、ヘルスチェック機能で稼働系を識別し、内部 TCP / UDP 負荷分散 IP アドレスを仮想 IP アドレスとして使用することにより稼働系を切り替えることが可能となります

    • ルート API 呼び出しを使用したフェイルオーバー
      フローティング IP 相当の IP として、ネットワークの有効なサブネットの外にある IP を IP 転送を有効にした VM に設定し、稼働系インスタンスをその IP への VPC ネットワーク内の静的ルートのネクストホップとして設定し、フェイルオーバーの際にはこの静的ルートのネクストホップを待機系インスタンスに再設定することで稼働系を切り替えます

    • Cloud DNS の限定公開ゾーンなどを利用したフェイルオーバー
      この構成ではフローティング IP を利用せず、 Cloud DNS の限定公開ゾーン等に作成した A レコードを稼働系のインスタンスの IP アドレスに設定し、フェイルオーバーの際に待機系インスタンスの IP へ変更することで稼働系の切り替えを実現します。ただし、この実装においては接続元となるアプリケーション サーバの DNS キャッシュの無効化や対象の A レコードの TTL を数秒など短期間程にすることで短い時間での切り替えを実現するなどの考慮が必要となります

      参考ドキュメント : 限定公開ゾーンの作成

  • スプリットブレインを防ぐことが可能な構成を採用する
    Google Cloud における HA クラスタ構成でも、オンプレミス環境での同構成と同様に、ゾーンのネットワーク コンポーネントの障害などで稼働系と待機系のネットワークが分断されてしまい、同一資源に複数のインスタンスがアクセスすることでデータの不整合を引き起こしてしまうスプリットブレインと呼ばれる現象が発生してしまう事があります。これを防ぐためにオンプレミス環境では、共有ディスクのロックステータスによるスプリットブレインを防止する構成を採用することが多いですが、 Google Cloud ではこの方式が採用できないため、代替構成として別のゾーンに配置したクォーラム デバイス ノードを利用した投票メカニズム等を検討する必要があります。以下は HA クラスタ ソフトウェアと代表的なスプリットブレイン防止する方法の例です

本構成におけるアンチパターンについて以下にて補足します。

  • シングルゾーンのウォーム スタンバイ構成
    前述の通り、マルチゾーンのウォーム スタンバイ構成を採用することで、ゾーンのインフラストラクチャ等で障害が発生した場合に、正常稼働している他のゾーンで処理を引き継ぐことが可能となりますが、同一のゾーンに稼働系と待機系のインスタンスを配置してしまうと、これらの障害の際に同時に影響を受けてしまい、ワークロードを復旧する事が出来ないため、特別な要件が無い限りマルチゾーンでのウォーム スタンバイ構成を採用するのが良いでしょう。
    また、シングルゾーンの構成が必要な場合は、待機系インスタンス分の追加コストが発生するウォーム スタンバイ構成以外にも、
    可用性ポリシーのインスタンスの再起動動作として、インスタンスがクラッシュまたは停止した場合にインスタンスを自動的に再起動する構成にしたり、マネージド インスタンス グループを構成することで、アプリケーション ベースのヘルスチェックを使用する自動修復ポリシーを設定することも可能ですので、こちらもご検討下さい

  • スプリットブレインに対する対策が採用されていない構成
    マルチゾーンでのウォーム スタンバイ構成を採用する場合に懸念となるのが、ネットワーク機器の障害などによるスプリットブレインの発生と、それに伴うデータの不整合の発生です。こちらに関しては、前述の各 HA クラスタ ソフトウェアのスプリットブレインを防止するための構成を採用することで回避可能となるため、可能な限りこちらを採用することを推奨します。

  • フローティング IP の代替構成としてエイリアス IP の利用
    フローティング IP の代替構成の選択肢としてエイリアス IP の利用も可能ですが、マルチゾーンの HA のデプロイには、1 つのゾーンに障害が発生した場合に、エイリアス IP を別のゾーンのインスタンスに再割り振りするには時間がかかる可能性があるため、前述の別の方法を採用することを推奨します

アーキテクチャの解説

マルチゾーン ウォーム スタンバイ について、様々な構成要素の組み合わせが可能となりますが、本項では以下の OS / MW を利用し、DB サーバの HA クラスタ構成を中心にした、一般的な ウェブサービスのワークロードのサンプル アーキテクチャと各構成要素の解説を行います。なお、各構成要素の解説については本構成における考慮点の解説のみを行うため、概要や詳細などはそれぞれ記載した参考リンクや他のデザイン パターンの解説を参照ください

  • CentOS 8

  • Pacemaker + Corosync

  • MySQL 8

  • Apache + php-fpm

本構成におけるポイントとサンプル アーキテクチャ図は以下となります

  • フロントエンドに関しては、ゾーン障害においても別のゾーンのインスタンスで処理を継続、必要に応じたオートスケーリングが可能なリージョン マネージド インスタンス グループを採用

  • DB インスタンスに関しては、リージョン永続ディスクを利用した HA クラスタ構成を採用し、ゾーン障害の際にも処理が引き継げる構成を採用

また、 D ~ H の部分についてはマネージド サービスである Cloud SQL を利用する事が可能です。この場合のサンプル アーキテクチャ図は以下となります

アルファベット記号に応じたサンプル アーキテクチャの各要素について、以下に解説を記載します。なお、ここでは本構成における特記事項のみの解説を行うため、詳細については各参照ドキュメントを参照ください。

A. 外部 HTTP(S) 負荷分散(External Load Balancing)
外部からの通信を負荷状況や障害発生状況に合わせて、適切に稼働しているバックエンド サービスに振り分けます。本構成ではバックエンド サービスとしてリージョン内の複数のゾーンにインスタンスを分散配置するリージョン マネージド インスタンス グループを採用する為、ゾーン障害発生時にも稼働が続いているインスタンスへ通信を振り分けます。また、外部 HTTP(S) 負荷分散自体もグローバル リソースの為、特別な構成を行うことなく、ゾーンやリージョンの障害の影響を受けずにサービス稼働を継続させることが可能です。

参考ドキュメント : 外部 HTTP(S) 負荷分散の概要

B. VPC ネットワーク( VPC Network )
Google Cloud では、 VPC を構成することにより、選択したリージョン内に共通のネットワークである、サブネットを構成することが可能で、このネットワークを利用し、マネージド インスタンス グループや Compute Engine のインスタンスなどを展開することが可能です。また、関連ルート、ファイアウォール ルールを含む VPC ネットワークはグローバル リソースの為、ゾーンやリージョンの障害の影響を受けることはありません

参考ドキュメント : VPC ネットワークの概要

C. リージョン マネージド インスタンス グループ (Regional Managed Instance Group)
リージョン マネージド インスタンス グループを使用すると、アプリケーションを 1 つのゾーンに制限することや、異なるゾーンで複数のインスタンス グループを管理することなく、アプリケーションの負荷を複数のゾーンに分散できます。複数のゾーンを使用することで、ゾーン障害の発生時にも、アプリケーションは同じリージョンの別のゾーンで実行しているインスタンスからトラフィックの処理を続行する事が可能です。 また、 リージョン マネージド インスタンス グループを利用することで、ゾーン障害に対応可能な高可用性だけではなく、自動修復Updater 機能を使用したアップデートのロールアウトによる運用負荷の軽減、負荷に応じた自動スケーリングの構成など様々なメリットがあります

参考ドキュメント : リージョン MIG を使用したインスタンスの分散

D. 内部 TCP / UDP 負荷分散 (Internal Load Balancing)
本構成ではフローティング IP の代替構成として、内部 TCP / UDP 負荷分散を使用したHA クラスタ構成を採用し、フロントエンド インスタンスから DB インスタンスへの接続は内部 TCP / UDP 負荷分散の IP を利用します。また、内部 TCP / UDP 負荷分散では 3306 / TCP ポートへのヘルスチェックを構成し、 MySQL のインスタンスが稼働しているインスタンスへ通信を振り分けます

参考ドキュメント : 内部 TCP / UDP 負荷分散の概要

E. 非マネージド インスタンス グループ (Unmanaged Instance Group)
内部 TCP / UDP 負荷分散の振り分け先として、マネージド インスタンス グループの設定が必要となりますが、前述のリージョン マネージド インスタンス グループの利用とは違い、 1 インスタンスのみを含むマネージド インスタンス グループをゾーンごとに 1 セットずつ構成することで単一のノードへ通信を振り分ける構成とし、HA クラスタの稼働系、待機系のインスタンスを構成します。
また、非マネージド インスタンス グループではマネージド インスタンス グループと違い、共通のインスタンス テンプレートを共有しない固有の VM として、通常の Compute Engine のインスタンス として構成した後に非マネージド インスタンス グループへ参加する手順となります。
なお、 MySQL のデータ保存に関しては後述のリージョン永続ディスクへ保存することでリージョン内のレプリケーションを行いますが、それぞれのインスタンスのブートディスクに関してはゾーン永続ディスクの利用で問題ありません

参考ドキュメント : 非マネージド インスタンス グループ非マネージド インスタンス グループの作成Google Compute Engine で MySQL をセットアップする方法

F. Compute Engine - Quorum Server
このノードは Corosync のスプリットブレイン防止構成におけるクォーラム デバイスとして corosync-qnetd デーモンが実行され、HA クラスタの稼働系、待機系 と通信を行うことでネットワーク パーティションの検知とクォーラム ルール(多数決)による稼働インスタンスの決定を構成します

参考ドキュメント : DRBD を使用した高可用性 MySQL 5.6 クラスタを Compute Engine にデプロイする

G. リージョン永続ディスク(Regional Persistent Disk)
リージョン永続ディスクを利用すると、同じリージョン内の 2 つのゾーン間でのデータの耐久性の高いストレージとレプリケーションを構成することが可能となり、両方のレプリカが使用可能な場合、両方のレプリカで書き込み内容が永続化されたときに、書き込みの確認応答が VM に返される為、同期の遅延などは通常発生しません。 また、ゾーン障害の際には、接続コマンドに --force-attach フラグを使用することにより、別のゾーンのインスタンスに接続することが可能です。 なお、リージョン永続ディスクはゾーン永続ディスクのパフォーマンス性能とは別定義となり、特にリージョン永続ディスクはインスタンスあたりの書き込みスループットが低くなるため、利用の際には注意が必要です

参考ドキュメント : リージョン永続ディスクリージョン永続ディスクのフェイルオーバーリージョン PD を使用した高可用性オプション

H. 永続ディスクのスナップショット(Persistent Disk Snapshot)
スケジュールによる定期的なスナップショットの作成により、ゾーン永続ディスクまたはリージョン永続ディスクからデータを定期的にバックアップすることが可能です。スナップショットのストレージ ロケーションとして、マルチリージョンや永続ディスク が配置されたリージョンとは別のリージョンへのバックアップの保管が可能であり、これによりリージョンの障害の際にもワークロードを別のリージョンで復元することが可能となります。加えて、HA クラスタ構成だけでは対応できないデータの破壊など、論理障害に対する備えにもなるため、可能な限りスケジュールによるスナップショットの定期作成を構成することを推奨します。
また、スナップショットでバックアップされるデータは永続ディスクに書き込みが完了しているデータのみとなるため、
永続ディスクのスナップショットに関するベスト プラクティスを参考にアプリケーションのデータや、ディスク バッファをフラッシュしてファイル システムを同期した上でスナップショットの作成を行う事も検討ください

参考ドキュメント : 永続ディスクのスナップショットの作成

I. Cloud SQL 高可用性構成
前述の通り HA クラスタ構成には複数のコンポーネントの組み合わせによる複雑な構成が必要となりますが、Cloud SQL HA 構成を採用することにより以下のようなメリットがあります

  • HA クラスタリング構成や、マルチリージョン バックアップについても事前定義されたマネージド サービスの機能を利用可能であり、複雑な構成を管理する必要がない。

  • データベース プロビジョニング、ストレージ容量の管理など、構築、運用作業が自動化されている。

  • バグの修正やセキュリティ パッチの反映などが自動反映される。

高可用性構成の Cloud SQL インスタンスはリージョン内のプライマリ ゾーンとセカンダリ ゾーンに配置され、各ゾーンの永続ディスクへの同期レプリケーションにより、プライマリ インスタンスへの書き込みのすべてがスタンバイ インスタンスにも反映されます。インスタンスまたはゾーンで障害が発生した場合、この構成によりダウンタイムが短縮され、クライアント アプリケーションで引き続きデータを使用できます。

参考ドキュメント : 高可用性構成の概要

J. プライベート サービス アクセス (Private Service Access)
VPC ネットワークでホストされている内部 IP アドレスでサービスを提供でき、プライベート サービス アクセスを使用すると、これらの内部 IP アドレスにアクセスできます。これは、VPC ネットワーク内の VM インスタンスから内部 IP アドレスで Cloud SQL のインスタンスに接続する際に利用可能です

参考ドキュメント : プライベート サービス アクセスプライベート サービス アクセスの有効化プライベート サービス アクセスの構成

K. Cloud SQL インスタンスのバックアップ
Cloud SQL インスタンスの自動バックアップを構成することにより、定期的なバックアップを取得し、問題が発生しているインスタンスをバックアップから復元することができます。バックアップの保存先としてデフォルトでは冗長性を確保するためにバックアップ データを 2 つのリージョンに保存します。これにより、リージョンの障害が発生した場合でも別のリージョンでインスタンスを復元することが可能です。
また、
バイナリログを有効にすることで、ポイントインタイム リカバリ(PITR)を使用することも可能です。ただし、ポイントインタイム リカバリではバイナリログが使用され、ログが作成される為、保存容量を使用します。バイナリログは、関連する自動バックアップによって自動的に削除されます。バイナリログによる予期しないストレージの問題を回避するには、バイナリログの使用時に合わせてストレージの自動増量を有効にすることをおすすめします

参考ドキュメント : バックアップの概要ポイントインタイム リカバリの構成方法


そのほかの選択肢

  • リージョン永続ディスク以外のデータ同期の方法
    本サンプル アーキテクチャではゾーン障害に備えた別ゾーンへのデータ同期はリージョン永続ディスクを利用した構成としていますが、 リージョン永続ディスク以外にも以下のようなデータ同期の方法を採用することが出来ますので、必要に応じて検討ください。

    • DRBD の利用
      Distributed Replicated Block Device(DRBD)を利用する事で、ネットワークを介したブロック デバイス レベルでのデータ同期を構成することが可能となり、Pacemakerと組み合わせる事で、レプリケーション構成の管理も含めた HA クラスタリングを構成することが可能です

      参考ドキュメント : DRBD を使用した高可用性 MySQL 5.6 クラスタを Compute Engine にデプロイする

    • DB のレプリケーション機能の利用
      SQL Server AlwaysOn や MySQL Group Replication 等、利用する DB のレプリケーション機能を利用しデータ同期を構成することも可能です。この場合、HA クラスタリング構成も合わせて MW で実装、管理する事が可能なことが多く、単一ソリューションでのシンプルな構成を実現できるのもメリットとなります

      参考ドキュメント : SQL Server AlwaysOn 可用性グループの構成、GCEとMySQLで実現する高可用性システム


利点

この構成の主な利点は以下です

  • 本構成を採用することで、同一リージョン内で、可用性を高め、かつ運用も多くの範囲で自動化できます。多くの場合、インスタンスの自動リカバリー、 メンテナンスに対するライブマイグレーション、レプリケーションなどの運用の機能や監視の機能も提供されます

  • Compute Engine のインスタンスの SLA は >= 99.5% と定義されていますが、本構成を採用すると、 Instances in Multiple Zones に該当するため >= 99.99 % の SLA が適用されます。ただし、注意点として SLA は稼働を保証するものではない点、サービスにより異なる点、常に更新される点を考慮して、設計段階で要求仕様に合わせて確認してください

  • フェイルオーバーの条件や、前後の処理など、きめ細やかな設定が HA クラスタリング ソフトウェアにて実装可能です


注意事項

  • 前述の通り、マルチゾーン ウォーム スタンバイではリージョンの障害が発生した場合にはワークロードを復旧させる事が出来ません。この場合 マルチリージョン ロケーション や 別のリージョンの Cloud Storage へのスナップショットの作成による Backup & Restore にて、リージョンの障害が発生した際にワークロードを復旧させることが可能です

  • Cloud SQL を利用する際には、以下に注意する必要があります

    • Cloud SQL では利用できない機能があるため、利用したい機能が利用可能か事前確認するのが良いでしょう。
      参考ドキュメント : Cloud SQL と標準 MySQL の機能の違いCloud SQL と標準 PostgreSQL の機能の違いCloud SQL で使用できない SQL Server の機能

    • Cloud SQL インスタンスでは、バグの修正、セキュリティ侵害の防止、アップグレードの実施のため更新が必要です。更新を適用すると、Cloud SQL でインスタンスが再起動され、サービスが中断される可能性があります。メンテナンス中、HA プライマリ インスタンスがスタンバイ インスタンスにフェイルオーバーすることはありません。ビジネスに対する影響を回避するため Cloud SQL メンテナンスウィンドウを設定し、メンテナンスの時間を事前に設定しましょう。また、バックアップなども業務要件に応じて設定すると良いでしょう。
      参考ドキュメント : Cloud SQL インスタンスでのメンテナンスの概要


このパターンで作成された事例


関係するデザインパターン

  • Dynamic site hosting Web

  • ホスティング キャッシュ利用パターン

  • SAP HANA on GCP の高可用性構成


参照ドキュメント


始める前に

  • 事前準備として以下を実施します

    • Cloud Console のプロジェクト セレクタページで、プロジェクトを選択または作成します。

    • プロジェクトに対して課金が有効になっていることを確認します。
      参考ドキュメント : プロジェクトの課金設定を変更する

  • Compute Engine API を有効にします。

MySQL 用インスタンス とリージョン永続ディスクの作成

  • 環境変数を設定したファイルを作成します

  • 現在のセッションで環境変数を読み込みます

  • クラスタ インスタンス用のサービス アカウントを設定します

  • 作成したサービス アカウントへ必要な権限を付与します

  • 3 つの各クラスタノード用に内部 IP アドレスを予約します

  • MySQL のデータ保存用のリージョン永続ディスクを作成します

  • asia-northeast1-a ゾーンに database1 という名前の VM インスタンスを作成します

  • asia-northeast1-b ゾーンに database2 という名前の VM インスタンスを作成します

database1 のセットアップと、MySQLのインストール

  • リージョン永続ディスクを database1 に接続します

  • database1 へ SSH で接続し、環境変数のセットを行います

  • MySQL 8.0 のインストールと初期セットアップを行います

  • 作成したユーザで SQL が実行可能か確認します

  • 以下のように稼働ノードが表示されることを確認します

  • MySQL の停止とファイルシステム、リージョン永続ディスクの切り離しを行います

  • Pacemaker のインストールと起動時の有効化を行います

  • 認証用のクラスタ ユーザー パスワードを設定します

  • corosync-keygen スクリプトを実行します。これにより、128 ビットのクラスタ認証キーが生成され /etc/corosync/authkey に書き込まれます

  • authkey を database2 インスタンスにコピーします。パスフレーズの入力については、そのまま Enter キーを押します

  • Corosync クラスタ構成ファイルを作成します

この構成の主な利点は以下です。

  • transport : ユニキャスト モード(udpu)を指定します。

  • Bindnetaddr : Corosync のバインド先のネットワーク アドレスを指定します。

  • nodelist : クラスタ内の特定のノードへの通信方法を定義します。この例では、database1 ノードと database2 ノードへの通信方法を定義しています。

  • quorum / two_node : デフォルトでは、2 ノードクラスタ内のノードはどちらもクォーラムを獲得しません。これをオーバーライドするには、quorum セクション内の two_node に値「1」を指定します。

この設定により、クラスタを構成して、今後 3 つ目のノードをクォーラム デバイスとして追加するときに備えることができます

  • Pacemaker を認識するように Corosync を構成します

  • Corosync サービスと Pacemaker サービスを再起動します

  • 永続ディスクの Resource Agent をインストールします

  • database2 へ SSH で接続し、環境変数のセットを行います

  • SE Linux の無効化などを行います

  • MySQL をインストールします

  • Pacemaker のインストールと起動時の有効化を行います

  • 前にコピーした Corosync authkey ファイルを /etc/corosync/ に移動します

  • 認証用のクラスタ ユーザー パスワードを設定します

  • Corosync 構成ファイルを作成します

  • Pacemaker を認識するように Corosync を構成します

  • Corosync サービスと Pacemaker サービスを再起動します

  • 永続ディスクの Resource Agent をインストールします

クラスタの起動

  • クラスタノードに対して認証を行います

  • クラスタの起動とステータス確認を行います

  • 以下のように各ノードが Online と表示されることを確認します

クラスタ リソースを管理するように Pacemaker を構成する

  • SSH を使用して database1 インスタンスに接続し、環境変数を読み込みます

  • Pacemaker の pcs ユーティリティを使用して、いくつかの変更をファイルに行い、後で Cluster Information Base(CIB)に一括反映可能にします

  • STONITH は無効化します

  • クォーラムの構成として、投票数が過半数を下回った場合にクラスター パーティション内の全リソースが停止される構成にします

  • ノードが障害からの復元後に Pacemaker でリソースが戻されないように構成します

  • リージョン永続ディスクの接続の為のリソースを作成します
    なお、監視操作の無効化を設定することで、 Google Cloud の API の障害の際などに不必要なフェイルオーバーを防ぐ事が可能です

  • /srv をマウントするファイル システム リソースを作成し、リージョン永続ディスクが接続されたインスタンスに配置され、リージョン永続ディスクの接続後にリソースを起動するようにクラスタを構成します

  • MySQL サービスを作成し、ファイル システムがマウントされたインスタンスに配置され、ファイル システムのマウント後にリソースを起動するようにクラスタを構成します

  • 変更をクラスタに commit し、リソースのステータスを確認します

  • 以下のようにリソースが Started となっていれば正常に稼働しています

クォーラム デバイスを構成する

  • SSH を使用して database1 インスタンスに接続し、環境変数を読み込みます

  • pcs と corosync-qnetd をインストール、起動します

  • 認証用のクラスタ ユーザー パスワードを設定します

  • クォーラム デバイスの起動と、ステータスを確認します

  • 以下のように起動を確認します

  • database1 へ SSH で接続し、環境変数を読み込みます

  • クラスタのクォーラム デバイスノードを認証します

  • クォーラム デバイスをクラスタに追加します。ffsplit アルゴリズムを使用します。このアルゴリズムにより、50% 以上の得票に基づいてアクティブ ノードが決定されます

  • クォーラム設定を corosync.conf に追加します ※ quorum { } の項目が変更されています

  • Corosync クォーラム デバイス デーモンを起動し、システム起動時に有効化します

  • database2 へ SSH で接続し、環境変数を読み込みます

  • クォーラム設定を corosync.conf に追加します ※ quorum { } の項目が変更されています

  • Corosync クォーラム デバイス デーモンを起動し、システム起動時に有効化します

クラスタのステータス確認

  • database1 へ SSH で接続し、環境変数を読み込みます

  • クラスタのステータスを確認します

  • クォーラムのステータスを表示します

クラスタ IP として内部ロードバランサを構成する

  • Cloud Shell を開き、環境変数を読み込みます

  • database1 用の非マネージド インスタンス グループを作成します

  • database1 用の非マネージド インスタンス グループに database1 を追加します

  • database2 用の非マネージド インスタンス グループを作成します

  • 3306 / TCP ( MySQL ) のヘルスチェックを作成します

  • バックエンド サービスを作成します

  • バックエンド サービスに、2 つのインスタンス グループを追加します

  • ロードバランサの転送ルールを作成します

  • 内部ロードバランサのヘルスチェックを許可するファイア ウォール ルールを作成します

(Optional)MySQL への接続テスト

  • 接続テスト用インスタンスを作成します

  • mysql-client へログインし以下にて接続をテストします

(Optional)Cloud SQL HA 構成の作成

アーキテクチャの解説で記載したとおり、 MySQL の部分を HA 構成の Cloud SQL にて行うことも可能です。その場合のサンプル コンフィグについて解説します

  • 以下のコマンドにて Service Networking API の有効可と、Private Service Access を構成します

  • HA 構成の Cloud SQL インスタンスの作成
    ※ インスタンスの作成と同時にバックアップの設定が行われ、 UTC 午後 6 時(日本時間 午前 3 時)に日次バックアップ取得が開始されます

作成が成功すると、以下のように VPC からアクセス可能なインスタンスのPRIVATE_ADDRESS が表示されます

リージョン マネージド インスタンス グループの作成

  • Cloud Shell を起動し、マネージド インスタンス グループの起動スクリプトを作成します
    ※ 作業簡略化の為、DB のパスワードをハードコーディングしておりますが、本番構成の場合は Cloud KMS 等の利用を検討ください。

  • インスタンス テンプレートを作成します

  • リージョン マネージド インスタンス グループを作成します

  • リージョン マネージド インスタンス グループ の Named Port を定義します

外部 HTTP(S) 負荷分散の作成

  • ヘルスチェック用のファイアウォール ルールを定義します

  • 外部 IP アドレスを予約します

また、以下コマンドで表示される予約された 外部 IP アドレスを記録します

  • ヘルスチェックを作成します

  • バックエンド サービスを作成します

  • リージョン マネージド インスタンス グループ をバックエンド サービスに追加します

  • デフォルトのバックエンド サービスに受信リクエストをルーティングする URL マップを作成します

  • URL マップにリクエストをルーティングするターゲット HTTP プロキシを作成します

  • 受信リクエストをプロキシにルーティングするグローバル転送ルールを作成します

動作確認

  • ブラウザを開き、先程確認した外部 IP アドレスへ http でアクセスすると以下のように表示され、database1 または database2 の部分は MySQL インスタンスへクエリを行った結果として稼働しているインスタンスのホスト名が表示されています

  • 次のテストを実施する事で、デプロイ済みクラスタの HA 機能をテストします

    • database1 インスタンスをシャットダウンして、マスター データベースが database2 インスタンスにフェイルオーバーするかどうかをテストします

    • database1 インスタンスを起動して、database1 がクラスタに正常に再参加できるかどうかを確認します

    • database2 インスタンスをシャットダウンして、マスター データベースが database1 インスタンスにフェイルオーバーするかどうかをテストします

    • database2 インスタンスを起動して、database2 がクラスタに正常に再参加できるかどうか、database1 インスタンスが引き続きマスターのロールを保持するかどうかを確認します

    • database1 をファイアウォール ルールで孤立させ、ネットワーク パーティション状態を作りだし、スプリット ブレインの問題をシミュレートします

  • Cloud Shell を開き、環境変数を読み込みます

  • クラスタのステータスを確認します
    ※ database1 でサービスが稼働していることを確認

  • database1 インスタンスを停止します

  • クラスタのステータスを確認します
    ※ database2 にサービスがフェイルオーバーしていることを確認

  • database1 インスタンスを起動します

  • クラスタのステータスを確認します
    ※ database1 が Online に復旧していることを確認

  • database2 インスタンスを停止します

  • クラスタのステータスを確認します
    ※ database1 にサービスがフェイルオーバーしていることを確認

  • database2 インスタンスを起動します

  • クラスタのステータスを確認します
    ※ database2 が Online に復旧していることを確認

  • 以下のファイアウォール ルールを作成し、 database1 をネットワーク パーティション状態にします

  • 数分後、クラスタのステータスを確認します
    ※ database1 が OFFLINE となり、サービスが database2 にフェイルオーバーされていることを確認

  • 続いて database1 のクラスタのステータスを確認します
    ※ database1 は Online ですが、クォーラムの投票により、サービス停止状態になっていることを確認 ( no-quorum-policy=stop 構成時の挙動 )

  • 続いて database1 のクォーラムのステータスを確認します
    ※ Qdevice の Vote も含め Total votes が 2 となっている事を確認

  • 最後にファイアーウォール ルールを削除し、ネットワーク パーティション状態を解除します

  • クラスターのステータスを確認します
    ※ database1 が復帰してもフェイルオーバーは発生しておらず、 database1 が Online に戻っていることを確認

(Optional)スナップショットの作成

前述の通りスナップショットの作成を組み合わせることにより、リージョンの障害や論理障害に備えることが可能となります。必要に応じて以下のサンプル コマンドを参考にスナップショットの作成を構成ください
※ 以下の手順については永続ディスクへのデータ同期については十分考慮されていない可能性がある為、必要に応じて永続ディスクのスナップショットに関するベスト プラクティスを参照し、要件に応じた実装方法を検討ください

  • Cloud Shell を開き、環境変数を読み込みます

  • スナップショットのスケジュールを作成します、以下のコマンド例ではリテンション期間は 7 日間で、日次バックアップが UTC 午後 6 時(日本時間 午前 3 時)に作成開始されます

  • 作成したスナップショット スケジュールを database1 と database2 の ブートディスクとクラスタの共有ディスクにスケジュールを割り当てます

クリーンアップ

注意: プロジェクトを削除すると、次のような影響があります。

プロジェクト内のすべてのものが削除されます。このチュートリアルで既存のプロジェクトを使用した場合、それを削除すると、そのプロジェクトで行った他の作業もすべて削除されます。

カスタム プロジェクト ID が失われます。このプロジェクトを作成したときに、将来使用するカスタム プロジェクト ID を作成した可能性があります。そのプロジェクト ID を使用した URL(たとえば、appspot.com)を保持するには、プロジェクト全体ではなくプロジェクト内の選択したリソースだけを削除します。

  • Cloud Console でリソースの管理ページに移動します

  • プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします

  • ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します