Flux CD Flux CD

Flux でマルチテナンシーをセットアップする

各チームに独自の namespace とリポジトリを与え、Kubernetes の RBAC で分離を強制します。

15 min learn.level.上級

複数のチームがクラスターを共有する場合、各チームが、他のチームのものに触れることなく、自分のアプリケーションをデプロイできるようにしたいものです。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 の default service 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 か所だけです。

人気のガイド