Skip to content

Add multi-tenancy guide#160

Open
sridhargaddam wants to merge 1 commit into
stolostron:mainfrom
sridhargaddam:add-multi-tenancy-doc
Open

Add multi-tenancy guide#160
sridhargaddam wants to merge 1 commit into
stolostron:mainfrom
sridhargaddam:add-multi-tenancy-doc

Conversation

@sridhargaddam

Copy link
Copy Markdown
Contributor

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.

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>
@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown

[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

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 7f92e7f4-23a8-4956-b234-b5994e3febcc

📥 Commits

Reviewing files that changed from the base of the PR and between 412885c and 2a4f638.

📒 Files selected for processing (2)
  • docs/design.md
  • docs/multi-tenancy.md

📝 Walkthrough

Walkthrough

Adds docs/multi-tenancy.md (288 lines), a new standalone guide covering how to run multiple MultiClusterMesh resources against the same ManagedClusterSet. Topics include control-plane namespace separation, cert-manager trust-chain setup per team, hub-namespace RBAC via Role/RoleBinding, data-plane isolation using Istio discoverySelectors, and controller conflict detection for namespace and operator-config collisions. docs/design.md gains a two-line pointer to this new guide.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • stolostron/multicluster-mesh-addon#93: Directly related — rewrites the "Cluster Selection and Multi-Tenancy" and collision/lifecycle sections in docs/design.md that this PR now extends with a dedicated guide.

Suggested labels

size/M

Suggested reviewers

  • yxun
🚥 Pre-merge checks | ✅ 9 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning Integration tests lack assertion messages on 24 Expect().To(Succeed()) calls, violating requirement 4. Many It blocks test multiple unrelated behaviors, violating requirement 1 (single responsibili... Add meaningful messages to all Expect() assertions (e.g., "failed to create operator ManifestWork"). Split multi-behavior It blocks into single-purpose tests (e.g., separate tests for ManifestWork creation vs label verification).
✅ Passed checks (9 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add multi-tenancy guide' directly and clearly describes the main change: adding documentation for multi-tenancy implementation.
Description check ✅ Passed The description accurately outlines the key multi-tenancy mechanisms covered (separate control planes, hub namespace isolation, cert-manager trust chains, discoverySelectors), matching the documentation additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All 76 Ginkgo test titles (It, Describe, Context, When) use static string literals with no dynamic identifiers, generated suffixes, timestamps, UUIDs, or variable interpolation.
No-Weak-Crypto ✅ Passed Documentation adds no weak crypto patterns (MD5, SHA-1, DES, RC4, 3DES, Blowfish, ECB). Only cryptographic algorithm mentioned is ECDSA-256 for cert-manager certificate generation, which is strong.
Container-Privileges ✅ Passed Documentation PR contains no container manifests with privileged: true, hostPID, hostNetwork, hostIPC, SYS_ADMIN capabilities, or allowPrivilegeEscalation: true settings.
No-Sensitive-Data-In-Logs ✅ Passed Documentation contains no hardcoded passwords, tokens, API keys, PII, or customer data; only example YAML with placeholder references.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Comment thread docs/multi-tenancy.md

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/multi-tenancy.md

Each Istio control plane discovers services across all namespaces by default. Configure `discoverySelectors` to restrict visibility to the mesh's own application namespaces:

```yaml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/multi-tenancy.md
kubectl label managedcluster cluster2 cluster.open-cluster-management.io/clusterset=shared-cluster-set
```

### Hub namespaces

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ManagedClusterSetBinding is not required for the add-on to function, though you may want one if using Placements alongside the mesh.

Comment thread docs/multi-tenancy.md
discoverySelectors:
- matchLabels:
mesh: team-a
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/multi-tenancy.md

### MultiClusterMesh resources

Team A — control plane in `istio-system-team-a`:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: em-dashes on lines 102 and 121. Replace with a colon or comma:

Suggested change
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.

Comment thread docs/multi-tenancy.md

### 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the renders fine in browsers but can be mangled in some terminals. Consider using -> instead.

Comment thread docs/multi-tenancy.md
Example RBAC for Team A:

```yaml
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. The Role is duplicated per namespace. You could define it once as a ClusterRole and bind it per namespace via RoleBinding. That's the standard pattern for reusable permission sets.

  2. This grants every member of team-a full 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.

Comment thread docs/multi-tenancy.md

Team A (`mesh-team-a`):

```yaml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/multi-tenancy.md
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/multi-tenancy.md
Comment on lines +29 to +42
```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
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clusteradm has commands for both of these:

Suggested change
```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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants