This tutorial walks you through running a custom Go provider controller using multicluster-runtime instead of api-syncagent. You will publish a MongoDBCommunity API into kcp and use a custom controller to sync resources from consumer workspaces to a downstream Kubernetes cluster running the MongoDB Community Operator.
By the end of this tutorial, you will have:
::: warning Development preview The local setup is under active development. Commands and component versions may change. :::
Before you begin, make sure you have:
kubectl with the kubectl-kcp plugin installedFor background on when this path applies, see multicluster-runtime.
Consumers create MongoDBCommunity resources in their kcp workspace. A custom Go controller using multicluster-runtime watches all bound consumer workspaces, projects each resource onto the downstream cluster, and syncs selected status fields back.
The full source code is available in platform-mesh/example-mongodb-multiclusterruntime.
::: warning Minimal example This example is intentionally small. It does not cover object collisions, finalizer safety, related resources, multi-namespace placement, or production-grade error recovery. :::
Apply the APIResourceSchema and APIExport defined in the example repository:
KUBECONFIG=kcp.kubeconfig kubectl apply -f sample/mongo-api.yaml
This creates the mongodb-provider APIExport that consumer workspaces will bind to.
Clone the example and build the controller:
git clone https://github.com/platform-mesh/example-mongodb-multiclusterruntime.git
cd example-mongodb-multiclusterruntime
go build -o mongodb-controller .
Run the controller against your local kcp endpoint and the downstream cluster:
./mongodb-controller \
--kcp-kubeconfig=/path/to/kcp.kubeconfig \
--target-kubeconfig=/path/to/downstream.kubeconfig
The controller uses the kcp APIExport provider to discover all consumer workspaces that have bound to the MongoDB APIExport. Each reconcile request includes a cluster name identifying the workspace that produced the event.
In a consumer workspace that has an APIBinding to mongodb-provider, create a MongoDB resource:
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
name: my-database
namespace: default
spec:
members: 3
type: ReplicaSet
version: "6.0.5"
security:
authentication:
modes:
- SCRAM
users:
- name: admin
db: admin
passwordSecretRef:
name: admin-password
roles:
- name: clusterAdmin
db: admin
- name: userAdminAnyDatabase
db: admin
The controller detects the resource, creates a matching MongoDBCommunity object on the downstream cluster, and syncs selected status fields back to the consumer workspace.
On the downstream cluster, confirm the resource was created:
kubectl --kubeconfig /path/to/downstream.kubeconfig \
get mongodbcommunity --all-namespaces
Back in the consumer workspace, watch the status update:
KUBECONFIG=kcp.kubeconfig kubectl get mongodbcommunity my-database -n default -o yaml
Look for status.phase and status.version populated by the downstream operator.
You ran a custom Go controller that uses multicluster-runtime to span kcp consumer workspaces and a downstream Kubernetes cluster. Unlike api-syncagent, the controller decides explicitly how to map spec down, how to handle deletes, and which status fields to surface back. That control is the trade-off the multicluster-runtime path makes.
Continue with multicluster-runtime for the architecture and the full pattern comparison with api-syncagent.
Optional branches: