Add multi-tenancy guide#160
Conversation
This PR documents how to run multiple meshes on the same ClusterSet with separate control planes, hub namespace isolation, cert-manager trust chains and data-plane isolation via discoverySelectors. Signed-off-by: Sridhar Gaddam <sgaddam@redhat.com>
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: sridhargaddam The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited) Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 9 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (9 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
|
||
| Multiple `MultiClusterMesh` resources can target the same [ManagedClusterSet], running independent meshes on the same pool of clusters. Isolation between meshes is achieved through: | ||
|
|
||
| 1. **Separate control plane namespaces** - Each mesh installs its Istio control plane in a distinct namespace on spoke clusters |
There was a problem hiding this comment.
This says each mesh "installs its Istio control plane in a distinct namespace." The add-on installs the operator and mesh plumbing (certs, discovery tokens), but users create the Istio CRs themselves (design.md L109, L212). Managing Istio CRs centrally is phase 2 (L244).
Rephrase to something like: "Each mesh uses a separate control plane namespace on spoke clusters" and note that Istio CR creation is user-managed.
|
|
||
| Each Istio control plane discovers services across all namespaces by default. Configure `discoverySelectors` to restrict visibility to the mesh's own application namespaces: | ||
|
|
||
| ```yaml |
There was a problem hiding this comment.
This section transitions from hub-side resources to spoke-side user configuration without making it clear. Everything above (MultiClusterMesh, Certificates, RBAC) is on the hub.
This Istio CR and the namespace labeling below are on each spoke cluster.
Suggestion: add a note at the start of this section, e.g.:
The following configuration is applied directly on each spoke cluster (not on the hub).
The kubectl label namespace commands below (L202-203) need the same clarification.
| kubectl label managedcluster cluster2 cluster.open-cluster-management.io/clusterset=shared-cluster-set | ||
| ``` | ||
|
|
||
| ### Hub namespaces |
There was a problem hiding this comment.
The guide creates hub namespaces for each team but does not mention ManagedClusterSetBinding. In OCM, a binding is typically needed to use a ClusterSet from a namespace.
The controller lists clusters by their ClusterSet label directly and does not require a binding. Worth adding a brief note here, e.g.:
Note: The add-on controller lists clusters by their ClusterSet label directly. A
ManagedClusterSetBindingis not required for the add-on to function, though you may want one if using Placements alongside the mesh.
| discoverySelectors: | ||
| - matchLabels: | ||
| mesh: team-a | ||
| ``` |
There was a problem hiding this comment.
The cert-manager and RBAC sections have "Repeat for mesh-team-b" notes, but this section does not.
Worth adding after L204:
Repeat for Team B with mesh: team-b.
|
|
||
| ### MultiClusterMesh resources | ||
|
|
||
| Team A — control plane in `istio-system-team-a`: |
There was a problem hiding this comment.
nit: em-dashes on lines 102 and 121. Replace with a colon or comma:
| Team A — control plane in `istio-system-team-a`: | |
| Team A, control plane in `istio-system-team-a`: |
Same on line 121 for Team B.
|
|
||
| ### cert-manager trust chain | ||
|
|
||
| Each namespace needs its own trust chain (self-signed issuer → root CA certificate → CA-backed issuer). The add-on uses the CA-backed issuer to mint intermediate CAs per cluster. |
There was a problem hiding this comment.
nit: the → renders fine in browsers but can be mangled in some terminals. Consider using -> instead.
| Example RBAC for Team A: | ||
|
|
||
| ```yaml | ||
| --- |
There was a problem hiding this comment.
Two things:
-
The Role is duplicated per namespace. You could define it once as a
ClusterRoleand bind it per namespace viaRoleBinding. That's the standard pattern for reusable permission sets. -
This grants every member of
team-afull CRUD on meshes. Worth a note that in practice you'd scope this to platform engineers and give the rest of the team read-only access.
|
|
||
| Team A (`mesh-team-a`): | ||
|
|
||
| ```yaml |
There was a problem hiding this comment.
This trust chain duplicates samples/cert-manager-issuer.yaml with different names.
You could instead reference the existing sample and note what to change for multi-tenancy:
Apply the trust chain from samples/cert-manager-issuer.yaml in each team namespace, adjusting the namespace and commonName.
| name: mesh-root-ca | ||
| ``` | ||
|
|
||
| Both meshes share the operator installation on each cluster. Trust domains (`team-a-mesh`, `team-b-mesh`) and discovery tokens are independent. |
There was a problem hiding this comment.
nit: both meshes reference issuerRef.name: mesh-root-ca which looks like a shared issuer. Worth adding a note that the issuerRef resolves in the mesh's namespace, so each team's mesh-root-ca is a different issuer backed by a different root CA.
| ```yaml | ||
| apiVersion: cluster.open-cluster-management.io/v1beta2 | ||
| kind: ManagedClusterSet | ||
| metadata: | ||
| name: shared-cluster-set | ||
| spec: | ||
| clusterSelector: | ||
| selectorType: ExclusiveClusterSetLabel | ||
| ``` | ||
|
|
||
| ```bash | ||
| kubectl label managedcluster cluster1 cluster.open-cluster-management.io/clusterset=shared-cluster-set | ||
| kubectl label managedcluster cluster2 cluster.open-cluster-management.io/clusterset=shared-cluster-set | ||
| ``` |
There was a problem hiding this comment.
clusteradm has commands for both of these:
| ```yaml | |
| apiVersion: cluster.open-cluster-management.io/v1beta2 | |
| kind: ManagedClusterSet | |
| metadata: | |
| name: shared-cluster-set | |
| spec: | |
| clusterSelector: | |
| selectorType: ExclusiveClusterSetLabel | |
| ``` | |
| ```bash | |
| kubectl label managedcluster cluster1 cluster.open-cluster-management.io/clusterset=shared-cluster-set | |
| kubectl label managedcluster cluster2 cluster.open-cluster-management.io/clusterset=shared-cluster-set | |
| ``` | |
| clusteradm create clusterset shared-cluster-set | |
| clusteradm clusterset set shared-cluster-set --clusters cluster1,cluster2 |
This PR documents how to run multiple meshes on the same ClusterSet with separate control planes, hub namespace isolation, cert-manager trust chains and data-plane isolation via discoverySelectors.