アプリケーション開発

クラウドネイティブ アーキテクチャ、5 つの原則

image0806.png

※この投稿は米国時間 2019 年 6 月 20 日に Google Cloud blog に投稿されたものの抄訳です。


私たち Google Cloud は、Google Cloud Platform(GCP)上に移行もしくは構築されるアプリケーションの最終目標として、よく「クラウドネイティブ アーキテクチャ」という言葉を使います。では、クラウドネイティブとは正確にはどういう意味なのでしょうか。そして、そのようなシステムはどうすれば設計できるのでしょうか。


大まかに言えば、クラウドネイティブとは、クラウドによってもたらされる、従来のオンプレミスにはない新しい可能性に適応することを意味します(アーキテクチャ上の制約も従来とは大きく異なるため、それにも適応)。ソフトウェア アーキテクトとして私たちが考慮するよう訓練を受けている高レベルの要素について考えてみましょう。


  • システムの機能要素(何をすべきか。たとえば、「この形式で注文データを処理」)

  • システムの非機能要素(どのように動作すべきか。たとえば、「1 分間に少なくとも 200 件の注文を処理」)

  • 制約(何を変更してはならないか。たとえば、「注文は既存のメインフレーム システム上で更新しなければならない」)


機能的な側面では大した変化はありませんが、クラウドは非機能要件を満たすための方法として従来と大きく異なるものを提供することがあり、それを使用するのが必須になることもあります。また、アーキテクチャ上の制約も従来とは大きく異なります。アーキテクトがそれらの制約に合わせてアプローチを修正できなければ、構築されたシステムは脆弱で高コストになり、保守管理が難しくなります。一方、適切なアーキテクチャのクラウドネイティブ システムでは、障害の多くを自己修復し、コスト効果が高く、継続的インテグレーション / 継続的デリバリ(CI/CD)によって容易に更新やメンテナンスを行えます。


ありがたいのは、クラウドが従来のインフラストラクチャと同じサーバー、ディスク、ネットワークなどのファブリックから構成されていることです。そのため、優れたアーキテクチャ設計のほとんどすべての原則が、クラウドネイティブ アーキテクチャにも当てはまります。ただし、クラウドではこれらのファブリックに関する基本前提の一部が変わります。たとえば、従来の環境では代替サーバーのプロビジョニングには数週間かかりますが、クラウドでは数秒でプロビジョニングできます。したがって、アプリケーションのアーキテクチャはそれを考慮に入れたものでなければなりません。


この投稿記事では、古いアプローチに新しいプラットフォームを無理やり当てはめるといった落とし穴を避けながら、クラウドをフルに活用できるクラウドネイティブ アーキテクチャの 5 原則について説明します。


クラウドネイティブ アーキテクチャの原則

以下で説明するクラウドネイティブ アーキテクチャの原則は、クラウド独特の特徴に合わせてシステム アーキテクチャをどう最適化すべきかとの問いに答えるものです。従来のアーキテクチャは固定的で高コストなため、変更にかなりの手作業が必要になるインフラストラクチャに合わせて最適化されており、比較的少数に固定化されたコンポーネントの回復力と性能に重点を置いたものになっています。これに対してクラウドの場合は、使用量に基づいて課金され(フットプリントを縮小すればコストを節約できます)、自動化もはるかに簡単なので(自動スケールアップ / スケールダウンはずっと簡単です)、従来のような固定的なインフラストラクチャは無意味です。そのため、クラウドネイティブ アーキテクチャでは、水平スケーリング、分散処理、故障したコンポーネントの自動交換を通じた回復力とスケーラビリティを実現することに重点を置いています。


原則 1 : 設計に自動化を組み込む

ソフトウェア システムにとって自動化は常にベスト プラクティスの 1 つであり、クラウドに取り入れると、コンポーネントだけでなくその下のインフラストラクチャの自動化まで容易になります。初期投資額が高くなるとしても、自動化されたソリューションを目指したほうが、中期的には労力面はもちろん、システムの回復力や性能面などほとんどの場合で有利です。自動化されたプロセスは、人間よりもはるかに速くシステムの修復やスケーリング、デプロイをこなしてくれます。後述しますが、クラウドのアーキテクチャ設計は単発で終わる仕事ではなく、自動化もその例外ではありません。システムが対処しなければならない新しい場面が見つかったら、自動化すべき新しい対象も見つかったということです。


クラウドネイティブ システムで自動化される対象としては、一般に次のものがあります。


  • スケーリング : システムの負荷がほとんど変わらないのでないかぎり、負荷の増大や継続的な低下に伴うシステムのスケーリングは自動化すべきです。スケールアップはシステムの可用性を維持し、スケールダウンはコスト削減を可能にします。公開ウェブ サイトなどの大規模なアプリケーションはもちろん、小規模でも不規則に負荷のかかるアプリケーション(たとえば、特定の時期には非常に混雑するものの、それ以外の時期にはほとんど使われない社内アプリケーション)でも、スケーリングには大きな意味があります。ときどきトラフィックがほとんどなくなり、起動時のレイテンシが無視できるアプリケーションでは、ゼロへのスケーリング(実行中のすべてのインスタンスを削除し、次に必要になったときにアプリケーションを再起動すること)も検討すべきです。

  • モニタリングと自動修復 : クラウドネイティブ システムには最初からモニタリングとロギングを組み込むべきです。データ ストリームのロギングとモニタリングは、当然ながらシステムの健全性を監視するうえで役に立ちますが、それ以外にも用途があります。たとえば、システムの利用状況やユーザーの行動に関する価値のある知見(システムの利用者は何人か、システムのどの部分が使われているか、平均レイテンシはどれほどか、など)が得られます。第 2 に、それらを集計すれば、システム全体における健全性の尺度が得られます(いつもより早くディスクを使い切りそうになっているかどうか、ディスクの利用状況とシステムのデータ取り込みの関係など)。そして、それらは新たな自動化の対象として最適です。ディスクが一杯になったときには、単にエラーをログに書き込むだけでなく、ディスク サイズを自動的に増やしてシステムが機能し続けられるようにするべきでしょう。


原則 2 : 状態をスマートに処理する

ユーザー データ(たとえば、ショッピング カート内の商品や従業員数)であれ、システムの状態情報(たとえば、実行中のジョブ インスタンス数、本番環境で実行されているコードのバージョン)であれ、「状態」の保存は分散型のクラウドネイティブ アーキテクチャを設計するうえで最も難しい部分です。いつ、どのように状態を格納するかを十分意識するとともに、可能なかぎりコンポーネントをステートレスにするようにシステムを設計すべきです。


ステートレスなコンポーネントは次のような点で有利です。


  • スケーリング : インスタンスを増やせばスケールアップでき、現在のタスクが完了したら終了するよう指示すればスケールダウンできます。

  • 修復 : 障害を起こしたインスタンスは、できるかぎり穏便に終了して新しいものを再起動すれば「修復」できます。

  • ロールバック : 問題のあるバージョンをデプロイしたときには、ステートレスなコンポーネントのほうが容易にロールバックできます。単に新しいバージョンを終了し、旧バージョンのインスタンスを起動するだけで済みます。

  • ロード バランシング : コンポーネントがステートレスなら、どのインスタンスでもリクエストを処理できるため、ロード バランシングは大幅に簡素化されます。通常、ステートフル コンポーネントのロード バランシングではユーザーのセッション状態がそのインスタンスと結びついており、そのユーザーのリクエストはすべてそのインスタンスで処理せざるをえなくなるため、とても難しくなります。


原則 3 : マネージド サービスを選ぶ

クラウドは単なるインフラストラクチャ以上のものです。ほとんどのクラウド プロバイダーは、バックエンドやインフラストラクチャの管理という頭の痛い仕事から開発者を解放してくれるマネージド サービスを数多く提供しています。しかし、多くの企業はプロバイダーに「ロックイン」されることを恐れて、そうしたマネージド サービスを利用することに慎重になっています。確かにそれはもっともなことですが、多くの場合、マネージド サービスは時間を大幅に節約し、運用上のさまざまなオーバーヘッドを取り除いてくれます。


大まかに言って、マネージド サービスを採用するかどうかは、コストだけでなくスキルの観点からも見て、ポータビリティと、運用上のオーバーヘッドのどちらをとるかという問題です。最新のマネージド サービスは大きく次の 3 種類に分類できます。


  • オープンソース、またはオープンソース互換のマネージド サービス : マネージド オープンソース サービス(たとえば Cloud SQL)や、オープンソース互換のインターフェースを提供するマネージド サービス(たとえば Cloud Bigtable)のことです。こうしたマネージド サービスには多くの利点があり、リスクはほとんどないので、積極的に使用することをお勧めします。

  • 運用上のメリットが大きいマネージド サービス : オープンソースと直接的な互換性がないか、代用できるオープンソース システムが存在しないものの、運用上のメリットが大きいマネージド サービスにはリスクに見合う価値があります。たとえば、BigQuery運用が非常に簡単なので、多くの企業が採用しています。

  • それ以外のすべて : 別のサービスへの乗り換えが容易でなく、運用上のメリットがとりわけ大きくもないこの種のマネージド サービスは面倒です。サービスの戦略的な重要性、自前で運用するときのオーバーヘッド、乗り換える際に必要な労力などを考慮しながらケースバイケースで判断する必要があります。


とはいえ、今までの実践的な経験から言えば、ほとんどのクラウドネイティブ アーキテクチャはマネージド サービスを選んでいます。サービスの管理をクラウド プロバイダーに任せることによる時間や労力の節約、そして運用上のリスク軽減よりも、乗り換えが必要になったときのリスクが重視されることは滅多にありません。


原則 4 : 多層防御を実践する

従来のアーキテクチャは境界セキュリティを特に重視し、ネットワーク境界を強化すれば外部の「信頼できないもの」から内部の「信頼されたもの」を守れると考えていました。しかし、このアプローチでは、内部からの攻撃だけではなく、スピア フィッシングのような外部からの攻撃に対しても脆弱です。しかも、柔軟性の高いモバイル ワーキングを求める圧力が高まるにつれて、境界セキュリティの意味はさらに失われてきています。


クラウドネイティブ アーキテクチャはインターネット接続されたサービスを起源としており、常に外部からの攻撃に対処する必要があります。そのため、各コンポーネントの間で認証を要求する多層防御のアプローチを採用し、コンポーネント間での信頼を最小限に抑えるようになっています(「内部」のものであってもそうです)。結果として、「内部」と「外部」の区別はありません


クラウドネイティブ アーキテクチャでは、この考え方を拡張して、認証だけでなくレート リミット制御やスクリプト インジェクションなども含めていくべきです。設計に含まれる個々のコンポーネントは、ほかのコンポーネントから自分を守れるようにしなければなりません。そうすれば、アーキテクチャの回復力が高まるだけでなく、サービスと利用者の間に信頼できるネットワークがないクラウド環境の場合でも、デプロイが簡単なサービスを開発できます。


原則 5 : アーキテクチャを常に考える

クラウドネイティブ システムの重要な特徴の 1 つは常に発展していることであり、アーキテクチャもその例外ではありません。クラウドネイティブ システムを設計するアーキテクトは、組織のニーズが変わり、IT システムの環境が変わり、クラウド プロバイダー自体の能力が変わるのに応じてシステムのアーキテクチャを洗練させ、単純化し、改良していくことを絶えず追求する必要があります。そのためには継続的な投資が必要なことは言うまでもありませんが、過去の教訓からも学べます。つまり、進化、成長、対応のためには IT システムが存続し、息を吹き込み、変化する必要があるということです。IT システムが崩壊し、硬直化すると、組織は急速に行き詰まり、新たな脅威やチャンスに対応できなくなります。


変わらないのは「常に変化がある」ということ

動物の世界で生き残るのは環境に適応した個体です。これは、「最悪」から「最高」、「原始的なもの」から「進化したもの」への直線的な発展ではなく、すべては常に流動的です。環境が変われば、種には進化や適応の圧力がかかります。同様に、クラウドネイティブ アーキテクチャも従来のアーキテクチャを駆逐するのではなく、クラウドという従来とは大きく異なる環境に適応しているだけです。クラウドは、私たちの大半が仕事をする場になりつつあり、生物の多くの種が証明してきたように、進化や適応に失敗すれば先は長くありません。


上で述べてきたことは、クラウドネイティブ アーキテクチャを作成できる魔法の方程式ではなく、クラウドを最大限に活用する方法を生み出すための強力なガイドラインだと考えてください。クラウドに合うようにアーキテクチャを進化、適応させれば、他の方法で進化、適応させたり、次の環境変化への適応性を高めたりすることもできます。変化は大変かもしれませんが、過去数十億年にわたる生物の進化が示してきたように、最高のものにならなくても生き残ることは可能です。適応できさえすればよいのです。


本稿で取り上げたテーマについてもっと深く学びたい方は、以下のリソースを参考にしてください。


  • ほとんどすべてのクラウド アーキテクチャはマイクロサービス アーキテクチャに基づいています。マイクロサービスの概要や、既存アプリケーションをマイクロサービスに移行させるための実践的なアドバイスについては、『Migrating a monolithic application to microservices on Google Kubernetes Engine』(モノリシック アプリケーションを Google Kubernetes Engine のマイクロサービスに移行する)をご覧ください。

  • どんな組織でも変化は困難を伴います。Google re:work サイトの『Changing the change rules at Google』(Google における変更ルールの変更)は、Google が変化や変更にどのようにアプローチしているかを示す興味深い内容になっています。


- By Tom Grey、Head of Cloud Solutions Architecture, EMEA