クラスタ マルチテナンシー

このページでは、Google Kubernetes Engine 上のクラスタ マルチテナンシーについて説明します。これには、単一の組織で複数の異なるユーザーによって共有されるクラスタ、および Software as a Service(SaaS)アプリケーションの顧客別インスタンスによって共有されるクラスタが含まれます。クラスタ マルチテナンシーは、多くの単一テナント クラスタを管理する代わりに使用できる手段です。

このページでは、マルチテナント クラスタの管理に使用できる Kubernetes と GKE の機能についても簡単に説明します。

マルチテナンシーとは

マルチテナント クラスタは、「テナント」と呼ばれる複数のユーザーやワークロードによって共有されます。マルチテナント クラスタのオペレーターは、不正使用されたテナントや悪意のあるテナントがクラスタや他のテナントに与える可能性のある被害を最小限に抑えるために、テナントを互いに分離する必要があります。また、クラスタ リソースはテナント間で公平に割り当てられている必要があります。

マルチテナント アーキテクチャを計画する際には、Kubernetes のリソース分離のレイヤ(クラスタ、名前空間、ノード、Pod、コンテナ)を考慮する必要があります。また、テナント間でさまざまなタイプのリソースを共有することによるセキュリティへの影響も考慮する必要があります。たとえば、同じノード上の異なるテナントから Pod をスケジュールすると、クラスタに必要なマシンの数を減らすことができます。一方、特定のワークロードが同じ場所に集中しないようにする必要がある場合もあります。たとえば、組織の外部で作成された信頼できないコードは、機密情報を処理するコンテナと同じノードで実行しないようにします。

Kubernetes はテナント間の分離の完全な安全性を保証するわけではありませんが、特定のユースケースには十分と考えられる機能を備えています。各テナントとその Kubernetes リソースをそれぞれ独自の名前空間に分離できます。その後ポリシーを使用してテナントを強制的に分離できます。ポリシーは、通常、名前空間でスコープを指定し、API アクセスやコンテナでの操作を制限したり、リソースの使用に制約を設けたりする目的で使用できます。

マルチテナント クラスタのテナントは、次のものを共有します。

マルチテナント クラスタの運用には、複数の単一テナント クラスタの運用と比較していくつかの利点があります。

  • 管理オーバーヘッドの削減
  • リソースの断片化を削減
  • 新しいテナント用のクラスタの作成に伴う時間が不要

マルチテナンシーのユースケース

このセクションでは、さまざまなマルチテナンシーのユースケースに合わせてクラスタを構成する方法について説明します。

エンタープライズ マルチテナンシー

エンタープライズ環境では、クラスタのテナントは組織内の別々のチームです。通常、各テナントにはそれぞれ対応する名前空間があります。クラスタ別のテナントまたは Google Cloud プロジェクト別のテナントで構成される代替マルチテナンシー モデルは、管理が困難です。名前空間内のネットワーク トラフィックは制限されません。名前空間でのネットワーク トラフィックは明示的にホワイトリストに登録する必要があります。これらのポリシーは、Kubernetes ネットワーク ポリシーを使用して適用できます。

クラスタのユーザーは、各自の権限に応じて次の 3 種類のロールに分けられます。

クラスタ管理者
このロールは、すべてのテナントの管理を担当するクラスタ全体の管理者用です。クラスタ管理者は、任意のポリシー オブジェクトの作成、読み取り、更新、削除を行うことができます。また、名前空間を作成し、名前空間管理者に割り当てることができます。
名前空間管理者
このロールは、特定の単一テナントの管理者用です。名前空間管理者は、自分が担当する名前空間のユーザーを管理できます。
デベロッパー
このロールのメンバーは、名前空間が指定された非ポリシー オブジェクト(PodジョブIngress など)の作成、読み取り、更新、削除が可能です。デベロッパーは、自分がアクセスできる名前空間でのみこれらの権限を持ちます。

企業組織用に複数のマルチテナント クラスタを設定する方法については、エンタープライズ マルチテナンシーのベスト プラクティスをご覧ください。

SaaS プロバイダ マルチテナンシー

SaaS プロバイダのクラスタのテナントは、アプリケーションの顧客別インスタンスおよび SaaS のコントロール プレーンです。名前空間でスコープを指定したポリシーを利用するには、SaaS のコントロール プレーンのコンポーネントと同様に、アプリケーション インスタンスを独自の名前空間別に編成する必要があります。エンドユーザーは、Kubernetes コントロール プレーンと直接対話することはできず、代わりに SaaS のインターフェースを使用して Kubernetes コントロール プレーンと対話します。

