OCI上のマルチテナント・アプリケーション・デプロイメント・モデル
テナンシについて
OCIテナンシとSaaSアプリケーションのテナントの概念を混同しないことが重要です。
OCIテナンシ: これは、OCIサービスにサインアップしたときに受け取るアカウントです。ルート・アカウントを表し、OCIリソースを編成および管理するセキュアで分離されたパーティションとして機能します。
テナント(SaaSコンテキスト内): ISVがOCI上にSaaSプラットフォームを構築するとします。ISVが独自の顧客をプラットフォームにプロビジョニングすると、それらの顧客それぞれがテナントとみなされます。この意味でのテナントは顧客組織を表し、各テナントには複数のユーザーを関連付けることができます。
つまり、OCIテナンシはOCIアカウント自体を指し、テナントはISVなど、別のエンティティによってOCIでホストされるアプリケーションを使用する組織(SaaS顧客など)を指します。
アーキテクチャ
このアーキテクチャは、OCI上のマルチテナント・アプリケーション・デプロイメント・モデルを概要レベルで表します。
次の図は、このリファレンス・アーキテクチャを示しています。
マルチテナント- アプリケーション- 会社-oracle.zip
この柔軟なアーキテクチャは、次の3つのレイヤーで構成されています。
| レイヤー | 目 的 | キー・アクション |
|---|---|---|
| 初期認証(OCI IAM) | グローバルIDの確認 | 資格証明の検証後にJSON Webトークン(JWT)を発行します |
| 認証ミドルウェア | リクエストごとのIDの確認 | JWTからのテナントおよびユーザー・コンテキストの抽出 |
| データ・アクセス・レイヤーまたはORMフック | データ分離の実施 | すべての問合せをtenant_idで自動的にフィルタします。 |
各レイヤーについて次に説明します。
初期認証およびテナント・コンテキスト確立
- 認証サービス:ユーザーは、通常、テナント固有のURL (mycompany.app.comなど)を使用するか、ログイン時にテナントを選択してログインします。
- アイデンティティ・プロバイダとしてのOCI Identity and Access Management (OCI IAM): OCI IAM (具体的には、専用アイデンティティ・ドメイン)は、ユーザーの資格証明を検証します。重要なことに、ユーザーが有効であるだけでなく、アクセスしようとしている特定のテナント・グループ(たとえば、mycompany-users)のメンバーでもあることを確認します。
- JWT発行:認証に成功すると、OCI IAMアイデンティティ・ドメインは署名付きJSON Webトークン(JWT)を発行します。このトークンには、次の重要な要求が含まれています。
- sub: ユーザーの一意の識別子。
- グループ: ユーザーが属するIAMグループのOCIDsの配列。これは、テナントを識別するためのキーです。
tenant_idやtenant_nameなどのカスタム・クレームは、OCI IAMのカスタム属性を使用して追加できます。(オプション)
認証ミドルウェア – 「誰」レイヤー
バックエンドは、テナント・コンテキストを安全に抽出および伝播するように設計する必要があります。このアーキテクチャでは、OCI APIゲートウェイまたはOCIロード・バランサを使用して、リクエストごとの認証およびテナント・コンテキストの伝播を実行できます。
- OCI APIゲートウェイ:これは推奨されるエントリ・ポイントです。JWT検証自体を実行して、この職責をアプリケーション・コードからオフロードできます。OCI IAMアイデンティティ・ドメインのJWKSエンドポイントに対して署名を検証するように構成します。
- OCIロード・バランサ: SSLの終了およびルーティングを処理できますが、検証のためにJWTを認証ミドルウェアに渡します。
処置: OCI APIゲートウェイは、JWTの署名および有効期限を検証します。無効の場合、リクエストは即時に拒否されます。有効な場合、リクエストはアップストリーム・サービスに転送され、多くの場合、検証されたトークンまたは抽出されたクレームがヘッダー(X-USER-ID、X-TENANT-IDなど)に渡されます。
OCI APIゲートウェイのかわりにOCIロード・バランサを使用している場合、アプリケーション・バックエンドの最初のコンポーネントは認証ミドルウェアである必要があります。
処置: Authorization: Bearer <token>ヘッダーからJWTを抽出し、OCI IAMの公開キーを使用してその署名を検証し、要求をデコードして、user_idおよびtenant_id (グループ要求から導出)を、後続のすべてのレイヤーで使用するリクエスト・コンテキストに注入します。
データ・アクセス・レイヤーまたはオブジェクト・リレーショナル・マッパー(ORM)のフック – 「What」レイヤー
このレイヤーは、すべてのSQL問合せにテナントIDを自動的に注入します。
- 例:
getAllInvoices()へのコールは、SELECT * FROM invoices WHERE tenant_id = :tenant_idに変換されます。 - 強制:これは、ヒューマン・エラーを回避するために、一元化されたデータ・アクセス・レイヤー、ORM (Hibernateなど)フックまたはテナント対応接続プールによって適用するのが最適です。
- ORMフック:アプリケーション・フレームワーク・レベルでデータベース操作をインターセプトおよび変更することによって、真の暗黙的なテナント分離を可能にするメカニズム。
テナント・データの分離戦略:
このアーキテクチャでは、テナントのデータを分離および保護するための2つのオプションがサポートされています:
オプション1: アプリケーション・レベル
ORMフック/スコープ: Hibernate (Java)、Django ORM (Python)、Eloquent (PHP)などのフレームワークでは、特定のモデルのすべての問合せにテナント・フィルタを自動的に追加するグローバル・スコープを定義できます。
または
オプション2: データベース・レベル
識別子列、テナントごとに個別のスキーマ、またはテナントごとに個別のデータベースを使用できます。
- 弁別子列(最も一般的な列):
tenant_id列は、すべてのテナント固有の表またはドキュメントに追加されます。アプリケーションのデータ・アクセス・レイヤー(DAL)またはORMは、すべての問合せに
WHERE tenant_id = ?句を自動的に追加します。これは、次の方法で実現されます。- リポジトリ・パターン:すべてのデータベース・アクセスは、集中クラスまたはクラスのセットを介して流れます。このリポジトリは、現在のリクエスト・コンテキストの
tenant_idに基づいて、すべてのSELECT、INSERT、UPDATEおよびDELETE操作にテナント・フィルタを自動的に追加します。 - 接続コンテキスト:一部のSQLデータベース(Oracle HeatWave MySQLなど)では、アプリケーションでセッション変数(
SET @tenant_id = 'mycompany123';など)を設定してから、ビューまたはストアド・プロシージャで使用できます。ただし、アプリケーション・レイヤーは、接続ごとにこの値を設定します。
- リポジトリ・パターン:すべてのデータベース・アクセスは、集中クラスまたはクラスのセットを介して流れます。このリポジトリは、現在のリクエスト・コンテキストの
- テナントごとのスキーマ:
各テナントには、同じデータベース・インスタンス内に専用のデータベース・スキーマがあります。
アプリケーション・ロジックは、テナントIDに基づいて、データベース接続の現在のスキーマを切り替える必要があります。
- テナントごとの接続プール:テナントごとに個別の接続プールを維持します。各接続は、テナントのスキーマ(
USE tenant_mycompany;など)を使用するように事前構成されています。 - 動的接続スイッチング:現在のtenant_idに基づいてチェックアウト時にスキーマを設定する接続プールを使用します(たとえば、PostgreSQLに
SET search_path TO tenant_mycompany;コマンドを使用します)。
- テナントごとの接続プール:テナントごとに個別の接続プールを維持します。各接続は、テナントのスキーマ(
- テナントごとのデータベース:
各テナントには、Bring Your Own Keys Encryption for Enterprisesで物理的に分離された独自のデータベース・インスタンスがあります。
アプリケーションでは、
tenant_idを正しいデータベース接続文字列にマップするために、テナント・データ参照サービスが必要です。- アプリケーションは、複数のデータベースへの接続プールを保持します。
- DALは、リクエスト・コンテキストのテナントIDを使用して、プールから正しい接続を取得し、専用テナント・データベースで問合せを実行します。
このオプションには長所と短所があります。
- Pros:最大の分離、セキュリティ、およびパフォーマンス。テナントは、異なるデータベース・バージョンまたはエンジン・タイプにすることもできます。
- Cons:最高の運用オーバーヘッド、コスト、および複雑さ。データベースの移行とパッチは、すべてのテナント・データベースで実行する必要があります。
このアーキテクチャは、次のコンポーネントを実装します。
- Tenancy
テナンシは、OCIへのサインアップ時にOracleがOracle Cloud内で設定する、セキュアで分離されたパーティションです。テナンシ内のOCI上でリソースを作成、編成および管理できます。テナンシは、会社または組織と同義です。通常、会社は単一のテナンシを持ち、そのテナンシの組織構造を反映させます。通常、単一のテナンシは単一のサブスクリプションに関連付けられ、単一のサブスクリプションには1つのテナンシのみが含まれます。
- OCI Identity and Access Management
Oracle Cloud Infrastructure Identity and Access Management (IAM)は、OCIおよびOracle Cloud Applicationsのユーザー・アクセス制御を提供します。IAM APIおよびユーザー・インタフェースを使用すると、アイデンティティ・ドメインとその中のリソースを管理できます。各OCI IAMアイデンティティ・ドメインは、スタンドアロンのアイデンティティおよびアクセス管理ソリューション、または別々のユーザー・移入を表します。
- ロード・バランサー
Oracle Cloud Infrastructure Load Balancerは、単一のエントリ・ポイントから複数のサーバーへの自動トラフィック分散を提供します。
- OCI APIゲートウェイ
Oracle Cloud Infrastructure API Gatewayでは、ネットワーク内からアクセス可能なプライベート・エンドポイントを含むAPIを公開でき、必要に応じてパブリック・インターネットに公開できます。エンドポイントは、API検証、リクエストとレスポンスの変換、CORS、認証と認可およびリクエスト制限をサポートします。
- Oracle Key Management Cloud Service
OCI Key Management Service Oracle Cloud Infrastructure (OCI) Key Management Service (KMS)はクラウドベースのサービスであり、OCIに格納されているデータの暗号化キーを一元管理および制御できます。OCI KMSは顧客管理の暗号化であり、OCI Vault (Virtual VaultとPrivate Vaultの両方)、OCI Dedicated KMSおよびOCI External KMSサービスを提供します。
- OCIコンピューティング
Oracle Cloud Infrastructure Computeを使用すると、クラウド内のコンピュート・ホストをプロビジョニングおよび管理できます。CPU、メモリー、ネットワーク帯域幅およびストレージのリソース要件を満たすシェイプを使用してコンピュート・インスタンスを起動できます。コンピュート・インスタンスを作成した後は、セキュアにアクセスし、再起動してボリュームをアタッチおよびデタッチし、不要になったときにそれを終了できます。
- OCI関数
Oracle Cloud Infrastructure Functionsは、完全に管理されたマルチテナントで、スケーラビリティに優れたオンデマンドのFunctions-as-a-Service (FaaS)プラットフォームです。これは、Fn Projectのオープン・ソース・エンジンによって機能します。OCI関数を使用すると、コードをデプロイし、直接コールするか、イベントに応答してトリガーすることができます。OCI Functionsは、Oracle Cloud Infrastructure RegistryでホストされているDockerコンテナを使用します。
- OCI Kubernetes Engine
Oracle Cloud Infrastructure Kubernetes Engine(OCI Kubernetes EngineまたはOKE)は、コンテナ化されたアプリケーションをクラウドに導入するために使用できるフルマネージドのスケーラブルな高可用性サービスです。アプリケーションに必要なコンピュート・リソースを指定し、OKEによって既存のテナンシのOCIにプロビジョニングされます。OKEは、Kubernetesを使用して、ホスト・クラスタ間のコンテナ化されたアプリケーションのデプロイメント、スケーリングおよび管理を自動化します。
- Oracle HeatWave MySQL
Oracle MySQL Database Serviceはフルマネージド・データベース・サービスであり、開発者は世界で最も人気のあるオープン・ソース・データベースを使用して、セキュアなクラウドネイティブ・アプリケーションを迅速に開発およびデプロイできます。Oracle HeatWave MySQLは、Oracle MySQL Database Serviceの統合された高パフォーマンスのインメモリー・クエリ・アクセラレータで、分析およびトランザクション問合せのMySQLパフォーマンスを高速化します。
- Oracle NoSQL Database Cloud Service
Oracle NoSQL Database Cloud Serviceを使用すると、開発者はドキュメント、固定スキーマおよびキーバリュー・データベース・モデルを使用してアプリケーションを簡単に構築でき、データ・レプリケーションで予測可能な1桁ミリ秒のレスポンス時間を高可用性を実現できます。このサービスは、オンデマンドおよびプロビジョニングされた容量モードの両方に対して、アクティブ/アクティブのリージョン・レプリケーション、ACIDトランザクション、サーバーレス・スケーリング、包括的なセキュリティ、および低従量制の価格を提供します。これには、オンプレミスのOracle NoSQL Databaseとの100%の互換性が含まれます。
- OCIオブジェクト・ストレージ
OCIオブジェクト・ストレージでは、データベースのバックアップ、分析データ、イメージおよびビデオなどのリッチ・コンテンツなど、あらゆるコンテンツ・タイプの構造化データおよび非構造化データの大量へのアクセスを提供します。アプリケーションから直接、またはクラウド・プラットフォーム内から、安全かつ安全にデータを格納できます。パフォーマンスやサービスの信頼性を低下させることなく、ストレージを拡張することができます。
迅速、即時、頻繁にアクセスする必要のあるホット・ストレージに標準ストレージを使用します。長期間保存し、ほとんどまたはめったにアクセスしないコールド・ストレージにアーカイブ・ストレージを使用します。
- Oracle Autonomous Database Serverless
Oracle Autonomous Database Serverlessは、Oracle Autonomous Databaseです。Oracleがデータベースの配置からバックアップおよび更新まで、データベース・ライフサイクルのすべての側面を自律的に操作する、完全に柔軟なデータベースがあります。
- Transparent Data Encryption
Transparent Data Encryption (TDE)は、Oracle AI Database内の保存データを透過的に暗号化します。TDEはOracle AI Databaseと完全に統合されており、データベース・バックアップ(RMAN)、Data Pumpエクスポート、アプリケーション表領域全体または特定の機密列を暗号化できます。暗号化データは、表領域ストレージ・ファイル、一時表領域、UNDO表領域、またはREDOログなどのその他のファイルのいずれであっても、データベース内で暗号化されたままです。これにより、アプリケーションがSQLを使用してデータにアクセスする方法に影響を与えることなく、データベース・データへの不正アクセスを防止できます。
レコメンデーション
- VCN
VCNを作成するときには、必要なCIDRブロックの数を決定し、VCN内のサブネットにアタッチする予定のリソースの数に基づいて各ブロックのサイズを決定します。標準のプライベートIPアドレス領域内にあるCIDRブロックを使用します。
プライベート接続を設定する他のネットワーク(Oracle Cloud Infrastructure、オンプレミス・データ・センターまたは別のクラウド・プロバイダ)と重複しないCIDRブロックを選択します。
VCNを作成した後、そのCIDRブロックを変更、追加および削除できます。
サブネットを設計するときには、トラフィック・フローおよびセキュリティ要件を考慮してください。特定の層またはロール内のすべてのリソースを同じサブネットにアタッチします。このサブネットはセキュリティ境界として機能します。
- セキュリティ・リスト
セキュリティ・リストを使用して、サブネット全体に適用されるイングレスおよびエグレス・ルールを定義します。
- ネットワーク・セキュリティ・グループ(NSG)
NSGを使用して、特定のVNICに適用されるイングレスおよびエグレス・ルールのセットを定義できます。NSGでは、VCNのサブネット・アーキテクチャとアプリケーションのセキュリティ要件を分離できるため、セキュリティ・リストではなくNSGを使用することをお薦めします。
- クラウド・ガード
Oracleが提供するデフォルト・レシピをクローニングおよびカスタマイズして、カスタム・ディテクタおよびレスポンダ・レシピを作成します。これらのレシピを使用すると、警告を生成するセキュリティ違反のタイプと、それらに対して実行できるアクションを指定できます。たとえば、可視性がパブリックに設定されているOCIオブジェクト・ストレージ・バケットを検出できます。
Oracle Cloud Guardをテナンシ・レベルで適用して、広範な範囲をカバーし、複数の構成を維持する管理上の負担を軽減します。
また、管理対象リスト機能を使用して、特定の構成をディテクタに適用することもできます。
- セキュリティ・ゾーン
最大限のセキュリティを必要とするリソースの場合、Oracleではセキュリティ・ゾーンを使用することをお薦めします。セキュリティ・ゾーンは、ベスト・プラクティスに基づくセキュリティ・ポリシーのOracle定義レシピに関連付けられたコンパートメントです。たとえば、セキュリティ・ゾーン内のリソースには、パブリック・インターネットからアクセスできない必要があり、顧客管理キーを使用して暗号化する必要があります。セキュリティ・ゾーンでリソースを作成および更新すると、OCIはレシピのポリシーに対して操作を検証し、いずれかのポリシーに違反する操作を防止します。
考慮事項
このアーキテクチャをデプロイする場合は、これらのオプションを検討してください。
- パフォーマンス:
- APIでのテナントベースのレート制限の設定
- OKEのネームスペース当たりのKubernetesリソース割当てを使用して、テナント当たりのポッド、CPUおよびメモリーを制限します
- 需要の高いテナントに専用ノード・プールを活用
- データベース接続でのテナントごとのプール・サイズの設定
- セキュリティ:
- OCI IAMグループは、ユーザーがアクセスできるテナントを制御します。これはJWTによって強制されます。
- Oracle Cloud Guardによる構成の誤り検出の有効化
- コスト:
表レベル、スキーマ・レベルまたはエンタープライズ・レベルの顧客専用のデータベースが必要かどうかに関係なく、ビジネス・ニーズに基づいて評価します。たとえば:
- 層1: 標準(弁別子列): テナントは同じ表/スキーマを共有します。
- Tier 2: Premium (テナントごとのスキーマ): テナントは、同じデータベース内で専用のスキーマを取得します。
- 層3: エンタープライズ(テナント当たりのデータベース): テナントは専用のデータベース・インスタンスを取得します。
- パッチ適用とアプリケーションの更新
単一インスタンスのマルチテナントのSaaSアーキテクチャでは、1つのテナントにすべてパッチを適用せずにパッチを適用することはできません。すべての顧客は、同じアプリケーション・コードベース、ランタイムおよびインフラストラクチャを共有します。この現実は、ユーザー・ベース全体に破壊的なダウンタイムを発生させずに、安全かつ効率的に更新をロールアウトする方法という大きな課題を生み出します。その答えは、この目的のために特別に設計された最新のDevOpsデプロイメント戦略にあります。ダウンタイムなしのデプロイメント戦略を使用して、ユーザーをオフラインにすることなく、バージョン間でシームレスに移行できます。
- ブルー/グリーン・デプロイメント:これには、2つの同一の本番環境(1つのブルー(現在のバージョンを実行)と1つのグリーン(新しいバージョンを実行)のメンテナンスが含まれます。Greenで新しいバージョンをデプロイおよびテストした後、すべてのトラフィックをBlueからGreenにシームレスに切り替えます。何か問題が発生した場合は、すぐにスイッチバックして、ロールバックを非イベントにします。古いブルー環境は廃止される。
- カナリア・デプロイメント:この戦略は、段階的なロールアウトを実行することでリスクを軽減します。新しいバージョンは、制御された小規模なユーザー(カナリア)のサブセットにデプロイされます。このグループでは、エラーやパフォーマンスの問題を注意深く監視します。メトリックが良好に見える場合は、すべてのユーザーが新しいバージョンになるまで、徐々に更新をより多くのユーザーにロールアウトします。
必須のアップグレード・ウィンドウをユーザーに通知します(たとえば、「アップグレード日が指定されていない場合、アップグレードは日曜日、mm/dd/yyyyで12:00に自動的に行われます)。ウィンドウの後、古いバージョンのセッションを終了し、すべてのトラフィックを新しいバージョンにリダイレクトします。その後、古いアプリケーション・コードが完全に停止します。
- データベースに関する考慮事項
アプリケーション・バージョンを切り替えた正確な時点では、データベース・スキーマを切り替えることはできません。ほとんどのSaaS企業は、次のものを使用してこれを回避しています。
- 下位互換データベース・スキーマの変更
- 機能フラグ/トグル
- テナント・メタデータ・ベースのバージョン管理
これにより、ロールアウト中に新しいコードが古いスキーマ・バージョンに対して安全に動作し、ダウンタイムなしの移行と即時ロールバックが可能になります。
