Flux でマルチテナンシーをセットアップする
各チームに独自の namespace とリポジトリを与え、Kubernetes の RBAC で分離を強制します。
複数のチームがクラスターを共有する場合、各チームが、他のチームのものに触れることなく、自分のアプリケーションをデプロイできるようにしたいものです。Flux は、これを Kubernetes のプリミティブの上に構築します。各テナントは namespace、service account、role binding を得て、Flux はその service account になりすましながら、テナントのマニフェストを適用します。分離は Kubernetes の RBAC によって強制され、別個のポリシーエンジンは必要ありません。このガイドでは、dev-team というテナントをセットアップします。
2 つのロール
- プラットフォーム管理者は、クラスターと Flux のインストールを所有します。テナントを作成し、各テナントがアクセスできるものを決めます。
- テナントは、自分のアプリケーションを所有します。自分のリポジトリにマニフェストを commit し、Flux はそれをテナントの namespace の中だけに適用します。
テナントを作成する
CLI が、namespace、service account、RBAC を生成してくれます。プラットフォームのリポジトリの clone で実行します。
mkdir -p tenants/base/dev-team
flux create tenant dev-team \
--with-namespace=apps \
--export > tenants/base/dev-team/rbac.yaml
生成された YAML には、apps という名前の Namespace、dev-team という名前の ServiceAccount、そしてその service account に、apps namespace の内部のみで cluster-admin ロールを付与する RoleBinding が含まれています。その外では、何もできません。
テナントのリポジトリを接続する
テナント自身のリポジトリのための source と Kustomization を、テナントの namespace に作成します。
flux create source git dev-team \
--namespace=apps \
--url=https://github.com/your-org/dev-team-apps \
--branch=main \
--export > tenants/base/dev-team/sync.yaml
flux create kustomization dev-team \
--namespace=apps \
--service-account=dev-team \
--source=GitRepository/dev-team \
--path="./" \
--prune=true --interval=5m \
--export >> tenants/base/dev-team/sync.yaml
重要な行は、Kustomization の serviceAccountName: dev-team です。これにより kustomize-controller は、テナントのマニフェストをその service account として適用するため、apps の外にリソースを作成しようとする試みや、ClusterRole のようなクラスタースコープのリソースは、Kubernetes の API によって拒否されます。同じフィールドが HelmRelease にもあります。
tenants/base/dev-team/ に、rbac.yaml と sync.yaml を列挙する kustomization.yaml を追加し、クラスターのフォルダーからテナントを参照します。たとえば clusters/production/tenants.yaml の、path: ./tenants/production を持つ Flux の Kustomization を通じて行います。commit して push します。Flux は、namespace、RBAC、テナントの同期を作成し、そこからはチーム自身のリポジトリが引き継ぎます。
プライベートなテナントのリポジトリの場合は、そのテナントのオブジェクトだけがそれを参照するように、テナントの namespace に認証情報を作成します。
flux create secret git dev-team-auth \
--namespace=apps \
--url=https://github.com/your-org/dev-team-apps \
--username=git --password=<token>
次に、source に --secret-ref=dev-team-auth を追加します。
コントローラーをロックダウンする
service account は、テナントがそれを回避できない場合にだけ役に立ちます。clusters/<env>/flux-system/kustomization.yaml の Flux のインストールにパッチを当てて、コントローラーにルールを強制させます。
patches:
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
- op: add
path: /spec/template/spec/containers/0/args/-
value: --default-service-account=default
target:
kind: Deployment
name: "(kustomize-controller|helm-controller)"
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
target:
kind: Deployment
name: "(notification-controller|image-reflector-controller|image-automation-controller)"
これらのフラグの役割は次のとおりです。
--no-cross-namespace-refs=trueは、テナントの Kustomization が別の namespace の source を参照することを防ぎ、テナントが互いのリポジトリや認証情報を使えないようにします。--default-service-account=defaultは、何も設定されていない場合に、コントローラーがオブジェクトの namespace のdefaultservice account になりすますようにします。serviceAccountNameを忘れたテナントは、Flux の cluster-admin の ID ではなく、ほとんど権限のない ID を得ます。
パッチを、bootstrap がそのフォルダーに生成した kustomization.yaml に commit します。bootstrap を再実行しても、そのファイルに追加したカスタマイズは保持されます。お使いのバージョンの正確なパッチは、Flux の現在のマルチテナンシーのドキュメントを確認してください。
テナントができることを制限する
namespace の境界を超えて、追加の制御を検討してください。
- namespace スコープの RBAC。 テナントが、たとえば Role や NetworkPolicy を作成すべきでない場合は、生成された
cluster-adminの role binding を、より狭いロールに置き換えます。 - アドミッションポリシー。 Kyverno や ValidatingAdmissionPolicy で、イメージレジストリの強制、リソース制限、特権 Pod の禁止を行います。
- クォータ。 RBAC と並んで、テナントの namespace に
ResourceQuotaとLimitRangeを追加します。 - ネットワークの分離。 テナントの namespace が互いに通信できないように、デフォルト拒否の
NetworkPolicyオブジェクトを追加します。
分離を確認する
テナントのリポジトリに、テナントの namespace の外に何かを作成するマニフェスト(ClusterRole など)を追加して push します。次に確認します。
flux get kustomizations -n apps
kubectl describe kustomization dev-team -n apps
Kustomization は、service account の名前を示す forbidden エラーで失敗します。これはまさに望ましい動作です。不正なマニフェストを削除すると、Flux は自力で回復します。
プロジェクトベースのテナンシーとの比較
一部のツールは、テナントを独自のポリシーオブジェクトを持つプロジェクトとしてモデル化します。Flux にはそのような概念はありません。テナントは、単に namespace と、Flux がなりすます service account であり、つまり、権限が適用される場所は、Kubernetes の API サーバーという 1 か所だけです。
人気のガイド
-
Push と Pull:Flux が Kubernetes にデリバリーする仕組み Git 主導の pull 型デリバリーが、デプロイ、セキュリティ、復旧の方法をどう変えるか。 -
GitRepository と Kustomization で最初のアプリケーションをデプロイする Kustomization リソースを使って Flux を Git のマニフェストに向け、同期の様子を確認します。 -
同期動作を制御する:間隔、prune、ドリフトの修正、ロールバック Flux がいつ変更を適用するか、何を削除するか、どう一時停止するか、失敗したデプロイをどう元に戻すかを決めます。 -
Flux Image Automation でイメージの更新を自動化する 新しいコンテナイメージのタグを Flux に検出させ、Git に commit させます。 -
Flux でマルチクラスターを構成する 共有インフラとクラスターごとの違いを持たせて、1 つのリポジトリから複数のクラスターを管理します。 -
Flux CD と Argo CD:GitOps ツールの選び方 アーキテクチャ、UI、Helm、シークレット、テナンシー、イメージの自動化を比較して、適切なツールを選びます。