This example shows how to build a syncher which syncs objects from kcp workspaces into a separate Kubernetes cluster and afterwards syncs any status updates from the downstream object back into kcp. It includes a demo based on the MongoDB Community Operator.
It is a barebone example to show that you can build a custom syncher if api-syncagent is not sufficient for your use-cases. It should be noted that this example does not handle any object collisions or related resources. It is far from production ready!
Here is a high-level workflow for creation:
sequenceDiagram
participant M as k8s cluster with MongoDB Operator
participant O as This Operator
actor Y as You
participant CW as kcp Consumer Workspace
O ->> CW: watches
Y ->> CW: creates new MongoDB Object
CW ->> O: Syncs MongoDB object
O ->> M: Syncs MongoDB object
M ->> M: Creates Database and <br/> updates status of MongoDB object
M ->> O: Syncs back status
O ->> CW: Syncs back status
Y ->> CW: Retrieve new status
Here is a high-level workflow for deletion:
sequenceDiagram
participant M as k8s cluster with MongoDB Operator
participant O as This Operator
actor Y as You
participant CW as kcp Consumer Workspace
O ->> CW: watches
Y ->> CW: deletes their MongoDB
CW ->> O: Retrieves Info that object got deleted
O ->> M: Deletes Object
M ->> M: Deletes database
-
Run the script to create a kind cluster and deploy kcp and cert-manager
./hack/run-kcp-in-kind.sh
-
Deploy the MongoDB Operator in kind cluster
export KUBECONFIG="./kind.kubeconfig" helm repo add mongodb https://mongodb.github.io/helm-charts helm repo update helm upgrade \ --install \ --wait \ --namespace mongodb \ --create-namespace \ --version 0.13.0 \ mongodb mongodb/community-operator kubectl apply -f sample/mongo-secret.yaml
-
Create the
consumerandmongodbworkspaces in kcpexport KUBECONFIG="./kcp-admin.kubeconfig" kubectl create workspace consumer kubectl create workspace mongodb
-
Create the ResourceSchema, APIExport, APIBinding & MongoDB namespace
kubectl ws :root:mongodb kubectl apply -f sample/mongo-api.yaml kubectl ws :root:consumer kubectl apply -f sample/apibinding.yaml kubectl create namespace mongodb
-
Create the kcp kubeconfig for our controller
kubectl ws :root:mongodb kubectl config view --minify --flatten > kcp-controller.kubeconfig # set the server to the VirtualWorkspace url VW_URL="$(kubectl get apiexportendpointslices.apis.kcp.io mongodb -o jsonpath='{.status.endpoints[0].url}')" # In the kind setup kcp uses a short service name (kcp:<port>); rewrite it # to include the namespace (kcp.kcp:<port>) so the controller running in # a different namespace can reach it. VW_URL="${VW_URL//kcp:/kcp.kcp:}" kubectl --kubeconfig=kcp-controller.kubeconfig config set-cluster --insecure-skip-tls-verify=true "workspace.kcp.io/current" --server "${VW_URL}"
-
Switch back to the kind cluster and create a Secret with kubeconfig, then deploy the controller
export KUBECONFIG="./kind.kubeconfig" kubectl create secret generic --namespace="mongodb" kcp-kubeconfig --from-file=kubeconfig=kcp-controller.kubeconfig kubectl apply -f sample/deployment.yaml
[!NOTE] If you're using this sample Deployment in some other setup, remove
hostAliasesfrom the manifest. The providedhostAliasesis used to allow controller to connect to kcp in our kind setup wherekcp.dev.testis not a valid domain. -
Switch back to kcp and create a MongoDB in the
consumerworkspaceexport KUBECONFIG="./kcp-admin.kubeconfig" kubectl ws :root:consumer kubectl apply -f sample/mongodb.yaml
The syncer will sync the mongodb from kcp into the kubernetes cluster. After around a minute you should see in your Kubernetes cluster that the PHASE and VERSION field of your cluster are filled. The syncer will then sync this status into kcp. In the end, you should see the following in your kcp consumer workspace:
kubectl ws :root:consumer kubectl -n mongodb get mongodbcommunity.mongodbcommunity.mongodb.com example-mongodb NAME PHASE VERSION example-mongodb Running 6.0.5
-
Delete the object again
kubectl ws :root:consumer kubectl delete -f sample/mongodb.yaml
You should now see that the object disappears both in kcp as well as in the downstream cluster.
This project is open to feature requests/suggestions, bug reports etc. via GitHub issues. Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines.
If you find any bug that may be a security problem, please follow our instructions at in our security policy on how to report it. Please do not create GitHub issues for security-related doubts or problems.
Please refer to our Code of Conduct for information on the expected conduct for contributing to Platform Mesh.
