モノリシック アプリケーションを Google Kubernetes Engine のマイクロサービスに移行する

この記事では、ウェブサイトをモノリシック プラットフォームから Google Cloud 上でリファクタリングされたコンテナベースのマイクロサービス プラットフォームに移行するための全体像について説明します。この移行は機能単位で行うため、大規模な移行に伴うリスクを回避できます。この記事は、モノリシック プラットフォームにホストされている複雑なウェブサイトを最新化する IT プロフェッショナルの方を対象としています。この記事を読むために Google Cloud や Kubernetes に関する深い知識は必要ありません。

この移行は、より機敏でスケーラブルな環境でサイトの個々の機能を実行できるようにすることを目的としています。このような環境では、機能がモノリシック プラットフォームの一部になっている場合よりも、管理や更新を簡単に行うことができます。 このような環境で実行することで、移行された各機能の改善が早くなり、ユーザーに価値とともに提供することが可能になります。

この記事では、ワークロードの例として e コマースサイトを使用します。多くの e コマースサイトはモノリシックで、独自のプラットフォーム上に構築されているため、ここで説明する移行の例としては最適の対象です。ただし、この記事で説明する原則はさまざまなワークロードに適用できます。ご使用のシステムと制約の構成がこの記事の説明と近いものであれば、この記事で紹介する原則を適用するメリットがあります。たとえば、ホテルの予約サイトやレンタカーのサイトもこの移行パターンの候補になります。

GCP への移行: はじめにで説明されているように、クラウドへの移行パターンは「リフト&シフト」、「改善して移行」、「削除して置き換え」の 3 つに大別できます。この記事では、「削除して置き換え」のパターンについて説明します。このパターンは、アプリケーション全体ではなく、アプリケーションの各機能に段階的に適用されます。

この移行パターンに加え、この記事では 2 つのハイブリッド パターンについても解説します。移行の途中では、アプリケーションの一部の機能がクラウドに移行し、残りがオンプレミスに存在するハイブリッド アーキテクチャになります。移行が完了すると、アプリケーション全体がクラウドにホストされますが、その段階でもオンプレミスに残っているバックエンド サービスと通信を行います。

用語

アプリケーション
この記事で言及しているアプリケーションとは、エンドユーザーからは 1 つの単位として認識されているが、実は多くの機能で構成されている、完全なソフトウェア システムを指します。たとえば、e コマースサイトはアプリケーションです。アプリケーションで実行できることはすべて、そのアプリケーションの特定の機能によって実行されます。
機能
アプリケーションの機能単位。機能はユーザーから見えるもので、アプリケーションの中心となるものです(e コマースサイトのショッピングカートなど)。それらには、ユーザーに表示され、アプリケーションで必須のもの(ログインなど)や、アプリケーションの内部にあるもの(e コマースサイトの在庫管理など)が挙げられます。
サービス
アプリケーションの独立したコンポーネント。アプリケーションはエンドユーザーに見えない複数のサービスから構成されています。たとえば、ウェブサイトで使用されるデータベースもサービスの 1 つです。
モノリシック アプリケーション
1 つのデプロイ可能単位として構築されたアプリケーション。モノリスともいいます。たとえば、単一の Java EE アプリケーションや単一の .NET ウェブ アプリケーションが該当します。多くの場合、モノリシック アプリケーションにはデータベースとクライアント側のユーザー インターフェースが関連付けられています。
マイクロサービス
アプリケーション機能に対応するために構築された単一のサービス。マイクロサービス パターンでは、アプリケーションは複数のサービスの集合体で、それぞれが特定の目的を持っています。たとえば、顧客のショッピング カートを処理するサービス、支払い決済を処理するサービス、在庫用のバックエンド アプリケーションとやり取りするサービスなどがあります。これらのマイクロサービスは疎結合で、定義した API を介した相互のインターフェースとして機能します。これらは異なる言語やフレームワークで作成でき、異なるライフサイクルを割り当てることが可能です。
ハイブリッド アーキテクチャ
独自のデータセンターでホストされているプライベート リソースと組み合わせて、パブリック クラウド プロバイダ(Google Cloud など)を使用するアーキテクチャ。ハイブリッド アーキテクチャを実装する理由と方法はいくつかあります。詳細については、ハイブリッド クラウドとマルチクラウドのパターンと実践をご覧ください。
ステートレス / ステートフル
サービスがデータ ストレージを直接管理するかどうかを表します。この記事では、Twelve-Factor App の方法論のステートレスとステートフルネスと同じ定義を使用します。使用するデータに依存しない場合、サービスはステートレスになります。 ステートフルはその逆です。たとえば、顧客のショッピング カートを処理するサービスは、ショッピング カートの保存と取得を行う必要があるため、ステートフルになります。バックエンド システムにアイテムが存在するかどうかを確認するサービスは、データ(状態)がサービスではなくバックエンド システムで保存されるため、ステートレスになります。

マイクロサービスに移行する理由

アプリケーションをマイクロサービスに分割すると、次のような利点があります。その多くはマイクロサービスが疎結合であることに起因しています。

  • マイクロサービスは個別にテストしてデプロイできます。デプロイ単位が小さいほど、デプロイが容易になります。
  • 異なる言語やフレームワークで実装できます。マイクロサービスごとに、ユースケースに最適なテクノロジーを自由に選択できます。
  • 異なるチームで管理できます。マイクロサービス間の境界により、1 つのチームが 1 つまたは複数のマイクロサービスを簡単に管理できます。
  • マイクロサービスに移行すると、チーム間の依存関係が緩和されます。各チームは、依存しているマイクロサービスの API のみを考慮し、マイクロサービスの実装方法やリリース サイクルなどについて考える必要はありません。
  • 障害に対する設計が簡単になります。サービス間に明確な境界があるので、サービスが停止した場合の対処方法を決定しやすくなります。

モノリスと比較した場合、マイクロサービスには次のような欠点があります。

  • マイクロサービス ベースのアプリを構成するサービスの相互関係が明確でない場合が多く、システム全体の複雑さは増大する傾向があります。
  • モノリスの内部と異なり、マイクロサービスはネットワークを介して通信を行うため、セキュリティ上の問題が発生することがあります。 この問題を解決するため、Istio はマイクロサービス間のトラフィックを自動的に暗号化しています。
  • サービス間のレイテンシのため、モノリシック アプローチと同じレベルのパフォーマンスを実現するのが困難な場合があります。
  • システムの動作は、単一のサービスに起因するのではなく、多くのシステムとシステム間のやり取りによって引き起こされます。このため、本番環境でのシステムの動作を把握することは難しくなります(可観測性が低くなります)。 Istio は、この問題の解決策となります。

マイクロサービス自体は Google などの一部の企業で何年も前から採用されているテクノロジーですが、そのコンセプト(さらにサービス指向アーキテクチャ(SOA)との関係)が正式に定義されたのは、James Lewis、Martin Fowler、Sam Newman の各氏が執筆した Microservices の記事においてです。

移行プロセスの概要

この記事で説明する移行プロセスは大規模なプロジェクトであるため、完了までに数か月かかることがあります。このセクションでは、モノリシックなオンプレミス アプリケーションから、マイクロサービスで構成され、Google Cloud で完全にホストされたアプリケーションに移行するまでのパスを紹介します。

開始点: モノリシックなオンプレミス アプリ

この記事では、モノリシックなアプリケーションをオンプレミスで実行していることを前提としています。現在のアーキテクチャは、次の概要図に類似したものになっています。

典型的なモノリシック アプリケーションのアーキテクチャ

この図は、現在のシステムを完全に表したものではありません。 このようなアーキテクチャでは、次のようなテクノロジーがよく利用されています。

  • リレーショナル データベース(Oracle® データベース、SAP HANA など)
  • e コマース プラットフォーム(Oracle ATG、SAP Hybris など)
  • 検索エンジン(Apache Solr など)

終了点: Google Cloud 上のマイクロサービス ベースのアプリ

この移行プロセスは、オンプレミスのモノリシック アーキテクチャから Google Cloud 上で動作するマイクロサービス ベースのアーキテクチャへの移行についてのものです。ターゲットのアーキテクチャについては、マイクロサービスを使用したスケーラブルなコマース ワークロードで説明されています。たとえば、次のようになります。

コンテナと GKE に移行した後のアーキテクチャ

ターゲット アーキテクチャでは、Google Kubernetes Engine(GKE)でマイクロサービスを実行します。 Kubernetes は、コンテナの管理、ホスト、スケーリング、デプロイを行うプラットフォームです。コンテナは移植性の高い手法で、コードをパッケージ化して実行します。それぞれのマイクロサービスを独自のコンテナ内で実行できるので、この手法はマイクロサービスのパターンにも適しています。 マイクロサービスは、Cloud Interconnect または Cloud VPN によって構築されたプライベート ネットワーク接続を介してバックエンド システムを呼び出すことができます。また、Apigee を使用してバックエンド サービスを公開し、これらのサービスに安全にアクセスすることもできます。これらのプロダクトの詳細と選択方法については、この記事の後半にある Apigee、Cloud VPN、Cloud Interconnect で説明します。

マイクロサービスは、必要に応じて他の Google Cloud プロダクトとも通信できます。e コマース アプリケーションでよく利用されている Google Cloud プロダクトには、Cloud StorageCloud SQL の 2 つがあります。Pub/Sub は、異なるマイクロサービス間で非同期処理を行うときのメッセージバスとして使用できます。

アプリケーションをインターネットに公開する方法は 2 つあります。画像などのアセットの場合は、Google Cloud のロードバランサ経由で直接公開します。公開 API の場合は必要に応じて Apigee を使用できます。

次の表に、ターゲット アーキテクチャで使用できるプロダクトを示します。すべてが必須というわけではありません。ユースケースによって使用するものが異なります。

ネットワーキング

Google Cloud プロダクト 用途
Virtual Private Cloud VPC は、リソース(GKE クラスタなど)が存在するソフトウェア定義のプライベート ネットワークです。VPC には、ファイアウォールやルーティングなどの機能が組み込まれています。VPC は世界中で利用可能であり、Google 所有のファイバー ネットワークを利用して、世界中でプライベート接続を可能にします。 このアーキテクチャの場合、Cloud VPC は必須です。
Cloud Interconnect Cloud Interconnect により、オンプレミス ネットワークが、可用性が高くレイテンシの低い接続を通じて Google のネットワークまで拡張されます。Dedicated Interconnect を使用して Google に直接接続することも、Partner Interconnect を使用して、サポートされているサービス プロバイダを介して Google に接続することもできます。 e コマースサイトでは、倉庫管理システムや請求システムなど、オンプレミスのバックエンド サービスの呼び出しが必要になる場合があります。
Cloud Interconnect は、この課題の解決策の 1 つになります。
Cloud VPN Cloud VPN は、IPsec VPN トンネルを使用して、オンプレミス ネットワークを Google のネットワークに安全に拡張します。暗号化されたトラフィックは、公共のインターネットを介して 2 つのネットワーク間を移動します。Cloud VPN は少量のデータ接続に適しています。 e コマースサイトでは、倉庫管理システムや請求システムなど、オンプレミスのバックエンド サービスの呼び出しが必要になる場合があります。
Cloud VPN は、この課題の解決策の 1 つになります。
Cloud Load Balancing Cloud Load Balancing は、Google が管理する負荷分散ソリューションです。L4(TCP / UDP)と L7(HTTP)の両方の負荷分散をサポートします。また、SSL(HTTPS)終端エンドポイントとしても機能します。Google Cloud ロードバランサを作成すると、単一のエニーキャスト IP が提供されます。この IP にアクセスを試みたユーザーはすべて最も近い Google の拠点に自動的にルーティングされます。Google のプレミアム ティア ネットワークにより、ネットワーク レイテンシは低くなります。 このアーキテクチャの場合、Cloud Load Balancing は必須です。
Cloud CDN Cloud CDN(コンテンツ配信ネットワーク)は、世界各地に分散している Google のエッジ接続拠点を使用して、HTTP(S) で負荷分散されたコンテンツをユーザーの近くにあるキャッシュに保存します。Google のネットワーク エッジのキャッシュにコンテンツを保存すると、コストを削減しながら、ユーザーにより速くコンテンツを配信できます。 このシナリオで Cloud CDN は必須ではありませんが、特に静的コンテンツの場合は推奨プロダクトになります。

プラットフォーム

Google Cloud プロダクト 用途
Google Kubernetes Engine(GKE) GKE は、コンテナ化されたアプリケーションをデプロイするための、Google 管理の Kubernetes プロダクトです。GKE はオープンソースの Kubernetes に完全に準拠しており、リージョン クラスタ(高可用性)、プライベート クラスタ垂直ポッド自動スケーリングクラスタの自動スケーリングGPUプリエンプティブ ノードなど、さまざまな高度な機能を提供します。 このアーキテクチャの場合、GKE は必須です。
Istio Istio は、マイクロサービスを保護、接続、モニタリングするための一貫した方法を提供し、マイクロサービス環境の管理を簡素化します。 このアーキテクチャで Istio は必須ではありませんが、高度なモニタリング、トラフィックの暗号化、ルーティングなどの便利な機能を使用できます。また、フォールト インジェクションによってアプリケーションの耐障害性をテストすることもできます。
Apigee Apigee はマネージド API ゲートウェイです。Apigee を使用すると、API の設計、公開、モニタリング、収益化を安全に行うことができます。
Apigee は公開 API と非公開 API の両方に使用できます。マイクロサービス アーキテクチャでは、公開 API を Google Cloud 上でホストし、Google Cloud 上のマイクロサービスによってのみ使用される非公開 API としてバックエンドのオンプレミス システムを公開できます。
このアーキテクチャで Apigee は必須ではありませんが、サイトのコンテンツはすべて公開 API によって提供することをおすすめします。Apigee のような API ゲートウェイは、割り当て、バージョニング、認証など、API 管理に必要な多くの機能を提供します。
Pub/Sub Pub/Sub は、メッセージング / ストリーミング システムです。このアーキテクチャで使用すると、マイクロサービス間のメッセージバスとして機能し、マイクロサービス間の非同期ワークフローを可能にします。 Pub/Sub は必須ではありませんが、パブリッシャー / サブスクライバーのパターンはスケーリングの問題の軽減に役立ちます。

ストレージ

Google Cloud プロダクト 用途
Cloud Storage Cloud Storage は、統合型オブジェクト ストレージの API を提供します。ウェブサイトのコンテンツ提供、データのバックアップとアーカイブ、ラージ オブジェクトの配信など、さまざまな用途に適しています。e コマースサイトの場合、Cloud Storage は主に商品画像や動画などの静的アセットの保存と提供に使用されます。 Cloud Storage のシームレスなスケーラビリティと Cloud CDN の組み合わせは、このドキュメントで説明しているマイクロサービス アーキテクチャに適しています。おすすめのプロダクトです。
Firestore Firestore は、高速なフルマネージドの NoSQL ドキュメント データベースです。 このアーキテクチャで Firestore は必須ではありませんが、e コマースサイトでよく見られるいくつかのユースケースには適しています。たとえば、ユーザーのショッピング カートやユーザーのメタデータの格納に使用できます。
Cloud SQL Cloud SQL は MySQL と PostgreSQL に対応した Google 管理のプロダクトです。これらのリレーショナル データベースはさまざまな用途で使用されています。 このシナリオで Cloud SQL は必須ではありませんが、e コマースサイトでよく見られるいくつかのユースケースには適しています。たとえば、Cloud SQL を使用して注文を保存することで、簡単な集計と計算が可能になります。
Cloud Spanner Spanner は、水平スケーリングが可能で強整合性を備えたリレーショナル データベースで、世界規模で利用できます。SLA で 99.999% の稼働時間(マルチリージョン インスタンスの場合)を保証し、ビジネスに不可欠なデータに非常に高い可用性を提供します。 このシナリオで Spanner は必須ではありません。Spanner は、世界規模でトランザクションの整合性を提供するリレーショナル データベースで、世界中の利用者がアクセスする e コマースサイトに非常に適しています。
Memorystore Memorystore for Redis は、Redis のマネージド バージョンで、メモリ内に Key-Value ペアを格納するデータベースです。Redis は、レイテンシが低いため、頻繁にアクセスされるデータに最適です。 このシナリオで Memorystore は必須ではありませんが、ユーザー セッション情報の保存やアプリケーション キャッシュの提供など、ウェブサイトでよく見られるユースケースに適しています。

これ以外の Google Cloud プロダクトも使用できますが、上のリストには e コマース アーキテクチャで最も一般的なものが含まれています。このアーキテクチャを進化させて、たとえば Cloud BigtableBigQueryAutoMLAI Platform などのプロダクトを使用して、データから分析情報を収集するコンポーネントを追加することもできます。

特定のテクノロジーへの依存度が高い場合や、移行のコストが高すぎる場合は、ターゲット アーキテクチャで現在のテクノロジーの一部を引き続き使用することもできます。Google Cloud では、一般的な e コマース テクノロジーを次のように実装できます。

  • Google Cloud Partner に Oracle ワークロードの管理を任せることができます。これにより、Google Cloud インフラストラクチャとの間のレイテンシがミリ秒未満になるだけでなく、既存のライセンスを再利用できます。
  • SAP と Google Cloud のパートナーシップにより、HANAHybris など、Google Cloud 上で幅広い SAP ワークロードを実行できます。
  • GKE 上の Apache Solr を実行することも、Google Cloud Marketplace で入手可能な Solr ソリューションを使用することもできます。
  • GKE で Elasticsearch を実行できます(たとえば、Cloud Marketplace ソリューションを使用)。また、Google Cloud 上に Elastic によって作成されたマネージド サービスを使用することもできます。

Apigee、Cloud VPN、Cloud Interconnect

このプロジェクトの早い段階で行わなければならない最も重要な決定事項の 1 つは、GKE でホストされている新しいマイクロサービスとオンプレミスのレガシー システムとの間の通信を処理する方法です。主な解決策には、API ベースの通信とプライベート接続に基づく通信の 2 つがあります。この 2 つは併用することもできます。

API ベースの場合、2 つの環境間のプロキシとして Apigee などの API 管理ソリューションを使用します。これにより、レガシー システムで公開する部分とその公開方法をきめ細かく制御できます。また、API の使用者に影響を与えることなく、API の実装をシームレスにリファクタリング(つまり、レガシー サービスからマイクロサービスに移行)できます。次の図は、Apigee、オンプレミス システム、Google Cloud システムの間のやり取りを示しています。

オンプレミスと GCP ベースのシステムの組み合わせでプロキシとして機能する Apigee

Apigee で大規模な Kubernetes API をデプロイするためのパターンと Apigee の eBook Beyond ESB Architecture with APIs に、この設計に役立つ情報が記載されています。

プライベート接続の場合は、プライベート ネットワーク接続を使用して Google Cloud とオンプレミス環境を接続します。マイクロサービスは、この接続を介してレガシー システムと通信します。Cloud VPN では、IPSec ベースの VPN トンネルを設定できます。より多くの帯域幅が必要な場合は、Cloud Interconnect を使用すると、可用性が高くレイテンシが低い接続を実現できます。さまざまなオプションの概要については、相互接続タイプの選択をご覧ください。

次の図では、Cloud VPN または Cloud Interconnect 経由でオンプレミス システムと Google Cloud システムを接続しています。

オンプレミス システムと Google Cloud ベースのシステムを接続する Cloud Interconnect または Cloud VPN

API ベースのソリューションは、アプリケーション チームによって実装されます。プライベート接続に基づくソリューションよりも、プロジェクトの開始時からレガシー アプリケーションとの統合を進める必要があります。長期的に見ると、API ベースのソリューションのほうが多くの管理オプションが提供されます。Cloud VPN または Cloud Interconnect に基づくソリューションは、ネットワーク チームによって実装され、プロジェクト開始当初のアプリケーションとの統合作業は少なくて済みます。ただし、それ以上の機能は提供されないので、長期的なメリットはありません。

移行プロセス

このセクションでは、新しいアーキテクチャへの移行手順の概要を示します。

要件

最初のマイクロサービスを GKE に移行する前に、作業する Google Cloud 環境を準備する必要があります。最初のマイクロサービスを GKE で本番環境に移行する前に、次のことを行ってください。

  • Google Cloud 組織を設定します。これは、Google Cloud リソースをホストするグローバル環境です。この手順では Google ID も構成します。この ID は、企業の社員が Google プロダクトを使用する際に必要とするアカウントです。このプロセスの概要については、エンタープライズ企業のベスト プラクティスをご覧ください。
  • Google Cloud リソースを制御する Google Cloud ポリシーを設計します。エンタープライズのお客様向けのポリシー設計をご覧ください。
  • Infrastructure as Code(IaC)を使用して GKE クラスタなどの Google Cloud リソースをデプロイする計画を策定します。これにより、標準化された、再現可能で監査可能な環境を構築できます。 Cloud Deployment Manager または Terraform の使用をおすすめします。Google Cloud 上の IaC のリソースは Infrastructure as Code のページで取得できます。
  • さまざまな GKE 機能を調べて、必要に応じて微調整します。ビジネスに不可欠なアプリケーションの場合は、いくつかのデフォルトを変更してクラスタを強化できます。 本番環境での GKE 環境の準備クラスタのセキュリティの強化に具体的な方法が記載されています。
  • Kubernetes 用に継続的インテグレーション / 継続的デリバリー(CI / CD)を作成します。コンテナ イメージを作成するには、Cloud Build を使用できます。作成したイメージの保管と脆弱性の検出には、Container Registry を使用できます。これらのプロダクトを既存の CI / CD ツールと組み合わせることもできます。この作業と一緒に、コンテナをビルドして操作するためのベスト プラクティスを実装します。この作業をプロジェクトの早い段階で行うと、本番環境での問題発生を防ぐことができます。
  • 選択したオプションに応じて、Apigee アカウントを設定するか、Cloud VPN または Cloud Interconnect を使用して Google Cloud とオンプレミス データセンターの間にプライベート接続を設定します。

段階的に移行する

必要に応じてマイクロサービスを作成し、e コマースサイトの機能を 1 つずつ新しい環境に移行します。これらのマイクロサービスは、必要に応じてレガシー システムを呼び出すことができます。

このアプローチは、この大規模な移行プロジェクトをいくつかの小規模なプロジェクトにリファクタリングすることに相当します。この方法には次の 2 つの利点があります。

  • 小規模なプロジェクトにすることで、移行プロジェクト全体よりも境界の設定や推論が容易になります。ウェブサイト全体を 1 回の作業で移行する場合、システム間の関係、制約事項、ウェブサイトに依存するサードパーティ システムなどをチームで把握していなければならないため、エラーのリスクが高くなります。
  • 複数の小規模なプロジェクトに分割すると、柔軟性が増します。チームの人数が少なくても、これらのプロジェクトに 1 つずつ順番に処理できるので、負担がかかりすぎることはありません。複数のチームがある場合は、いくつかの作業を並行して行い、一度に複数の移行を進めることができます。

プロジェクトのこの段階で最も重要となる決定事項は、どの機能をどのタイミングで移行するかを決めることです。この判断を行う場合、機能間の依存関係を考慮する必要があります。正常に動作するために他の機能を必要としているものあれば、他の機能に依存せず、独立しているものもあります。機能の依存関係が少ないほど、移行は容易になります。依存関係の問題については、移行する機能を決定するときに考慮すべき要因とともに、どの機能を最初に移行するのかで詳しく説明します。

例: ショッピング カートの移行

移行プロセスを具体的に説明するため、このセクションでは、e コマースサイトのショッピング カートという単一機能を移行する場合について考えてみます。

この機能の依存関係を確認するため、標準的なユーザーの操作の流れとモノリシック アプリケーションの機能を想定してみましょう。

  1. ウェブサイトの閲覧中に、ユーザーが気になる商品を見つけました。
  2. ユーザーが [ショッピング カートに追加] をクリックします。この操作で、ユーザーのブラウザからショッピング カート機能への API 呼び出しがトリガーされます。これが最初の依存関係になります。フロントエンドがショッピング カートを操作しています。
  3. ショッピング カート機能が呼び出しを受信すると、商品の在庫を確認します。このイベントにより、ショッピング カート機能から在庫処理システムへの API 呼び出しがトリガーされます。これが 2 番目の依存関係です。ショッピング カートは在庫サブシステムに依存しています。
  4. 商品の在庫がある場合、ショッピング カート機能は「ユーザー A のカートに商品 X のインスタンスが 1 個存在する」という情報を格納します。これが 3 番目の依存関係です。ショッピング カートは、この情報を格納するデータベースを必要とします。
  5. ユーザーが会計をして支払いプロセスに進むと、ショッピング カートは支払いサブシステムからクエリの結果を受け取り、合計金額を計算します。 支払いが完了すると、支払いサブシステムがショッピング カートを空にするようにショッピング カート機能に通知します。これが 4 番目の依存関係です。ショッピング カートは支払いサブシステムからクエリの結果を受け取ります。

要約すると、ショッピング カート機能がフロントエンドと支払いサブシステムから呼び出され、データベースと在庫サブシステムにクエリを送信します。

ショッピング カートの保存には、ドキュメント データベースが適しています。ショッピング カードのデータを処理するのにリレーショナル データベースの能力は必要ありません。ユーザー ID で簡単にインデックスを作成できます。 Firestore は、サーバーレスのマネージド NoSQL ドキュメント データベースで、このユースケースには最適なデータベースです。これはターゲット アーキテクチャに推奨されるデータストアです。

ショッピング カートのデータはいくつかの方法で移行できます(詳しくは、後述のデータ移行戦略をご覧ください)。 この記事では、後で説明する定期メンテナンスを前提としています。このアプローチでは、次のようにショッピング カートの機能を移行します。

  1. ショッピング カートの API を実装する新しいマイクロサービスを作成します。Firestore を使用してショッピング カートを保管します。この新しいマイクロサービスで在庫サブシステムの呼び出しが可能であることを確認します。
  2. 従来のショッピング カート サブシステムからショッピング カートを抽出し、Firestore に書き込むスクリプトを作成します。スクリプトを作成し、必要に応じて何度でも実行できるようにします。最後の実行以降に変更されたショッピング カートだけをコピーするようにします。
  3. 同じ処理を行うスクリプトを作成します。ただし、方向は逆です。この場合、Firestore からレガシー システムにショッピング カートをコピーします。このスクリプトは、移行をロールバックする必要がある場合にのみ使用します。
  4. Apigee を使ってショッピング カートの API を公開します。
  5. フロントエンドと支払いサブシステムに加える変更を準備してテストし、新しいショッピング カートでマイクロサービスを呼び出せるかどうか確認します。
  6. 手順 2 で作成したデータ移行スクリプトを実行します。
  7. ウェブサイトをメンテナンス モードにします。
  8. データ移行スクリプトを再度実行します。
  9. 手順 5 の変更内容を本番環境のレガシー システムにデプロイします。
  10. ウェブサイトのメンテナンス モードを無効にします。

これで、ウェブサイトのショッピング カート機能が Google Cloud. 上でホストされるマイクロサービスに移行されました。手順 5 は、レガシー システムに対する変更が必要になるため、このプロセスで最も難しい作業になるでしょう。ただし、より多くの依存関係がマイクロサービスになっていくため、マイクロサービスに移行する機能が増えるほど、移行は容易になります。これらはモノリシック アプリケーションよりも疎結合で、変更やデプロイが簡単です。

また、新しいマイクロサービスで元のショッピング カート データベースを呼び出して、データを Firestore に移行することもできます。どちらの移行モデルを選択するかは、マイクロサービスと元のデータベース間のレイテンシ、スキーマのリファクタリングの複雑さ、採用するデータ移行戦略などによって異なります。

どの機能を最初に移行するか

このセクションでは、最初に移行する機能(最初の移行作業)を決める方法について説明します。複雑な移行作業にはリスクが伴います。このようなリスクを軽減するには分割統治法が有効です。

移行を計画するときに、影響のない機能から検討を始めるかもしれません。このような選択をすると、すぐに成果が出るかもしれませんが、チームにとって最善の学習方法とは言えません。目先の結果を求めず、時間をかけてすべての機能を評価し、移行計画を作成してください。

機能の分析を行うときに、次の領域について評価を行いましょう。

  • ビジネス プロセス
  • 設計と開発
  • 運用
  • チーム

ビジネス プロセスの評価

移行チームは初期の移行作業を行いながら、さまざまなプロセスを理解し、開発していきます。この過程では、間違いを犯すこともあるでしょう。したがって、メインの業務に支障をきたさないよう、初期の作業からはビジネスに不可欠なシステムの移行を除外してください。これらのシステムの移行作業は、チームが時間をかけてビジネス プロセスを評価したうえで慎重に行う必要があります。ビジネス プロセスを評価するときは、開発プロセスだけでなく、コンプライアンスやライセンスに関連するプロセスも検討しなければなりません。

設計と開発の評価

設計と開発の観点からすると、移行作業の初期段階では、他の機能やデータへの依存度が最も少なく、簡単にリファクタリングできる機能を移行するのが理想的です。

依存関係とリファクタリングの作業量を考慮して、それぞれの機能を分析する必要があります。機能の依存関係を分析するには、次の点を検討します。

  • 依存関係の種類 - データや他の機能との依存関係
  • 依存関係の規模 - 依存関係の変更によって影響を受ける可能性のある機能の数

データへの依存度が高い機能を移行する場合は、次の点に注意が必要です。

  • 機能を移行してから関連データを移行する場合は、最初の移行作業の後に、プロデューサ、コンシューマ、データストア間のネットワーク レイテンシが増加します。
  • 移行の段階でデータの整合性と同期の問題が発生します。一時的に複数の場所でデータの読み書きが発生する可能性があるためです。

また、各機能に必要なリファクタリングの量も評価する必要があります。 リファクタリングの量は、機能の現在の設計だけでなく、将来の方向性によっても変わります。また、関連するビジネス プロセスへの影響も検討する必要があります。

この評価で検討すべき最も重要な項目は次のとおりです。

  • この機能はどのデータを使用するのか
  • この機能はどのくらいのデータを使用しているのか
  • この機能が正常に機能するために他の機能を必要とするか
  • この機能の変更によって影響を受ける機能はいくつあるか
  • この機能にネットワークまたは接続の要件があるか
  • この機能の現在の設計がリファクタリングにどのように影響するのか

運用の評価

運用面では、カットオーバーまでのダウンタイムを容認できる機能かどうかを検討する必要があります。ダウンタイムを最小限に抑える必要がある場合に、高可用性を必要とする機能を移行すると、余分な作業が増える可能性があります。

チームの評価

明確に定義されたプロセスを持ち、初期の移行作業をリードできるチームを選択しましょう。移行プロセスの途中で発生した課題に取り組み、解決策を見つけ出せる人材を選ぶ必要があります。

初期の移行作業を選択する

初期の移行作業としては、取り組む意味があり、複雑すぎず、失敗のリスクを最小限に抑えられるものを選ぶのが理想的です。また、初期の移行プロセスでは次の点も考慮する必要があります。

  • 機能だけでなく、関連するビジネス プロセスも考慮し、リファクタリングが発生しないようにする。
  • ステートレスにする。つまり、外部のデータ要件がないようにする。
  • 依存関係がほとんどないか、まったくない機能を選ぶ。

移行計画の例

以下に、移行順序の例を示します。

  1. プラットフォームのフロントエンド(つまり、ユーザー インターフェース)
  2. ステートレスな機能(通貨変換サービスなど)
  3. 独立したデータセット(他のデータセットに依存しないデータセット)を使用する機能(実店舗を一覧表示するサービスなど)
  4. 共有データセットを使用する機能(e コマース プラットフォームのビジネス ロジック)

プラットフォームのフロントエンドとステートレスな機能

通常、プラットフォームのフロントエンドとステートレスな機能には依存関係がほとんどありません。どちらもアーキテクチャの重要なコンポーネントであるため、初期に移行する有力候補となります。初期の移行段階では、バックエンド API が従来のデータセンターか、別のクラウド プロバイダでホストされているランタイム環境から提供されるため、リファクタリングの量が少なくて済みます。

プラットフォームのフロントエンドとステートレスな機能については、統合とデプロイメントのパイプラインを中心に検討します。GKE ワークロードはコンテナ化が必要なため、運用側の作業量が増える可能性があります。

独立したデータセットを使用する機能

次に移行するコンポーネントは、他のデータセットから独立しているデータセットを使用する機能です。依存関係のあるデータセットと比べると、独立したデータセットは移行前のシステムから容易に抽出できます。ステートレスな機能と異なり、このようなデータセットを使用する機能を移行する場合は、新しいデータストアの作成と管理、実際のデータの移行が必要になります。

データの移行を計画するときに、ストレージ システムも選択します。 アプリケーションをモダナイズするので、次のものを使用できます。

  • Cloud Storage や Filestore などのマネージド データ ストレージ サービス(ファイルの保存)
  • Cloud SQL(RDBMS からのデータの移行)
  • Firestore(NoSQL データベースからのデータの移行)

共有データセットを使用する機能

移行が最も難しいのが、共有データセットを使用する機能です。後で詳しく説明しますが、一貫性、分散性、アクセス、レイテンシの要件があるため、データの移行は非常に難しくなります。

データ移行戦略

