このトピックでは、共有クラスター内でテナント間のリソース割り当てを公平に保ち、テナント間での攻撃を最小限に抑える方法について説明します。
背景情報
隔離はセキュリティレベルによって、ソフト マルチテナンシーとハード マルチテナンシーに分類されます。
-
ソフト マルチテナンシーは主に組織内のマルチテナント ユースケース向けです。テナントは一般的に信頼されており、隔離は内部チーム間の重要なサービスを保護し、潜在的な攻撃から防御することを目的としています。
-
ハード マルチテナンシーは、外部顧客向けにサービスを提供するサービスプロバイダー向けです。この場合、テナントが信頼できるとは保証できず、互いに攻撃したり Kubernetes システムを攻撃したりする可能性があるため、より厳格な隔離が必要です。
ソフト マルチテナンシー
ネイティブな Kubernetes 機能(namespace、roles、role bindings、および network policies など)を使用して、テナント間の論理的隔離を実現できます。たとえば、RBAC を使用すると、テナントが互いのリソースにアクセスまたは操作することを防止できます。quotas および limit ranges は、各テナントが消費できるクラスターリソース量を制御し、network policies は、異なる名前空間にデプロイされたアプリケーション間の通信を防止できます。
これらの制御機能では、異なるテナントに属する pods がノードを共有することを防ぐことはできません。nodeSelector、anti-affinity ルール、taints、および tolerations を使用して、異なるテナントの Pod を異なるノードにスケジュールできます。これは一般に、専用テナントノードを使用する方法と呼ばれます。テナント数が多いシナリオでは、このアプローチは複雑かつコストがかさむ可能性があります。
namespaces を使用して実装されたソフト マルチテナンシーでは、名前空間がクラスタースコープのリソースであるため、テナントにフィルター済みの名前空間リストを提供することはできません。テナントが特定の名前空間を表示できる場合、そのクラスター内のすべての名前空間を表示できます。
ソフト マルチテナンシーでは、テナントはデフォルトでクラスター内で実行中のすべてのサービスについて CoreDNS にクエリを実行できます。攻撃者は、クラスター内の任意の pod から dig SRV..svc.cluster.local を実行することでこれを悪用できます。クラスター内で実行中のサービスの DNS レコードへのアクセスを制限する必要がある場合は、CoreDNS のファイアウォールまたはポリシープラグインを使用してください。詳細については、「kubernetes-metadata-multi-tenancy-policy」をご参照ください。
-
企業内環境
最初のシナリオは、クラスターのすべてのユーザーが組織内に所属する企業環境です。これは多くの Kubernetes 顧客にとって一般的な利用モデルです。ユーザーのアイデンティティが管理されているため、セキュリティリスクは管理可能です。各テナントは通常、部門やチームなどの管理単位に対応します。
このようなシナリオでは、クラスター管理者が通常、名前空間の作成およびポリシーの管理を担当します。また、特定の個人に名前空間に対する監督権限を付与し、
deployments、services、pods、およびjobsなどのポリシー以外のオブジェクトに対してCRUD操作を実行できるようにする、委任型管理モデルも実装できます。このシナリオでは、Docker が提供する隔離メカニズムで十分です。Pod Security Policy (PSP) などの追加制御を導入することもできます。より厳格な隔離が必要な場合は、異なる名前空間内のサービス間の通信も制限する必要があります。
-
Kubernetes as a Service (KaaS)
ソフト マルチテナンシーは、Kubernetes as a Service (KaaS) を提供したいシナリオにも使用できます。KaaS では、アプリケーションが共有クラスター内でホストされ、一連のコントローラーおよび CRD が PaaS サービスのセットを提供します。テナントは Kubernetes API サーバーと直接やり取りし、ポリシー以外のオブジェクトに対して CRUD 操作を実行できます。テナントが独自の名前空間を作成および管理できるセルフサービスタイプの機能も利用できます。このような環境では、テナントは信頼できないコードを実行していると想定されます。
このような環境でテナントを隔離するには、厳格なネットワークポリシーおよび Pod サンドボックス化を実装する必要があります。詳細については、「 Sandboxed-Container 」をご参照ください。
-
Software as a Service (SaaS)
この環境では、各テナントはクラスター内で実行されるアプリケーションの特定のインスタンスに関連付けられます。各インスタンスは通常、独自のデータを持ち、
Kubernetes RBACとは独立したアクセス制御メカニズムを使用します。他のシナリオとは異なり、SaaS 環境のテナントは
Kubernetes APIと直接やり取りしません。代わりに、SaaS アプリケーションがKubernetes APIとやり取りして、各テナントに必要なオブジェクトを作成します。
ネイティブ Kubernetes 構成
Kubernetes は、シングルテナントのコンテナオーケストレーションプラットフォームとして設計されています。つまり、クラスター内のすべてのテナント間でコントロールプレーンの単一インスタンスが共有されます。さまざまな Kubernetes オブジェクトを使用してマルチテナント隔離を実現できます。たとえば、名前空間およびロールベースアクセス制御 (RBAC) を使用して、テナント間の論理的隔離を実現できます。同様に、resource quotas および limit ranges を使用して、各テナントが消費できるクラスターリソース量を制御できます。ただし、クラスターは強力なセキュリティ境界を提供する唯一の構造体です。これは、クラスター内のホストへのアクセスを取得した攻撃者が、そのホスト上にマウントされたすべての secrets、configmaps、および volumes を取得できるためです。また、攻撃者は Kubelet を偽装してノードプロパティを操作したり、クラスター内で横方向に移動したりすることもできます。以下のネイティブ Kubernetes 構成は、これらのリスクを軽減し、ある程度の隔離を提供するのに役立ちます。
-
名前空間
名前空間はソフト マルチテナンシーを実装する基盤です。これにより、クラスターを異なる論理レイヤーに分割できます。マルチテナンシーを実現するには、リソースクォータ、ネットワークポリシー、サービスアカウント、およびその他のリソースを名前空間のスコープ内で実装する必要があります。
-
認証、認可、アドミッション制御
ACK クラスターの認可は、Resource Access Management (RAM) 認可と RBAC 認可の 2 段階で行われます。RAM 認可は、クラスター管理インターフェイスへのアクセスを制御し、クラスターの可視性、スケーリング、ノードの追加などのクラスターに対する CRUD 権限を管理します。RBAC 認可は、クラスター内の Kubernetes リソースモデルへのアクセスを制御し、特定のリソースに対して名前空間レベルでの詳細な認可を可能にします。ACK の認可管理では、テナント内のユーザー向けに複数のレベルで事前定義されたロールテンプレートを提供し、複数のユーザー定義クラスターロールのバインドをサポートし、ユーザーのバッチ認可も可能です。詳細については、「Authorization overview」をご参照ください。
-
ネットワークポリシー
デフォルトでは、Kubernetes クラスター内のすべての Pod が互いに通信できます。ネットワークポリシーを使用して、このデフォルトの動作を変更します。
-
ネットワークポリシーは、ラベルまたは IP アドレス範囲を使用して Pod 間の通信を制限します。テナント間で厳格なネットワーク分離を必要とするマルチテナント環境では、次の 2 つのルールを追加する必要があります。
-
Pod 間の通信を拒否するデフォルトルール。
-
すべての Pod が名前解決のために DNS サーバーにクエリを実行できるようにするルール。
-
-
リソースクォータおよび LimitRange
リソースクォータは、クラスター内でホストされるワークロードに対する制限を定義します。リソースクォータを使用すると、Pod が消費できる CPU およびメモリの最大量を指定できます。また、クラスターまたは名前空間内で割り当て可能なリソース数を制限することもできます。LimitRange を使用すると、各制限の最小値、最大値、およびデフォルト値を宣言できます。
共有クラスターでリソースをオーバーコミットすることは、リソース使用率を最大化できるため、多くの場合有益です。ただし、クラスターへの無制限なアクセスはリソース飢餓を引き起こし、パフォーマンスの低下やアプリケーションの可用性喪失につながる可能性があります。Pod のリクエストが低く設定され、実際のリソース使用量がノードの容量を超えると、ノードは CPU またはメモリの圧迫状態になります。このような状況では、Pod が再起動またはノードからエビクトされる可能性があります。
これを防ぐには、マルチテナント環境で名前空間にリソースクォータを適用する必要があります。これにより、テナントはクラスター上で Pod をスケジュールする際にリクエストおよびリミットを指定することが強制されます。この方法は、Pod が消費できるリソース量を制限することで、潜在的なサービス拒否 (DoS) リスクを軽減するのにも役立ちます。
KaaS シナリオでは、リソースクォータを使用して、テナントのニーズに合わせたクラスターリソースを割り当てることができます。
-
Pod 優先度およびプリエンプション
Pod 優先度およびプリエンプションは、異なる顧客に異なるサービス品質 (QoS) レベルを提供したい場合に役立ちます。たとえば、Pod 優先度を使用して、顧客 A の Pod を顧客 B の Pod よりも高い優先度で実行するように構成できます。容量が不足している場合、Kubelet は顧客 A の高優先度 Pod を収容するために、顧客 B の低優先度 Pod をエビクトします。SaaS 環境では、これは、より高品質なサービスに対してより多くの料金を支払う意思のある顧客にサービスを提供する便利な方法です。
緩和策
マルチテナント環境のセキュリティ管理者として、最も懸念すべき点は、攻撃者が基盤となるホストへのアクセスを取得することを防ぐことです。このリスクを軽減するために、以下の制御機能を検討してください。
-
Sandboxed-Container
標準的な Docker ランタイムと比較して、Sandboxed-Container は新しいコンテナランタイムオプションを提供し、アプリケーションを軽量仮想マシンのサンドボックス環境で実行できるようにします。独立したカーネルを持ち、より強力なセキュリティ隔離を提供します。
Sandboxed-Container は、信頼できないアプリケーションの隔離、障害分離、パフォーマンス分離、および複数ユーザー間のワークロード隔離などのシナリオに特に適しています。セキュリティを向上させながらもパフォーマンスへの影響は最小限に抑えられ、ログ、モニタリング、エラスティシティなどの機能では Docker コンテナと同等のユーザーエクスペリエンスを提供します。詳細については、「Sandboxed-Container」をご参照ください。
-
Open Policy Agent (OPA) および Gatekeeper
Open Policy Agent (OPA) は、ポリシー決定サービスを分離してサポートする強力なポリシーエンジンであり、Kubernetes クラスターで広く使用されています。RBAC による名前空間レベルの隔離が複雑な企業のセキュリティ要件を満たせない場合、OPA を使用してオブジェクトモデルレベルで詳細なアクセス制御ポリシーを提供できます。Gatekeeper は Kubernetes のアドミッションコントローラーであり、アプリケーションデプロイ時に指定された OPA ポリシーを強制できます。詳細については、「Gatekeeper」をご参照ください。
OPA は、レイヤー 7 のネットワークポリシー定義およびラベルとアノテーションに基づく名前空間間アクセス制御もサポートしており、ネイティブ Kubernetes ネットワークポリシーを効果的に強化する手段となります。
-
Kyverno
Kyverno は Kubernetes 向けに設計されたポリシーエンジンであり、Kubernetes リソースの検証、ミューテート、およびポリシー生成が可能です。Kyverno は Kustomize スタイルのポリシー検証およびミューテートをサポートし、柔軟なトリガーに基づいて名前空間間でリソースをクローンできます。詳細については、「Kyverno」をご参照ください。
Kyverno を使用して、名前空間の隔離、Pod セキュリティおよびその他のベストプラクティスの実装、ネットワークポリシーなどのデフォルト設定の生成が可能です。詳細については、「policy repository」をご参照ください。
ハード マルチテナンシー
テナントごとに個別のクラスターを構成すると、ハード マルチテナンシーを実現できます。これによりテナント間の非常に強力な隔離が提供されますが、いくつかの欠点があります。
-
テナント数が多い場合、コストが高くなります。各クラスターのコントロールプレーンに対して料金が発生し、計算リソースを共有できないため、一部のクラスターが未使用になる一方で、他のクラスターが過剰に使用される断片化が発生します。
-
これらのクラスターを管理するために、専用のツールを購入または構築する必要がある場合があります。時間の経過とともに、数百または数千のクラスターを管理することは、運用面で非常に負担が大きくなります。
-
テナントごとにクラスターを作成するのは、名前空間を作成するよりも遅くなります。ハード マルチテナンシーのアプローチは、高度に規制された業界や、強力な隔離を必要とする SaaS 環境で必要不可欠です。
今後の方向性
Kubernetes コミュニティは、ソフト マルチテナンシーの現在の課題およびハード マルチテナンシーの課題を認識しています。マルチテナンシー特別興味グループ (SIG) は、いくつかのインキュベーションプロジェクトを通じてこれらの問題の解決を試みています。
-
仮想クラスター提案では、クラスター内の各テナントに対してコントロールプレーンサービスの個別インスタンスを作成するメカニズム(「Kubernetes on Kubernetes」とも呼ばれる概念)が説明されています。これらのサービスには、API サーバー、コントローラーマネージャー、スケジューラーが含まれます。詳細については、「Virtual Cluster」をご参照ください。
-
階層的名前空間コントローラー (HNC) 提案 (KEP) では、ポリシーオブジェクトの継承およびテナント管理者によるサブ名前空間の作成機能を通じて、名前空間間に親子関係を作成する方法が説明されています。詳細については、「HNC」をご参照ください。
-
マルチテナンシー ベンチマーク提案では、名前空間を使用して共有クラスターを隔離およびセグメント化するためのガイドラインと、コンプライアンスを検証するためのコマンドラインツール Kubectl-mtb が提供されています。詳細については、「Multi-Tenancy Benchmarks」をご参照ください。