KubernetesでのOCIキュー・コンシューマのスケーリングについて

このプレイブックでは、Oracle Cloud Infrastructure (OCI)キューの機能の使用方法を示し、クライアントの需要量に基づいて、バック・プレッシャやパフォーマンスのボトルネックの問題を発生させることなく、動的スケーリングを必要とするユースケースの大部分に適合するレシピを提供します。

マイクロサービスをOracle Kubernetes Engine (OKE)にデプロイして、OCIキューからのメッセージを処理し、キューの深さを利用して、OKEクラスタで実行されているマイクロサービス・インスタンスを水平方向にスケーリングできます。この例には、ローカル・マシンや別のコンテナまたはVMの一部として、任意の場所から実行できるメッセージ・ジェネレータが含まれています。

このプレイブックには、Oracle-DevRel GitHubリポジトリoci-arch-queue-oke-demo (このプレイブックの「詳細を確認」セクションからアクセスできる)にあるコードおよび詳細な設定手順も記載されています。このソリューションは、すべてのJavaコード、スクリプトおよび構成ファイル、およびビルディング・ブロックの構築、デプロイおよび実行の詳細なステップを提供します。このドキュメントでは、アーキテクチャ・ビューを提供し、ソリューションを独自のニーズに適応させるために変更する必要があるコード部分を識別するなど、実装の主な要素を確認します。

OCIキューAPIについて学習

ソリューションは、単一プロセスにほとんど対応しません。多くの場合、アプリケーション間の通信は、ソリューションの最も制限のある部分(CPU、待機時間などが必要)によってソリューションが制限されないように非同期である必要があります。これらの問題は、プロデューサとコンシューマが相互に依存しない通信を確立することで解決できます。これは、OCIキューが非常に高いパフォーマンスでサポートされるものです。

Queueは需要変動からアプリケーションをクッションできますが、ユーザーが関与している場合は、メッセージ作成とメッセージ処理の間に多くの時間をかけたくありません。したがって、バックエンドは需要に基づいて動的にスケーリングできる必要があります。この要求は、キュー内に存在するメッセージの数によって決まります。メッセージ数が多いほど、需要が増えるため、必要な計算作業が増えます。反対に、空のキューは需要がないことを表しているため、必要なバックエンド・リソースは最小限です。動的スケーリングは、これらの定数変化に対応します。

アーキテクチャ

このアーキテクチャはフルマネージド・サービスであるため、可視フォルト・ドメインの外部に存在するメッセージのキューが必要です。

OCIでは、クライアント管理ノードまたはOracle管理ノードを使用してKubernetesを実行できます。このシナリオでは、クライアント・ノードの古いアプローチを使用するため、クラスタにアタッチされたコンピュート・ノードが必要です。これらのノードは、可用性ゾーン内のフォルト・ドメイン全体に最も分散しています。

ノート:

このプレイブックでは、需要の生成はローカル・マシンから行われるため、OCI環境外です。

最後の2つの主要要素はスケーリングを制御します。まず、OCIファンクションが定期的に起動され、キューの深さの詳細が取得されます。キューの深さを確認する方法を抽象化するために、APIゲートウェイが使用され、これによりOCIファンクションの呼出しが容易になります。

最後に、キューへのアクセス、一般的なヘルス監視の監視などの資格証明を格納するために、Vaultなどの補助的なサービスが必要です。


queue-scaling-oke-arch.pngの説明が続きます
図queue-scaling-oke-arch.pngの説明

queue-scaling-oke-arch-oracle.zip

前述の図の番号は、このイベント順序を表しています。
  1. ローカルでホストされるプロデューサは、メッセージをOCIキューに入れます。
  2. OCIコンシューマ・インスタンスは、キューからメッセージを取得します。コード内で、消費レートは遅延を使用して制約されます。これにより、プロバイダは、1つのコンシューマがキューから削除できる数を超えるメッセージを生成できます。その結果、スケーリング・メカニズムが機能します。
  3. Kubernetesスケジュール済ジョブは定期的にKEDAをサポートして、公開済APIを呼び出してキュー上のメッセージ数を取得します。
  4. APIゲートウェイは、リクエストをOCIファンクションのインスタンスに送信します。
  5. OCIファンクションは、OCIキューを問い合せます。
  6. レスポンスが返されるため、KEDAはマイクロサービスのインスタンスの増減をトリガーします。
さらに(a)この実装では、ユーザーはいつでもキューの深さの状態を問い合わせることができます。
このアーキテクチャには、次のコンポーネントが含まれています。
  • リージョン

    OCIリージョンは、可用性ドメインと呼ばれる1つ以上のデータ・センターを含むローカライズされた地理的領域です。リージョンは他のリージョンから独立しており、広大な距離で(複数の国または複数の大陸にまたがる)リージョンを分離できます。

  • 可用性ドメイン

    アベイラビリティ・ドメインは、リージョン内の独立したスタンドアロン・データ・センターです。各可用性ドメイン内の物理リソースは、他の可用性ドメイン内のリソースから分離されるため、耐障害性が提供されます。可用性ドメインは、電源、冷却、内部可用性ドメイン・ネットワークなどのインフラストラクチャ・サービスを共有しません。そのため、ある可用性ドメインでの障害がリージョン内の他の可用性ドメインに影響することはほとんどありません。

  • フォルト・ドメイン

    フォルト・ドメインは、可用性ドメイン内のハードウェアおよびインフラストラクチャのグループです。各アベイラビリティ・ドメインに3つのフォルト・ドメインがあり、それぞれ独立した電源とハードウェアがあります。複数のフォルト・ドメインにリソースを分散すると、アプリケーションは、フォルト・ドメイン内の物理サーバー障害、システム・メンテナンスおよび電源障害を許容できます。

  • コンパートメント

    コンパートメントは、OCIテナンシ内のリージョン間論理パーティションです。コンパートメントを使用して、Oracle Cloudでリソースを編成、リソースへのアクセスを制御および使用割当てを設定します。各コンパートメント内のリソースへのアクセスを制御するには、誰がリソースにアクセスできるか、どのアクションを実行できるポリシーを定義します。

  • 仮想クラウド・ネットワーク(VCN)およびサブネット

    VCNは、OCIリージョンで設定する、カスタマイズ可能なソフトウェア定義ネットワークです。従来のデータ・センター・ネットワークと同様に、VCNによってネットワーク環境を完全に制御できます。VCNには、VCNの作成後に変更できる、重複しない複数のCIDRブロックを含めることができます。VCNをサブネットにセグメント化して、そのスコープをリージョンや可用性ドメインに設定できます。各サブネットは、VCN内の他のサブネットと重複しない連続した範囲のアドレスで構成されます。サブネットのサイズは、作成後に変更できます。サブネットはパブリックにもプライベートにもできます。

  • コンピュート・インスタンス

    OCI Computeでは、コンピュート・ホストをプロビジョニングおよび管理できます。リソース要件(CPU、メモリー、ネットワーク帯域幅およびストレージ)を満たすシェイプのコンピュート・インスタンスを起動できます。コンピュート・インスタンスを作成した後は、セキュアにアクセスし、再起動、ボリュームのアタッチおよびデタッチを行い、不要になったら終了できます。

  • 関数

    Oracle Functionsは、完全に管理されたマルチテナントのスケーラビリティの高いオンデマンドFunctions-as-a-Service (FaaS)プラットフォームです。Fn Projectのオープンソース・エンジンを搭載しています。ファンクションを使用すると、コードをデプロイし、それを直接コールするか、イベントに応答してトリガーできます。Oracle Functionsは、OCIレジストリでホストされているDockerコンテナを使用します。

  • コンテナ・レジストリ

    OCIレジストリは、開発から本番のワークフローを簡略化できるOracle管理レジストリです。Registryを使用すると、Dockerイメージなどの開発アーティファクトを簡単に格納、共有および管理できます。OCIの可用性と拡張性の高いアーキテクチャにより、アプリケーションを確実に導入および管理できます。

  • Container Engine for Kubernetes

    OCI Container Engine for Kubernetesは、コンテナ化されたアプリケーションをクラウドにデプロイするために使用できる、完全に管理されたスケーラブルで可用性の高いサービスです。アプリケーションに必要なコンピュート・リソースを指定すると、Container Engine for Kubernetesによって既存のテナンシのOCIにプロビジョニングされます。Container Engine for Kubernetesは、Kubernetesを使用して、ホスト・クラスタ間のコンテナ化されたアプリケーションのデプロイメント、スケーリングおよび管理を自動化します。

  • APIゲートウェイ

    Oracle API Gatewayでは、エンドポイントを含むAPIを公開して、ファンクション、マイクロサービス、その他のアプリケーション・インタフェースなどの機能の可視性を管理できます。エンドポイントは、バックエンド・ソリューションのきめ細かなセキュリティ制御を提供し、APIの実装方法を抽象化します。

  • キュー

    キューは、サーバーレスのスケーラビリティの高い非同期通信メカニズムです。サービスとメッセージ配信の分離を有効にするのに最適です。

注意事項

マイクロサービスをKubernetesにデプロイしてOCIキューからのメッセージを処理する場合は、次の点を考慮する必要があります。

  • キューのポリシーに関する考慮事項

    OCIキューを制御および構成するためのポリシーと、メッセージを作成および使用するためのポリシーは分離されています。これにより、APIを介して使用可能な操作を詳細に制御できます。つまり、アプリケーションの要件とセキュリティ・ニーズを少し考慮する必要があります。本番環境では、厳密な制御が推奨されます。この実装では、構成エラーによってデモが動作しない可能性を最小限に抑える緩和された構成設定を使用します。

  • Kubernetesのスケーリング制限に関する考慮事項

    バックエンド・スケーリングのレートと制限を検討する必要があります。マイクロサービスの追加インスタンスが起動する前にキューの深さなどの要因に対処する必要があります。マイクロサービスの最大追加インスタンス数が実行されている必要があります。実際的な意味では、これをバインドしないことは避けたいが、誰かが(意図的または偶発的に)間違ったメッセージでキューをフラッディングし始めると、逃げるために必要な追加の計算能力のコストを吸収したくない。また、マイクロサービスの追加のインスタンスをどれだけ迅速にスピンダウンするかを検討する必要があります。短時間でスピンダウンすると、環境が常にサービスの開始および停止になります。マイクロサービスの効率に関係なく、サービス・インスタンスの起動および停止にかかるオーバーヘッド・コストが常に発生し、最終的にはコストがかかります。

  • スケーリング制御に関する考慮事項

    スケーリングを制御する最後の側面は、スケーリングを適用するかどうか、およびスケーリングを制御する方法です。このシナリオでは、KEDA (Kubernetes Event Driven Autoscaler)と呼ばれるCNCFプロジェクトを利用します。バックエンド・スケーリングの実行方法に加えて、APIの起動方法を検討する必要があります。この場合、Kubernetesスケジュール済ジョブを(図にこのフローを反映するワーカー・ノードによってジョブが実行されるため)構成してAPIを呼び出すことができます。

前提条件

これを開始する前に、ここで説明する前提条件に対処して環境を準備する必要があります。

  • メッセージ生成には、Java 8以降が必要です(Java 8はApache Mavenとともにインストールされます)。
  • OCIキューとの対話には、アクセスを許可するためにユーザーおよび関連する資格証明が必要です。次のポリシーを設定します:
    • 使用するコンパートメント(compartment-name)を識別するには、このポリシーを設定します:
      allow any-user to manage queues in compartment compartment-name 
    • OCIキューに対する読取りまたは書込みのみにユーザーを制限するには、MessageConsumersおよびMessageProducersというOCIグループを作成し、適切なユーザーをこれらのグループに割り当てます。次のポリシーを使用します。
      allow group MessageConsumers to use queues in compartment compartment-name 
      allow group MessageProducers to use queues in compartment compartment-name
    • OCIで認証してAPIを使用できるように、プロデューサ・クライアントに標準のOCI構成属性を指定します。
    • 新しいリソースが実行され、キューにアクセスする必要があるため、動的動作をサポートするポリシーを設定する必要があります。これらのポリシーを設定するには、柔軟に制御する必要があるリソースを含む動的グループを作成します。この制御はOCI内で行われるため、インスタンス・プリンシパルを使用します。このグループqueue_dgをコールします。次のポリシー文を使用します。
      ALL {instance.compartment.id='instance Compartment id (OCID)'} 
      allow dynamic-group queue_dg to use queues in compartment queue_parent_compartment 
      ここで、instance Compartment id (OCID)はワーカー・ノードを含むコンパートメントです。

Java SDKについて学習

3つのコード(プロデューサ、コンシューマおよびファンクション)はすべてOCI APIを使用します。APIを操作する最も簡単な方法は、Java SDKを使用することです。OCIによって提供されるSDKは、OCIサービスの呼出しを認証および認可するために必要な情報を取得する一連の説得機能を提供します。SDKは、Joshua Blochのビルダー・パターンのバリアントを採用しています。SDKの詳細は、Java SDKを参照してください。Oracle DevRel GitHubリポジトリには、https://github.com/oracle-devrel/oci-arch-queue-demoなど、ここで使用されるSDKのその他の例があります。