データを移行する場合、一般的な流れは次のようになります。

  1. 前のサイトから新しいサイトにデータを転送する。
  2. 複数のソースから同じデータを同期する場合など、データの統合で発生した問題を解決する。
  3. データの移行を検証する。
  4. 新しいサイトをマスターコピーに昇格する。
  5. フォールバックの必要がなくなったら、前のサイトを廃止する。

データの移行戦略を決める場合、次のことを検討します。

  • 移行が必要なデータの量はどれくらいか
  • このデータはどのくらいの頻度で変更されるのか
  • カットオーバーまでのダウンタイムを許容できるか
  • 現在のデータ整合性モデルは何か

最善の方法はありません。どれを選択するかは環境と要件によって異なります。

以下では、次の 4 つのアプローチについて説明します。

  • 定期メンテナンス
  • 継続的なレプリケーション
  • Y(書き込み / 読み取り)
  • データアクセス マイクロサービス

どのアプローチにも課題はあります。問題点は、データ移行の規模や要件によって異なります。

マイクロサービス アーキテクチャの場合、データアクセス マイクロサービスが最も望ましい選択肢ですが、データ移行という点では他のアプローチも有効です。データアクセス マイクロサービスを使用するためにインフラストラクチャの最新化が必要な場合は、他のアプローチのほうがよい場合もあります。

次のグラフは、それぞれのアプローチのカットオーバーまでの期間、リファクタリングの作業量、柔軟性を比較しています。

4 つのアプローチの柔軟性、リファクタリングの作業量、カットオーバーまでの期間を相対的に表した棒グラフ

これらのアプローチを実施する前に、新しい環境に必要なインフラストラクチャが準備されていることを確認してください。

定期メンテナンス

ワークロードのカットオーバーに余裕がある場合は、定期メンテナンスが理想的な選択肢です(カットオーバーの時期を計画できるため)。

このアプローチでは、次の手順で移行を行います。

  1. 前のサイトにあるデータを新しいサイトにコピーします。このコピーを行うことで、カットオーバーまでの時間を短縮できます。この後は、移行期間中に変更されたデータだけをコピーします。
  2. データの検証と整合性のチェックを行い、前のサイトのデータと新しいサイトにコピーしたデータを比較します。
  3. コピーしたデータがこれ以上変更されないように、これらのデータに書き込み権限のあるワークロードとサービスを停止します。
  4. 最初のコピーの後に発生した変更を同期します。
  5. 新しいサイトを使用するように、ワークロードとサービスをリファクタリングします。
  6. ワークロードとサービスを開始します。
  7. フォールバックの必要がなくなったら、前のサイトを廃止します。

このアプローチでは、ワークロードとサービスのリファクタリングは最小限になるため、ほとんどの作業が運用側で行われます。

継続的なレプリケーション

カットオーバーまでに余裕のないワークロードがある場合は、最初のコピーと検証の後にレプリケーションを継続的に行うようにスケジューリングできます。このとき、データが変更される頻度も考慮する必要があります。2 つのシステムが同期された状態を維持するのが難しい場合もあります。

継続的なレプリケーションは、定期メンテナンスよりも複雑になりますが、同期に必要なデータ量が最小限になるため、カットオーバーまでの時間は短くなります。継続的なレプリケーションを行う場合の移行手順は次のようになります。

  1. 前のサイトにあるデータを新しいサイトにコピーします。このコピーを行うことで、カットオーバーまでの時間を短縮できます。この後は、移行期間中に変更されたデータだけをコピーします。
  2. データの検証と整合性のチェックを行い、前のサイトのデータと新しいサイトにコピーしたデータを比較します。
  3. 前のサイトから新しいサイトへの継続的なレプリケーションを設定します。
  4. 移行するデータ(つまり、前の手順に含まれるデータ)にアクセスできるワークロードとサービスを停止します。
  5. 新しいサイトを使用するように、ワークロードとサービスをリファクタリングします。
  6. レプリケーションによって新しいサイトがレガシーサイトに完全に同期されるまで待ちます。
  7. ワークロードとサービスを開始します。
  8. フォールバックの必要がなくなったら、前のサイトを廃止します。

このアプローチでは、定期メンテナンスの場合と同様に、大半の作業は運用側で行います。

Y(書き込み / 読み取り)

ワークロードに高い可用性が必要で、カットオーバーまでのダウンタイムを許容できない場合は、別のアプローチが必要になります。この場合、このドキュメントで Y(書き込み / 読み取り)と呼んでいるアプローチを使用できます。これは一種の並行移行です。 移行が終わるまで前のサイトと新しいサイトの両方でデータの書き込みと読み取りを行います。この Y の文字は、移行期間中のデータフローの形を記号として表したものです。

このアプローチの場合、移行手順は次のようになります。

  1. データを前のサイトから読み取り、前のサイトと新しいサイトの両方に書き込むように、ワークロードとサービスをリファクタリングします。
  2. 新しいサイトへの書き込みを有効にする前に書き込まれたデータを識別し、そのデータを前のサイトから新しいサイトにコピーします。前述のリファクタリングとともに、これによりデータストアがアライメントされます。
  3. データの検証と整合性のチェックを行い、前のサイトのデータと新しいサイトのデータを比較します。
  4. 読み取りオペレーションを前のサイトから新しいサイトに切り替えます。
  5. データの検証と整合性のチェックを再度行い、前のサイトのデータと新しいサイトのデータを比較します。
  6. 前のサイトへの書き込みを無効にします。
  7. フォールバックの必要がなくなったら、前のサイトを廃止します。

定期メンテナンスや継続的なレプリケーションとは異なり、このアプローチでは複数のリファクタリングが必要になるため、ほとんどの作業を開発側が行うことになります。

