このトピックでは、悪意のあるテナントが他のテナントを攻撃しないように、共有クラスター内のテナントにリソースを公平に割り当てる方法について説明します。
背景情報
マルチテナントは、孤立性のレベルに基づいて、ソフトマルチテナントとハードマルチテナントに分類されます。
ソフトマルチテナントは、信頼できるテナントに適しています。 たとえば、ソフトマルチテナントは、企業の複数の部門間でKubernetesクラスターを分離できます。 このシナリオでは、マルチテナントの目的は、各部門のワークロードを保護し、潜在的な脅威を防ぐことです。
ハードマルチテナントは、信頼できないテナントに適しています。 例えば、サービスプロバイダは、異なる組織にインフラストラクチャリソースを提供する必要があり得る。 ハードマルチテナンシーは、テナントが他のテナントやKubernetesシステムにアクセスできないようにすることで、テナントの分離を強化します。
ソフトマルチテナント
名前空間
、ロール
、ロールバインディング
、およびネットワークポリシー
のKubernetes
ネイティブリソースを使用して、ソフトマルチテナントを実装できます。 これにより、テナント間の論理的分離が可能になります。 たとえば、ロールベースのアクセス制御 (RBAC)
を使用して、テナントが他のテナントのリソースにアクセスしたり操作したりしないようにすることができます。 クォータ
と制限範囲
を使用して、各テナントで消費できるクラスターリソースの量を管理できます。 ネットワークポリシー
を使用して、異なる名前空間にデプロイされたアプリケーションが相互に通信できないようにすることもできます。
ただし、これらの制御方法を使用して、異なるテナントのポッド
がノードを共有しないようにすることはできません。 node selectors
、anti-affinity
ルール、taints
、およびtolerations
を使用して、異なるテナントのポッドを個別のノードに強制的にスケジュールすることができます。 これらのノードは、唯一のテナントノードと呼ばれます。 単一のテナントノードの複雑さとコストは、クラスタが多数のテナントによって共有される場合に著しく増加する。
名前空間
を使用してソフトマルチテナントを実装する場合、名前空間のフィルタリングされたリストをテナントに提供することはできません。 これは、名前空間がグローバルにスコープされたリソースだからです。 テナントがクラスター内の特定の名前空間にアクセスできる場合、テナントはクラスター内のすべての名前空間にアクセスできます。
ソフトマルチテナントが使用されている場合、テナントはデフォルトでクラスターで実行されているすべてのサービスについてCoreDNS
をクエリできます。 攻撃者は、を実行してこの機能を悪用できます掘るSRV
. . svc.cluster.local
からポッド
クラスターで クラスターで実行されるサービスのDNSレコードへのアクセスを制限する場合は、CoreDNS
のファイアウォールまたはポリシープラグインを使用できます。 詳細については、「kubernetes-metadata-multi-tenancy-policy」をご参照ください。
エンタープライズ設定
ソフトマルチテナンシーモデルは、Kubernetesエンタープライズユーザーによって広く使用されています。 Kubernetesクラスターのすべてのテナントが同じ企業に属している場合、サービスユーザーのロールは管理可能です。 これにより、企業はビジネスのセキュリティを管理できます。 各テナントは、部署やチームなどの管理部門に対応しています。
このシナリオでは、クラスター管理者が名前空間の作成とポリシーの管理を担当します。 クラスター管理者は、特定のテナントに名前空間に対する権限が付与される委任管理モデルを使用できます。 テナントには、
[デプロイメント]
、[サービス]
、[ポッド]
、[ジョブ]
など、ポリシーに関連しないオブジェクトに対してCRUD
操作を実行する権限が付与されます。Dockerによって提供される分離メソッドは、このシナリオに適しています。 ビジネス要件に基づいて、ポッドセキュリティポリシー (PSP) などの他の方法を使用することもできます。 より厳密な分離が必要な場合は、異なる名前空間のサービス間の通信を制限することができます。
Kubernetes as a Service (KaaS)
Kubernetesをサービスとして提供するシナリオでは、ソフトマルチテナントを使用できます。 KaaS環境では、アプリケーションは共有クラスターでホストされます。 共有クラスターには、一連のPlatform as a Service (PaaS) サービスを提供するコントローラーとCustomResourceObject (CRD) が含まれています。 テナントはKubernetes APIサーバーと対話し、非ポリシーオブジェクトに対してCRUD操作を実行できます。 セルフサービス機能が提供されます。 たとえば、テナントは自分の名前空間を作成および管理できます。 このタイプの環境では、テナントは信頼できないコードを実行していると見なされます。
このタイプの環境でテナントを分離する場合は、ネットワークポリシーとポッドサンドボックスを使用する必要があります。 詳細については、「サンドボックスコンテナー」をご参照ください。
Software as a Service (SaaS)
SaaS環境では、各テナントは、クラスターで実行されるアプリケーションの特定のインスタンスに関連付けられます。 各インスタンスにはデータが含まれ、
Kubernetes RBAC
以外の個別のアクセス制御ポリシーを使用します。SaaS環境のテナントは、
Kubernetes APIサーバー
と対話しません。 SaaSアプリケーションは、Kubernetes APIサーバー
と対話して、各テナントが必要とするオブジェクトを作成します。
Kubernetes設定
Kubernetesは、コンテナ化されたワークロードを管理するために使用されるシングルテナントのオーケストレーションプラットフォームです。 Kubernetesを使用すると、コントロールプレーンはクラスター内のすべてのテナントで共有されます。 さまざまなKubernetesオブジェクトを使用して、テナントを分離できます。 たとえば、名前空間とRBAC
を使用して、テナントを論理的に分離できます。 クォータ
と制限範囲
を使用して、各テナントで消費できるクラスターリソースの量を制御することもできます。 各クラスタは、強力なセキュリティ境界を提供する。 クラスター内のホストにアクセスする攻撃者は、ホストにマウントされているすべてのSecrets
、ConfigMaps
、およびボリューム
を取得できます。 攻撃者はkubelet
を悪用することもできます。これにより、ノードの属性を操作したり、クラスター内で横方向に移動したりできます。 以下のKubernetesネイティブリソースは、Kubernetesなどのシングルテナントオーケストレーションプラットフォームを使用するときに発生するリスクを軽減するのに役立ちます。 前のセクションで提供されている方法を使用して、Kubernetesリソースを使用してテナントを分離することもできます。
名前空間
名前空間は、ソフトマルチテナントを実装するための基礎です。 名前空間を使用して、クラスターを論理パーティションに分割できます。 ソフトマルチテナントの実装に必要なクォータ、ネットワークポリシー、サービスアカウント、およびその他のオブジェクトは、名前空間にスコープする必要があります。
AuthN&AuthZ&入場料
Container Service for Kubernetes (ACK) クラスターの承認は、Resource Access Management (RAM) 承認とRBAC承認で構成されています。 RAM権限付与を使用して、クラスターに対するCRUD操作を含むクラスターレベルのアクセス制御を調整できます。 たとえば、RAMユーザーに必要な権限を付与することで、クラスターの表示管理、クラスターのスケーリング、クラスターへのノードの追加を行うことができます。 RBAC認証は、クラスター内のKubernetesリソースへのアクセスを制御するために使用されます。 RBAC権限付与を使用して、名前空間内の指定されたリソースにきめ細かいアクセス制御を適用できます。 ACKは、テナント内のユーザーに異なる定義済みロールのテンプレートを提供します。 複数のカスタムクラスターロールをユーザーに関連付けて、一度に複数のユーザーに権限を付与することもできます。 詳細については、『Authorization overview』をご参照ください。
ネットワークポリシー
デフォルトでは、Kubernetesクラスター内のすべてのポッドは相互に通信できます。 ネットワークポリシーを使用して、このデフォルト設定を変更できます。
ネットワークポリシーは、ラベルまたはCIDRブロックに基づいてポッド間の通信を制限します。 マルチテナント環境でテナント間のネットワーク分離が必要な場合は、次のルールを追加します。
ポッド間の通信を拒否するデフォルトのルール。
ポッドがDNSクエリをDNSサーバーに送信できるようにするルール。
クォータと制限範囲
クォータは、クラスターでホストされるワークロードの制限を定義するために使用されます。 クォータを使用して、ポッドで消費できるCPUおよびメモリリソースの最大量を指定できます。 クォータを使用して、クラスターまたは名前空間に割り当てることができるリソースの量を指定することもできます。 制限範囲では、各制限の最小値、最大値、およびデフォルト値を指定できます。
リソース使用率を最大化するには、共有クラスター内のリソースをオーバーコミットできます。 クラスタへのアクセスが無制限である場合、クラスタ内のリソースが使い果たされる可能性がある。 これにより、クラスターのパフォーマンスが低下し、アプリケーションの可用性に影響します。 ポッドのリクエストしきい値を小さな値に設定し、実際のリソース使用率がノードの容量を超えると、ノードのCPUまたはメモリリソースが使い果たされる可能性があります。 CPUまたはメモリリソースが使い果たされると、ポッドは、再起動されるか、またはノードから追い出され得る。
この問題を防ぐには、マルチテナント環境の名前空間にクォータを追加する必要があります。 これにより、テナントはクラスター内のポッドをスケジュールするときに、要求と制限のしきい値を指定します。 さらに、ポッドによって消費され得るリソースの量が制限される。 これにより、サービスが利用できなくなるリスクが軽減されます。
KaaSシナリオでは、クォータを使用して、テナントの要件を満たすようにクラスターリソースを割り当てることができます。
ポッドの優先順位とプリエンプション
顧客に異なるサービス品質 (QoS) レベルを提供する場合は、ポッドの優先順位とプリエンプションを使用できます。 たとえば、顧客aのポッドに顧客Bよりも高い優先度の値を指定できます。リソース容量が不十分な場合、kubeletは優先度の低い値を持つポッドを顧客Bから削除し、顧客Aの優先度の高い値を持つポッドを満たします。SaaS環境でこの方法を使用すると、プレミアム料金を支払う顧客に対してより高いQoSレベルを提供できます。
緩和方法
マルチテナント環境の管理者の主な関心事は、攻撃者が基盤となるホストにアクセスできないようにすることです。 次のいずれかの方法を使用して、攻撃者が基になるホストにアクセスできないようにします。
サンドボックス-コンテナ
Sandboxed-Containerは、Dockerランタイムの代替手段です。 Sandboxed-Containerを使用すると、専用カーネルを備えたサンドボックス化された軽量の仮想マシンでアプリケーションを実行できます。 これにより、リソースの分離が強化され、セキュリティが向上します。
Sandboxed-Containerは、信頼できないアプリケーションの分離、障害の分離、パフォーマンスの分離、複数のユーザー間の負荷の分離などのシナリオに適しています。 Sandboxed-Containerは、セキュリティを強化し、アプリケーションのパフォーマンスにわずかな影響を与え、ロギング、モニタリング、および柔軟なスケーリングの点でDockerと同じユーザーエクスペリエンスを提供します。 詳細については、「サンドボックスコンテナーの概要」をご参照ください。
オープンポリシーエージェント (OPA) &ゲートキーパー
Open Policy Agent (OPA) は強力なポリシーエンジンです。 OPAは分離されたポリシー決定をサポートし、Kubernetesで使用されます。 RBACを使用して名前空間レベルで分離を実行した後、エンタープライズアプリケーションのセキュリティ要件が満たされない場合は、OPAを使用してオブジェクトレベルでアクセスポリシーを制御できます。 Gatekeeperは、アプリケーションのデプロイ中にOPAによって作成されたポリシーを適用するKubernetesアドミッションコントローラーです。 詳細については、「Gatekeeper」をご参照ください。
さらに、OPAは、ラベルとアノテーションに基づいて、レイヤー7ネットワークポリシーと名前空間間のアクセス制御をサポートします。 OPAを使用して、Kubernetesネットワークポリシーを効率的に管理できます。
Kyverno
KyvernoはKubernetesネイティブのポリシーエンジンです。 Kyvernoは、Kubernetesリソースの設定の検証、変更、生成に使用できるポリシーを提供しています。 Kyvernoは、検証にKustomizeスタイルのオーバーレイを使用し、突然変異の戦略的マージパッチをサポートしています。 さらに、Kyvernoは柔軟なトリガーに基づいて、名前空間間でリソースをクローンできます。 詳細については、「Kyverno」をご参照ください。
Kyvernoを使用して、名前空間を分離し、ポッドセキュリティやその他のベストプラクティスを適用し、ネットワークポリシーなどのデフォルト設定を生成できます。 詳細については、「Policyリポジトリ」をご参照ください。
ハードマルチテナント
テナントごとに個別のクラスターを作成することで、ハードマルチテナントを実装できます。 ハードマルチテナントは、テナント間の強力な隔離を提供します。 次のセクションでは、ハードマルチテナントの欠点について説明します。
多数のテナントを管理すると、ハードマルチテナントのコストが大幅に増加します。 使用するクラスターごとに制御プレーン料金が課金されます。 さらに、コンピューティングリソースをクラスタ間で共有することはできません。 その結果、特定のクラスターが十分に活用されていない、または過度に活用されているシナリオで断片化が発生します。
クラスターを管理するには、特別なツールを購入または構築する必要があります。 何百ものクラスターを長期間にわたって管理する必要があります。
名前空間と比較して、テナントのクラスターの作成に必要な時間が長くなります。 ハードマルチテナントは、高度に規制された業界や強力な分離を必要とするSaaS環境に適しています。
将来のトレンド
Kubernetesコミュニティは、ソフトマルチテナントの欠点とハードマルチテナントの課題を認識しています。 Multi-Tenancy Special Interest Group (SIG) は、いくつかのプロジェクトを使用して欠点に対処しようとしています。
仮想クラスタ提案では、APIサーバ、コントローラマネージャ、およびスケジューラを含む、クラスタ内の各テナントに対して制御プレーンサービスの別々のインスタンスを作成するためのメカニズムについて説明する。 クラスター内のテナントは、Kubernetes on Kubernetesを参照します。 詳細については、「仮想クラスター」をご参照ください。
Kubernetes Enhancement proposal (KEP) で提案されているHNC (Hierarchical Namespace Controller) 提案では、ポリシーオブジェクトを継承して名前空間間に親子関係を作成する方法について説明します。 HNCでは、テナント管理者がサブ名前空間を作成することもできます。 詳細については、「HNC」をご参照ください。
マルチテナンシーベンチマークの提案では、名前空間を使用してクラスターを分離およびセグメント化した後にクラスターを共有する方法に関するガイドラインを提供します。 この提案では、kubectl-mtb CLIを使用してガイドラインに準拠する方法についても説明しています。 詳細については、「マルチテナンシーベンチマーク」をご参照ください。