Istio ソフトマルチテナンシーのサポート
Kubernetesの名前空間とRBACを使用して、Istioのソフトマルチテナンシー環境を作成します。
マルチテナンシーは、さまざまなアプリケーションの多くの環境で一般的に使用されていますが、テナントごとに提供される実装の詳細と機能は、すべての環境で1つのモデルに従っているわけではありません。 Kubernetes マルチテナンシーワーキンググループ は、Kubernetes 内で利用可能であるべきマルチテナントのユースケースと機能を定義するために取り組んでいます。ただし、これまでの作業から、悪意のあるコンテナやワークロードが他のテナントのポッドやカーネルリソースにアクセスするのを完全に防ぐことができないため、「ソフトマルチテナンシー」のみが可能であることが明らかになっています。
ソフトマルチテナンシー
このブログでは、「ソフトマルチテナンシー」とは、単一の Kubernetes コントロールプレーンに複数の Istio コントロールプレーンと複数のメッシュがあり、テナントごとに1つのコントロールプレーンと1つのメッシュがあるものと定義します。クラスタ管理者はすべての Istio コントロールプレーン全体で制御と可視性を取得し、テナント管理者は特定の Istio インスタンスの制御のみを取得します。テナント間の分離は、Kubernetes の名前空間と RBAC によって提供されます。
このデプロイモデルのユースケースの1つは、悪意のあるアクションは想定されていないが、テナントの明確な分離が依然として必要な共有企業インフラストラクチャです。
潜在的な将来の Istio マルチテナントデプロイモデルは、このブログの最後に記載されています。
デプロイ
複数の Istio コントロールプレーン
複数の Istio コントロールプレーンのデプロイは、マニフェストファイル内のすべての namespace
参照を目的の名前空間に置き換えることから始まります。 istio.yaml
を例として使用すると、2つのテナントレベルの Istio コントロールプレーンが必要な場合、1つ目は istio-system
の istio.yaml
デフォルト名を使用でき、2番目のコントロールプレーンは異なる名前空間を持つ新しい yaml ファイルを生成することで作成できます。例として、次のコマンドは、Istio 名前空間が istio-system1
である yaml ファイルを作成します。
$ cat istio.yaml | sed s/istio-system/istio-system1/g > istio-system1.yaml
istio.yaml
ファイルには、コントロールプレーンを構成するポッド(Mixer、Pilot、Ingress、Galley、CA)を含む、Istio コントロールプレーンデプロイの詳細が含まれています。2つの Istio コントロールプレーン yaml ファイルをデプロイすると
$ kubectl apply -f install/kubernetes/istio.yaml
$ kubectl apply -f install/kubernetes/istio-system1.yaml
2つの名前空間で実行される2つの Istio コントロールプレーンになります。
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
istio-system istio-ca-ffbb75c6f-98w6x 1/1 Running 0 15d
istio-system istio-ingress-68d65fc5c6-dnvfl 1/1 Running 0 15d
istio-system istio-mixer-5b9f8dffb5-8875r 3/3 Running 0 15d
istio-system istio-pilot-678fc976c8-b8tv6 2/2 Running 0 15d
istio-system1 istio-ca-5f496fdbcd-lqhlk 1/1 Running 0 15d
istio-system1 istio-ingress-68d65fc5c6-2vldg 1/1 Running 0 15d
istio-system1 istio-mixer-7d4f7b9968-66z44 3/3 Running 0 15d
istio-system1 istio-pilot-5bb6b7669c-779vb 2/2 Running 0 15d
Istio サイドカー および必要な場合は アドオンマニフェストも、テナントの Istio コントロールプレーンで使用されている構成済み namespace
に一致するようにデプロイする必要があります。
これらの2つの yaml ファイルの実行は、テナントレベルの管理者ではなく、クラスタ管理者の責任です。テナント管理者を割り当てられた名前空間のみに制限する、追加のRBAC制限も構成および適用する必要があります。
共通リソースと名前空間固有のリソースの分割
Istio リポジトリのマニフェストファイルは、すべての Istio コントロールプレーンで使用される共通リソースと、コントロールプレーンごとに複製されるリソースの両方を作成します。上記のように istio-system
名前空間参照を置き換えることで複数のコントロールプレーンをデプロイするのは簡単なことですが、より良いアプローチは、マニフェストをすべてのテナントに対して1回デプロイされる共通部分と、テナント固有の部分に分割することです。カスタムリソース定義の場合、ロールとロールバインディングは、提供されている Istio マニフェストから分離する必要があります。さらに、提供されている Istio マニフェストのロールとロールバインディングは、マルチテナント環境にはおそらく適しておらず、次のセクションで説明するように変更または拡張する必要があります。
Istio コントロールプレーンリソースの Kubernetes RBAC
テナント管理者を単一の Istio 名前空間に制限するために、クラスタ管理者は、少なくとも下記のような Role
と RoleBinding
を含むマニフェストを作成します。この例では、sales-admin という名前のテナント管理者は、名前空間 istio-system1
に制限されています。完成したマニフェストには、テナント管理者にリソースアクセスを提供する Role
の下に、さらに多くの apiGroups
が含まれます。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: istio-system1
name: ns-access-for-sales-admin-istio-system1
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: access-all-istio-system1
namespace: istio-system1
subjects:
- kind: User
name: sales-admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: ns-access-for-sales-admin-istio-system1
apiGroup: rbac.authorization.k8s.io
サービスディスカバリのための特定の名前空間の監視
テナント管理者のアクセスを特定の Istio コントロールプレーンに制限する RBAC ルールを作成することに加えて、Istio マニフェストを更新して、Pilot が xDS キャッシュの作成を監視するアプリケーションの名前空間を指定する必要があります。これは、Pilot コンポーネントを --appNamespace, ns-1
の追加のコマンドライン引数で起動することで行われます。ここで、ns-1 は、テナントのアプリケーションがデプロイされる名前空間です。istio-system1.yaml
ファイルからの例を以下に示します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: istio-pilot
namespace: istio-system1
annotations:
sidecar.istio.io/inject: "false"
spec:
replicas: 1
template:
metadata:
labels:
istio: pilot
spec:
serviceAccountName: istio-pilot-service-account
containers:
- name: discovery
image: docker.io/<user ID>/pilot:<tag>
imagePullPolicy: IfNotPresent
args: ["discovery", "-v", "2", "--admission-service", "istio-pilot", "--appNamespace", "ns-1"]
ports:
- containerPort: 8080
- containerPort: 443
名前空間へのテナントアプリケーションのデプロイ
クラスタ管理者がテナントの名前空間(例:istio-system1
)を作成し、Pilot のサービスディスカバリが特定のアプリケーションの名前空間(例:ns-1)を監視するように構成されたので、そのテナントの特定の名前空間にデプロイするアプリケーションマニフェストを作成します。例:
apiVersion: v1
kind: Namespace
metadata:
name: ns-1
そして、アプリケーションのマニフェストファイルに含まれる各リソースタイプに名前空間参照を追加します。例:
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
namespace: ns-1
図には示されていませんが、アプリケーションの名前空間には、特定のリソースへのアクセスを制限する RBAC 設定もあります。これらの RBAC 設定は、クラスタ管理者および/またはテナント管理者によって設定できます。
マルチテナント環境での kubectl
の使用
ルーティングルールまたは宛先ポリシーを定義する場合、kubectl
コマンドが Istio コントロールプレーンが実行されている名前空間にスコープされていることを確認して、リソースが適切な名前空間に作成されるようにする必要があります。さらに、ルール自体はテナントの名前空間にスコープされている必要があるため、そのテナントのメッシュに適切に適用されます。-i オプションは、Istio コントロールプレーンがデプロイされている名前空間でルールを作成(または取得または記述)するために使用されます。-n オプションは、ルールをテナントのメッシュにスコープし、テナントのアプリがデプロイされている名前空間に設定する必要があります。リソースの .yaml ファイルが適切にスコープしている場合は、コマンドラインで -n オプションを省略できることに注意してください。
たとえば、次のコマンドは、istio-system1
名前空間にルーティングルールを追加するために必要です。
$ kubectl –i istio-system1 apply -n ns-1 -f route_rule_v2.yaml
次のコマンドを使用して表示できます。
$ kubectl -i istio-system1 -n ns-1 get routerule
NAME KIND NAMESPACE
details-Default RouteRule.v1alpha2.config.istio.io ns-1
productpage-default RouteRule.v1alpha2.config.istio.io ns-1
ratings-default RouteRule.v1alpha2.config.istio.io ns-1
reviews-default RouteRule.v1alpha2.config.istio.io ns-1
マルチテナント環境における namespace
要件の詳細については、このドキュメントの複数の Istio コントロールプレーンセクションを参照してください。
テスト結果
上記の手順に従うと、クラスタ管理者は、RBACと名前空間を介して、テナント管理者がデプロイできるものを制限する環境を作成できます。
デプロイ後、特定のテナント管理者に割り当てられた Istio コントロールプレーンポッドへのアクセスが許可されます
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
grafana-78d649479f-8pqk9 1/1 Running 0 1d
istio-ca-ffbb75c6f-98w6x 1/1 Running 0 1d
istio-ingress-68d65fc5c6-dnvfl 1/1 Running 0 1d
istio-mixer-5b9f8dffb5-8875r 3/3 Running 0 1d
istio-pilot-678fc976c8-b8tv6 2/2 Running 0 1d
istio-sidecar-injector-7587bd559d-5tgk6 1/1 Running 0 1d
prometheus-cf8456855-hdcq7 1/1 Running 0 1d
ただし、クラスタのすべてのポッドへのアクセスは許可されていません
$ kubectl get pods --all-namespaces
Error from server (Forbidden): pods is forbidden: User "dev-admin" cannot list pods at the cluster scope
また、別のテナントの名前空間へのアクセスも許可されていません
$ kubectl get pods -n istio-system1
Error from server (Forbidden): pods is forbidden: User "dev-admin" cannot list pods in the namespace "istio-system1"
テナント管理者は、そのテナント用に構成されたアプリケーションの名前空間にアプリケーションをデプロイできます。例として、Bookinfoマニフェストを更新し、テナントのアプリケーションの名前空間ns-0にデプロイすると、このテナントの名前空間で使用されているポッドを一覧表示することが許可されます
$ kubectl get pods -n ns-0
NAME READY STATUS RESTARTS AGE
details-v1-64b86cd49-b7rkr 2/2 Running 0 1d
productpage-v1-84f77f8747-rf2mt 2/2 Running 0 1d
ratings-v1-5f46655b57-5b4c5 2/2 Running 0 1d
reviews-v1-ff6bdb95b-pm5lb 2/2 Running 0 1d
reviews-v2-5799558d68-b989t 2/2 Running 0 1d
reviews-v3-58ff7d665b-lw5j9 2/2 Running 0 1d
ただし、別のテナントのアプリケーションの名前空間へのアクセスは許可されていません
$ kubectl get pods -n ns-1
Error from server (Forbidden): pods is forbidden: User "dev-admin" cannot list pods in the namespace "ns-1"
アドオンツール(例:Prometheus)がデプロイされている場合(Istio namespace
によっても制限されます)、返される統計結果は、そのテナントのアプリケーションの名前空間から確認されたトラフィックのみを表します。
結論
実施された評価では、Istio は少数のマルチテナントのユースケースに対応するのに十分な機能とセキュリティを備えていることが示されています。また、特に信頼できないテナント間の完全なセキュリティと分離を必要とするユースケースなど、他のユースケースに対して、Istio と Kubernetes が十分な機能とセキュリティを提供できないことも示しています。より安全なセキュリティと分離モデルを実現するために必要な改善には、Istio 機能の改善ではなく、コンテナテクノロジー(例:Kubernetes)の取り組みが必要です。
問題
- あるテナントの Istio コントロールプレーン(例:
istio-system
名前空間)からの CA(認証局)および Mixer ポッドログには、2番目のテナントの Istio コントロールプレーン(例:istio-system1
名前空間)からの「情報」メッセージが含まれていました。
他のマルチテナンシーモデルに関する課題
他のマルチテナンシーデプロイモデルが検討されました
メッシュ上の各テナントに1つずつ、複数のアプリケーションを備えた単一のメッシュ。クラスタ管理者は、メッシュ全体およびすべてのアプリケーション全体で制御と可視性を取得し、テナント管理者は特定のアプリケーションの制御のみを取得します。
テナントごとに1つのメッシュを持つ複数のメッシュを備えた単一の Istio コントロールプレーン。クラスタ管理者は、Istio コントロールプレーン全体とすべてのメッシュ全体で制御と可視性を取得し、テナント管理者は特定のメッシュの制御のみを取得します。
単一のクラウド環境(クラスタ制御)ですが、複数の Kubernetes コントロールプレーン(テナント制御)。
これらのオプションは、コード変更なしには適切にサポートできないか、ユースケースを完全に満たしていません。
現在のIstioの機能は、クラスタとテナントの操作をサポートするのに十分なRBAC機能がないため、最初のモデルをサポートするのに適していません。さらに、現在のメッシュモデルとIstioがEnvoyプロキシに構成を適用する方法では、1つのメッシュ内に複数のテナントが存在するのは非常に危険です。
2番目のオプションに関しては、現在のIstioのパラダイムでは、Istioコントロールプレーンごとに1つのメッシュを想定しています。このモデルをサポートするために必要な変更は非常に大規模です。名前空間に基づいたリソースとセキュリティドメインのより細かいスコープ設定や、追加のIstio RBACの変更が必要になります。このモデルは将来の作業で対応される可能性が高いですが、現時点では不可能です。
3番目のモデルは、ほとんどのユースケースを満たしていません。ほとんどのクラスタ管理者は、テナントにPaaSとして提供する共通のKubernetesコントロールプレーンを好むためです。
今後の作業
1つのIstioコントロールプレーンで複数のメッシュを制御できるようにすることは、次の明らかな機能となります。さらなる改善点として、テナント間で一定レベルの隔離とセキュリティを備えた複数のテナントをホストできる単一のメッシュを提供することが挙げられます。これは、Kubernetesと同じ名前空間という論理的な概念を使用して、単一のコントロールプレーン内でパーティショニングすることで実現できます。Istioコミュニティ内で、追加のユースケースと、それらのユースケースをサポートするために必要なIstioの機能を定義するためのドキュメントが開始されています。
参考文献
- Kubernetesのマルチテナンシーサポートに関するビデオ、RBACと名前空間によるマルチテナンシーサポートとセキュリティモデリング、および補足資料。
- Kubernetesの「協調的なソフトマルチテナンシー」のサポートについて議論したセキュリティに関するKubeCon講演、信頼構築:Kubernetesを安全にする方法。
- RBACと名前空間に関するKubernetesドキュメント。
- マルチテナンシーの深掘りに関するKubeCon資料。
- Kubernetesのマルチテナンシーモデルに関するGoogleドキュメント。(権限が必要です)
- Cloud FoundryのWIPドキュメント、マルチクラウドとマルチテナンシー
- Istio Auto Multi-Tenancy 101