データアクセス マイクロサービス

Y(書き込み / 読み取り)アプローチで必要なリファクタリングを少なくしたい場合は、データアクセス マイクロサービスを使用するようにワークロードとサービスをリファクタリングします。これにより、データの読み取り / 書き込みオペレーションが一元化されます。このスケーラブルなマイクロサービスがデータ ストレージ レイヤへの唯一のエントリ ポイントとなり、レイヤのプロキシとして機能します。アーキテクチャの他のコンポーネントに影響を与えず、カットオーバーまでの期間を考慮せずにコンポーネントをリファクタリングできるため、ここで説明しているアプローチの中では最も柔軟な方法となります。

データアクセス マイクロサービスを使用するアプローチは Y(書き込み / 読み取り)とよく似ています。違うのは、データ ストレージ レイヤにアクセスするすべてのワークロードとサービスをリファクタリングするのではなく、データアクセス マイクロサービスをリファクタリングする点です。このアプローチの場合、移行手順は次のようになります。

  1. 前のサイトと新しいサイトの両方にデータを書き込むように、データアクセス マイクロサービスをリファクタリングします。読み取りは前のサイトに対して行われます。
  2. 新しいサイトへの書き込みを有効にする前に書き込まれたデータを識別し、そのデータを前のサイトから新しいサイトにコピーします。前述のリファクタリングとともに、これによりデータストアがアライメントされます。
  3. データの検証と整合性のチェックを行い、前のサイトのデータと新しいサイトのデータを比較します。
  4. 新しいサイトからデータを読み取るようにデータアクセス マイクロサービスをリファクタリングします。
  5. データの検証と整合性のチェックを再度行い、前のサイトのデータと新しいサイトのデータを比較します。
  6. 新しいサイトにのみ書き込むように、データアクセス マイクロサービスをリファクタリングします。
  7. フォールバックの必要がなくなったら、前のサイトを廃止します。

このアプローチでは、Y(書き込み / 読み取り)と同様に、作業の大半を開発側で行います。ただし、リファクタリングはデータアクセス マイクロサービスにのみ行うため、Y(書き込み / 読み取り)よりも負担はかなり軽減されます。

マイクロサービスのベスト プラクティス

以下では、マイクロサービスの設計、作成、デプロイを行う場合のベスト プラクティスについて説明します。

マイクロサービスの設計

マイクロサービスを設計する場合は、マイクロサービスのコンテキストと境界を適切に決定できる設計パターンを使用します。これにより、マイクロサービス ワークロードの不要な断片化を防ぐことができます。また、マイクロサービスが有効なコンテキスト(またはドメイン)を正確に定義できます。このような設計パターンとして、ドメイン主導の設計(DDD)があります。

API コントラクト

マイクロサービスは一連のインターフェースからのみ呼び出す必要があります。インターフェースは、OpenAPI Initiative 仕様(以前の Swagger)や RAML などの API 定義言語で実装できるコントラクトにより明確に定義されている必要があります。明確に定義された API コントラクトとインターフェースを使用すると、これらの API インターフェースに対するテストを、ソリューションのメイン コンポーネントとして開発できます(たとえば、テストドリブンな開発が可能になります)。

変更管理

API コントラクトに重大な変更を加える必要がある場合は、その変更に応じてクライアントが行うリファクタリングを最小限に抑えるため、事前に準備する必要があります。この問題に対処する方法は 2 つあります。

  • バージョニング
  • 新しいマイクロサービスの実装

バージョニング

既存のクライアントに影響を与える更新を柔軟に管理するには、マイクロサービスのバージョニングを実装する必要があります。バージョニングにより、既存のバージョンを使用しているクライアントに影響を与えることなく、更新後のマイクロサービスをデプロイできます。バージョニングを行う場合は、変更が最小限であっても、既存のコントラクトに影響を及ぼす変更を行うたびに、新しいバージョンを作成する必要があります。

次のスキームを使用してバージョン管理スキームを実装できます。

  • グローバル バージョニング
  • リソース バージョニング

グローバル バージョンでは、API 全体のバージョニングを行います。たとえば、次のようにバージョン情報をリソース URI に組み込みます。

/api/v1/entities or api.v3.domain.tld/entities

このバージョニングは 1 か所で管理されるため、デプロイは簡単ですが、リソース バージョニングほどの柔軟性はありません。グローバル バージョニングの例については、Kubernetes API のバージョニング スキームをご覧ください。

リソース バージョニングでは、マイクロサービスが提供するリソースのバージョンを個別に管理できます。このスキームは非常に柔軟です。たとえば、リソースに対するオペレーション(HTTP 動詞など)でリソースのバージョンを管理できます。このバージョニングはさまざまな方法で実装できます。URI を使用することも、カスタムまたは標準 HTTP リクエスト ヘッダーを使用することもできます。例を示します。

Accept: application/tld.domain.entities.v2+json

リソース バージョニングは、すべてのエンティティに対して汎用的なアプローチが必要になるため、グローバル バージョニングよりも設計が難しくなる場合があります。ただし、リソースに対して個別のアップグレード ポリシーを実装できるため、グローバル バージョニングよりも柔軟です。

新しいマイクロサービスの実装

影響のある変更に対応するもう 1 つのアプローチは、新しいコントラクトを使用する新しいマイクロサービスを実装することです。たとえば、マイクロサービスで非常に多くの変更が必要になり、既存のバージョンを更新するよりも新しいバージョンを作成したほうがよい場合に、このアプローチを使用します。ただし、このアプローチの場合、マイクロサービスの機能やコントラクトが重複する可能性もあります。新しいマイクロサービスの実装後、クライアントを段階的にリファクタリングし、前のサービスから移行することもできます。

次のステップ