たとえば、ブログ プラットフォームはマルチテナント クラスタ上で実行できます。この場合、テナントは各顧客のブログ インスタンスとプラットフォーム独自のコントロール プレーンです。プラットフォームのコントロール プレーンとホストされている各ブログはすべて別々の名前空間で実行されます。顧客は、クラスタの動作状況を把握することなく、プラットフォームのインターフェースを介してブログの作成と削除、ブログ作成ソフトウェアのバージョンの更新を行うことができます。

マルチテナンシー ポリシーの適用

GKE と Kubernetes には、マルチテナント クラスタの管理に使用できるいくつかの機能が用意されています。次の各セクションでは、これらの機能の概要を説明します。

アクセス制御

GKE には、Cloud Identity and Access Management(Cloud IAM)とロールベースのアクセス制御(RBAC)の 2 つのアクセス制御システムがあります。Cloud IAM は、GCP リソースの認証と承認を管理するための Google Cloud のアクセス制御システムです。Cloud IAM を使用して、GKE リソースと Kubernetes リソースへのアクセス権をユーザーに付与します。Kubernetes に組み込まれている RBAC を使用すると、クラスタ内の特定のリソースや操作に対する詳細な権限を付与できます。

これらのオプションとそれぞれを使用する状況の詳細については、アクセス制御の概要をご覧ください。

これらのアクセス制御システムの使用方法については、RBAC 入門ガイドおよび Cloud IAM 入門ガイドをご覧ください。

ネットワーク ポリシー

クラスタのネットワーク ポリシーを使用すると、クラスタの Pod 間の通信を制御できます。ポリシーでは、Pod が通信可能な名前空間、ラベル、IP アドレス範囲を指定します。

GKE でネットワーク ポリシーを適用できるようにする手順については、ネットワーク ポリシーの入門をご覧ください。

ネットワーク ポリシーの記述方法については、ネットワーク ポリシーのチュートリアルに従ってください。

リソースの割り当て

リソースの割り当てでは、名前空間内のオブジェクトで使用されるリソースの量を管理します。割り当ては、CPU とメモリの使用量の観点で設定するか、オブジェクト数の観点で設定できます。リソースの割り当てを通じて、各テナントで使用されるクラスタ リソースがそれぞれの割り当て量を超えないようにできます。

詳細については、リソースの割り当てに関するドキュメントをご覧ください。

Pod のセキュリティ ポリシー

PodSecurityPolicies は、Pod の作成リクエストおよび更新リクエストを検証する Kubernetes API タイプです。PodSecurityPolicies では、Pod 仕様の中でセキュリティ上重要なフィールドのデフォルト値と要件を定義します。ホスト ファイルシステム、ネットワーク、PID 名前空間、ボリュームなどにアクセスする Pod のデプロイを制限するポリシーを作成できます。

詳細については、PodSecurityPolicies の入門をご覧ください。

Pod の反アフィニティ

Pod の反アフィニティを使用すると、異なるテナントの Pod が同じノードにスケジュールされないようにできます。反アフィニティの制約は、Pod のラベルに基づきます。たとえば、次の Pod 仕様では、"team": "billing" というラベルを適用した Pod を記述し、この Pod がラベルなしの近くの Pod にスケジュールされないようにするための反アフィニティ ルールを定義しています。

apiVersion: v1
kind: Pod
metadata:
  name: bar
  labels:
    team: "billing"
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - topologyKey: "kubernetes.io/hostname"
        labelSelector:
          matchExpressions:
          - key: "team"
            operator: NotIn
            values: ["billing"]

この手法の欠点は、悪意のあるユーザーが任意の Pod に team: billing ラベルを適用してルールを回避する可能性があることです。Pod の反アフィニティだけでは、信頼できないテナントが存在するクラスタに安全にポリシーを適用することはできません。

詳細については、Pod の反アフィニティに関するドキュメントをご覧ください。

taint と容認機能を使用した専用ノード

ノード taint は、ワークロードのスケジューリングを制御するもう 1 つの方法です。ノード taint を使用すると、特別なノードを特定のテナント専用として予約できます。たとえば、特定のテナントのワークロードで GPU が必要になる場合は、GPU 搭載ノードをそのテナント専用として扱うことができます。

ノードプールを特定のテナント専用にするには、effect: "NoSchedule" を指定した taint をノードプールに適用します。これにより、対応する容認機能を備えた Pod しかノードプールのノードにスケジュールできなくなります。

この手法の欠点は、悪意のあるユーザーが自分の Pod に容認機能を追加して専用ノードプールへのアクセスを取得する可能性があることです。ノード taint と容認機能だけでは、信頼できないテナントが存在するクラスタにポリシーを安全に適用することはできません。

ノード taint を使用してスケジューリングを制御する方法については、ノード taint の入門ページをご覧ください。

次のステップ