この記事は、サービス メッシュを使用して、仮想マシンでアプリケーションを実行しているオンプレミスのデータセンターなどの移行元の環境から、機能ごとに Google Kubernetes Engine (GKE)に移行する方法について説明するシリーズのパート 1 です。
このシリーズは、このコンセプトに関する記事と付随するチュートリアルで構成されています。この記事では、移行の理由と大まかな手順について説明します。このチュートリアルでは、移行の例を示します。
はじめに
以下を最小限に抑えながら、段階的に移行とモダナイズを行う複雑なインフラストラクチャを担当する IT プロフェッショナルを対象としています。
- ダウンタイム
- リファクタリングの作業
- ネットワークの運用上の複雑さ
説明するコンセプトはすべてのクラウドに適用されるため、この記事ではクラウド テクノロジー、コンテナ、マイクロサービスに精通していることを前提としています。
ハイブリッドおよびマルチクラウドのパターンとプラクティスで説明されているように、クラウドへの移行パターンは「リフト&シフト」、「改善して移行」、「削除して置き換え」の 3 つに大別できます。この記事では、「改善して移行」のパターンについて説明します。ここで、このパターンは、アプリケーション全体ではなく、アプリケーションの各機能に適用されます。
移行時は、アプリケーションの一部の機能が Google Cloud に移行し、その他が移行元の環境に残るハイブリッド アーキテクチャになります。移行が完了すると、アプリケーション全体が Google Cloud でホストされます。
用語
- アプリケーション
- この記事では、アプリケーションとは、多くの機能を備えた完全なソフトウェア システムを指します。ユーザーはアプリケーションを 1 つの単位として認識します。たとえば、書籍を販売するウェブサイトはアプリケーションです。
- 機能
機能とは、アプリケーションの機能の単位を指します。たとえば、ブックストア アプリの書籍のレビュー機能などです。機能はマイクロサービスで構成されます。
機能は、どのような種類のデータにも依存しないステートレスにすることも、データに依存するステートフルにすることもできます。
- マイクロサービス
マイクロサービスとは、アプリケーション機能に対応するように構築されたスタンドアロン コンポーネントを指します。この記事では、ユーザーを区別できないさまざまなマイクロサービスでアプリケーションが構成されています。たとえば、書籍のレビューを処理するコンポーネントはマイクロサービスです。
マイクロサービス パターンでは、アプリケーションは複数のマイクロサービスの集合体で、それぞれが特定の目的を持っています。たとえば、書籍の評価を処理する 1 つのマイクロサービスと、書籍のレビューを処理する 1 つのマイクロサービスがあるとします。これらのマイクロサービスは疎結合で、定義した API を介した相互のインターフェースとして機能します。これらは異なる言語やフレームワーク(多言語で記述されたアプリケーションなど)で作成でき、異なるライフサイクルを割り当てることが可能です。
各マイクロサービスの境界線をさらに定義するために、次のツールを使用してそれらをコンテナ化できます。
- Docker は、オペレーティング システムレベルでユーザー空間レベルのプログラムを隔離するためのツールです。コンテナと呼ばれるパッケージを実行します。
- Kubernetes は、コンテナ化されたワークロードのための代表的なオーケストレーション ソリューションです。サービス ディスカバリ、負荷分散、自己修復の Pod とノード、Secret、構成管理などの機能が用意されています。
- Google Kubernetes Engine(GKE)は Google Cloud の一部で、本番環境に対応したマネージド環境です。
- サービス メッシュ
サービス メッシュとは、さまざまなサービスをリンクし、サービス ディスカバリ、安全な通信、負荷分散、トラフィック管理、モニタリング、オブザーバビリティなどの高価値なネットワーキング機能を提供するソフトウェアを指します。
サービス メッシュの一般的な実装では、各サービスを、こうした機能を提供するプロキシのペアを設定します。サービス プロキシはほとんどの場合、サイドカーと呼ばれます。サイドカーの役割は、アプリケーションの知識がなくても、接続されているアプリケーションを強化して改善させることです。
- 移行
移行とは、移行元の環境で実行されている 1 つ以上のアプリケーションの機能を Google Cloud などの移行先環境に移行するプロセスのことです。この記事では、次のいずれかの移行を行います。
- ビッグバン方式の移行: アプリケーションのすべての機能を一度に移行します。
- 段階的な機能ごとの移行: 一度に 1 つの機能を移行します。
- コンプライアンス テストスイート
コンプライアンス テストスイートは、環境に対して実行して、指定された要件のセットを満たしているかどうかを確認するテストセットです。環境が有効である場合、要件を満たしています。たとえば、テスト リクエストに対するレスポンスの検証や、アプリケーションの依存関係がインストールされているかどうかの確認を行えます。
モニタリング、トレース、サービス メッシュの可視化ツールを使用して、手動で検証を行えます。その後、テストスイートを実装して、時間の経過とともに進化させることが可能です。
- 読み込みテスト。テスト トラフィックを環境に自動的に送信して結果を評価することで、テストスイートを進化させることが可能です。
- コンプライアンス テストツール。専用のツールを使用して、テストスイートの設計と開発を行えます。
段階的な移行戦略を選択する理由
1 回に 1 つ以上のアプリケーションを移行することには課題やリスクが伴うため、ビッグバン方式の移行は困難です。時間と予算に制約がある場合、ビッグバン方式の移行に重点を置くと、新しいアプリケーション機能に取り組むための余力が十分得られなくなります。
一方、機能ごとの段階的な移行では、移行するワークロードのサイズが小さくなるため、全体的な複雑さが少なくなります。1 つの機能のフットプリントが、アプリケーション全体の場合と比較すると小さくなります。リスクが高い 1 回の実行ではなく、段階的な移行を行うことで、小規模な移行イベントにリスクを分散できます。また、段階的な移行では、さまざまな種類の機能に対応するために複数の移行戦略を計画し、設計して開発することもできます。
最初に移行する機能の選択方法とステートフル機能の移行方法については、モノリシック アプリケーションを Google Kubernetes Engine のマイクロサービスに移行するをご覧ください。
サービス メッシュを使用する理由
サービス メッシュは、サービス機能(ビジネス ロジックの実装方法)とネットワーク機能(トラフィックをサービス機能にルーティングする方法とタイミング)を切り離します。
移行元の環境では、ほとんどのサービス呼び出しがモノリシック プラットフォームで発生するため、ネットワークに関与しません。マイクロサービス アーキテクチャでは、サービス間の通信がネットワーク経由で行われるため、サービスでこの異なるモデルに対処する必要があります。サービス メッシュでは、ネットワーク通信に対処する関数が抽象化されるため、アプリケーションごとに実装する必要はありません。また、サービス メッシュでは、安全な通信チャネル、負荷分散、トラフィック管理、モニタリング、オブザーバビリティの機能をすぐに利用できるため、ネットワークの運用上の複雑さも軽減します。
付属のチュートリアルでは、Istio をサービス メッシュとして使用します。Istio 機能は次のとおりです。
- トラフィック管理: HTTP、gRPC、WebSocket、TCP トラフィック用の豊富なルーティング ルールによるトラフィックのきめ細かい制御。
- リクエスト復元機能: 再試行、フェイルオーバー、回路ブレーカー、フォールト インジェクション。
- アクセス制御とレート制限をサポートするプラグイン可能なポリシーレイヤと構成 API。
- クラスタの上り(内向き)と下り(外向き)を含む、クラスタ内のすべてのトラフィックの指標、ログ、トレースの自動作成。
- サービス アカウント ベースの認証と承認を使用した安全なサービス間通信。
- A/B テスト、Canary ロールアウト、フォールト インジェクション、レート制限などのテストとデプロイのタスクの円滑化。
また、サービス メッシュを可視化することもできます。Kiali などのツールを Istio と統合すると、サービス メッシュに含まれるサービスとその接続方法を確認できます。
次のスクリーンショットは、Istio メッシュを表す Kiali サービスグラフの例を示しています。
サービス メッシュをデプロイして構成することで、トラフィックを移行元の環境または移行先の環境に動的にルーティングできます。トラフィック管理はメッシュに含まれるサービスに対して透過的であるため、移行をサポートするためにアプリケーションの構成を変更する必要はありません。
このアプローチはステートレスな機能に適していますが、ステートフルでありレイテンシの影響を受けやすい機能、または他の機能と非常に密結合な機能を移行するには、追加の計画とリファクタリングを行う必要があります。
- ステートフル。ステートフルな機能を移行する場合、ダウンタイムを最小限に抑え、移行中の同期や整合性に関する問題に対処するために、データも移行する必要があります。データの移行戦略について詳しくは、モノリシック アプリケーションを Google Kubernetes Engine のマイクロサービスに移行するをご覧ください。
- レイテンシの影響を受けやすい。ある機能が他の機能との通信時にレイテンシの影響を受けやすい場合は、移行プロセス中に追加のコンポーネントをデプロイすることが必要となる可能性があります。この感度を下げるために、データのプリフェッチやレイヤのキャッシュ保存に使用できるプロキシが一般的に使用されます。
- 他の機能と非常に密結合。2 つ以上の機能が非常に密結合である場合、それらを同時に移行することが必要となる可能性があります。このアプローチは、アプリケーション全体を移行するよりも簡単ですが、単一の機能を移行するよりも困難となる場合があります。
移行計画
このセクションでは、サービス メッシュを使用して、機能ごとの段階的な移行を実行する計画について説明します。この計画は次のフェーズで構成されています。
- 移行元の環境を評価する。
- 移行先の環境で基盤を構築する。
- 移行先の環境でサービスをデプロイし、移行先の環境へのトラフィックのルーティングを開始する。
- 移行元の環境へのトラフィックのルーティングを停止する。
- 移行元の環境を廃止する。
移行元の環境を評価する
移行の設計または実装のアクティビティの前に、移行元の環境を評価して情報を収集し、移行先の環境に対する一連の要件と、テストと検証のためのベースラインを確立します。まずは、移行するすべてのアプリケーション機能のカタログを構築します。機能ごとに、次の(包括的でない)一連の質問に回答できる必要があります。
- ランタイム環境とパフォーマンスの要件は何ですか?
- 他の機能との依存関係はありますか?
- この機能はビジネス クリティカルですか?
- この機能はステートレスですか、ステートフルですか?
- 移行にどの程度のリファクタリングが予測されますか?
- この機能によってカットオーバーに余裕が生まれますか?
評価プロセスと移行する機能の詳細については、こちらをご覧ください。次に、移行中と移行後に、ベースラインとしての移行元の環境および移行先の環境に対してコンプライアンス テストスイートを実行します。
テストスイートでは、移行中に次のアスペクトを検証することに集中する必要があります。
- プロビジョニング。構成する前に、環境で必要となるリソースをプロビジョニングします。
- 構成。環境でリソースをプロビジョニングした後、アプリケーションのニーズに合わせてリソースを構成します。構成テストスイートによって、環境でアプリケーションをホストするための準備が整っていることを確認できます。
- ビジネス ロジック。環境のプロビジョニングと構成を検証したら、アプリケーションのビジネス ロジックを検証します。たとえば、リクエストに対するレスポンスを検証できます。
InSpec、RSpec、Serverspec は、自動コンプライアンス テストスイートを開発するためのツールです。これらはプラットフォームに依存せず、拡張可能であるため、組み込みのコントロールをカスタマイズした独自のコントロールを実装できます。
次の図に、移行元の環境の例を示します。
移行先の環境のプロビジョニングを行う
これで環境と移行するアプリケーションに関する十分な情報が得られたので、評価中に設定した要件に従って移行先の環境のプロビジョニングを行えます。
このフェーズでは、コンプライアンス テストスイートを使用して、移行先の環境を検証できます。ハードウェアやネットワークのトポロジなど、移行元の環境と移行先の環境の最終的な違いを考慮してテストスイートを更新する必要があります。完全アクセス権を持っているオンプレミス環境から、通常はスタック全体への完全アクセス権を持っていないパブリック クラウド環境に移行するということを念頭に置いてください。
新しい環境のプロビジョニングを行うため、Infrastructure as Code の手法を適用して、インフラストラクチャを監査可能、再現可能、自動的にプロビジョニング可能にすることをおすすめします。
次の図は、移行元の環境と、新しくプロビジョニングした現在は空白の移行先の環境を示しています。
サービス メッシュを構成する
次のステップでは、移行元の環境と移行先の環境にまたがるサービス メッシュを設定します。サービス メッシュでは、移行先の環境に移行される、移行元の環境で実行中のさまざまなマイクロサービスが接続されます。このフェーズでは、サービス メッシュは空白であるため、サービスが登録されるのを待機します。サービス メッシュでまだ本番環境トラフィックを受信していません。
次の図に、移行元の環境と、移行先の環境にある空白のサービス メッシュを示します。
移行元の環境のサービスをメッシュに追加する
この例では、移行元の環境がサービス メッシュに直接統合されていません。移行元の環境で実行しているすべてのサービスを手動でサービス メッシュに登録する必要があります。環境がすでに Kubernetes で動作している場合、サービス メッシュ API とのネイティブな統合により、登録を自動化できます。
このステージでは、クライアントで引き続き移行元の環境のインターフェースを使用して、移行するマイクロサービスにアクセスします。サービス メッシュでまだ本番環境のトラフィックを受信していません。
次の図は、移行元の環境で実行されているサービスがサービス メッシュに追加されることを示しています。
サービス メッシュからサービスを公開する
移行元の環境が登録されたら、サービス メッシュを使用して移行元の環境で実行中のマイクロサービスを公開します。このステージでは、移行元の環境のインターフェースから移行先の環境のインターフェースにトラフィックを段階的にルーティングします。
クライアントでは負荷分散レイヤを介して 2 つの環境のインターフェースにアクセスするため、サービスは中断されません。また、サービス メッシュ内でのトラフィック ルーティングはクライアントに対して透過的です。ルーティング構成が変更されたことはクライアントではわかりません。
次の図は、移行元の環境で実行されているサービスが、サービス メッシュによって公開されることを示しています。
移行先の環境でサービスをデプロイする
このフェーズでは、マイクロサービスを移行先の環境にデプロイします。ここでは、これらのマイクロサービスをすでにコンテナ化していることを前提としています。そのプロセスが完了したら、移行先の環境で、移行するワークロードを初期化するデプロイ戦略を選択できます。
- 一括デプロイ: すべてのマイクロサービス インスタンスを同時にデプロイします。
- 段階的なデプロイ: 一度に 1 つのマイクロサービスをデプロイします。
移行先の環境のマイクロサービス インスタンスで、まだ本番環境のトラフィックを受信していません。
ステートフル マイクロサービスを移行する場合は、ダウンタイムを最小限に抑え、同期や整合性の問題に対処する必要があります。詳しくは、データの移行戦略をご覧ください。
Kubernetes と Istio とのネイティブな統合により、移行先の環境で実行されているマイクロサービスはサービス メッシュに自動的に登録されます。このステージでは、クライアントで、移行元の環境で実行されているサービス メッシュによって公開されたマイクロサービスを使用します。移行先の環境で実行されているマイクロサービスで、まだ本番環境のトラフィックを受信していません。
次の図は、本番環境のトラフィックを受信してない拡張サービスと、サービス メッシュを使用して公開された移行元の環境のサービスを示しています。
トラフィックを分割するルーティング ルールを設定する
ここで、サービス メッシュを使用して、移行元の環境で実行されているサービスと移行先の環境で実行されているサービスの間で、本番環境のトラフィックを分割するルーティング ルールを設定します。まず、本番環境トラフィックのごく一部を、移行先の環境で実行されているマイクロサービスのインスタンスにルーティングします。テストスイートと堅牢なモニタリングを使用して移行先の環境で信頼性を構築すると、時間の経過とともにトラフィックの総量を増やすことが可能です。
クライアントのリクエストは両方の環境でルーティングされるため、ステートフル マイクロサービスの追加の計画と調整が必要です。また、関連データも移行する必要があるため、移行中に、複数の信頼できる情報源がある一時的なフェーズが存在する可能性があります。
次の図は、移行先の環境で実行されているマイクロサービスと移行元の環境で実行されているマイクロサービスの間で、トラフィックを分割する方法を示しています。
また、環境間でのリクエストを禁止するようにルーティング ルールを調整して、移行元または移行先の環境にクライアントによるリクエストが発生したときに、その環境に留まるようにすることをおすすめします。
移行先の環境にトラフィックをルーティングするルールを設定する
このフェーズでは、移行先の環境で実行されているサービスにのみトラフィックをルーティングするようにルーティング ルールを更新します。
次の図は、トラフィックが移行先の環境にのみルーティングされ、移行元の環境をバックアップとして保持する方法を示しています。
移行元の環境を廃止する
このフェーズでは、移行元の環境を廃止します。
移行元の環境を廃止する前に、次のことを確認してください。
- 移行元の環境で実行されているマイクロサービスのインスタンスにトラフィックがルーティングされていない。
- 移行元の環境のインターフェースからトラフィックが送信されていない。
- 移行先の環境が完全に検証されている。
これらの条件が満たされたら、移行先の環境のプロビジョニング フェーズで設定したロードバランサを指すように DNS レコードを更新できます。
次の図は、以前の環境が廃止されたために、移行先の環境のみを示しています。
次のステップ
- Google Kubernetes Engine について読む。
- Istio について読む。
- 関連チュートリアルを読む。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud Architecture Center をご覧ください。