getting-started.md
February 9, 2026 · View on GitHub
# KubePlus
## Getting Started with an Example
Let’s look at an example of creating a multi-instance WordPress Service using KubePlus. The WordPress service provider goes through the following steps on their cluster.
**NOTE:**
If you have not set up KubePlus, follow the [Installation](../README.md#installation) steps to set up KubePlus.
Create the resourcecomposition instance and application CRD instances in the same namespace where KubePlus is deployed.
KubePlus will ignore creation of resourcecomposition instance and application CRD instances if other namespaces are used.
In the below steps, `KUBEPLUS_NS` is the namespace in which KubePlus is deployed.
### 1. Create Kubernetes CRD Representing WordPress Helm Chart
*The WordPress Helm chart can be specified as a [public URL](./examples/multitenancy/application-hosting/wordpress/wordpress-service-composition.yaml) or can be [available locally](./examples/multitenancy/application-hosting/wordpress/wordpress-service-composition-localchart.yaml).*
```sh
kubectl create -f https://raw.githubusercontent.com/cloud-ark/kubeplus/master/examples/multitenancy/application-hosting/wordpress/wordpress-service-composition.yaml --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
kubectl get resourcecomposition -n $KUBEPLUS_NS
kubectl describe resourcecomposition wordpress-service-composition -n $KUBEPLUS_NS
If the status of the wordpress-service-composition indicates that the new CRD has been created successfully, verify it:
kubectl get crds
You should see wordpressservices.platformapi.kubeplus CRD registered.
2. Create WordpressService Instance wp-tenant1
kubectl create -f https://raw.githubusercontent.com/cloud-ark/kubeplus/master/examples/multitenancy/application-hosting/wordpress/tenant1.yaml --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
3. Create WordpressService Instance wp-tenant2
kubectl create -f https://raw.githubusercontent.com/cloud-ark/kubeplus/master/examples/multitenancy/application-hosting/wordpress/tenant2.yaml --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
4. Check Created WordpressService Instances
kubectl get wordpressservices -n $KUBEPLUS_NS
NAME AGE
wp-tenant1 86s
wp-tenant2 26s
5. Check the Details of the Created Instance
kubectl describe wordpressservices wp-tenant1 -n $KUBEPLUS_NS
6. Check Created Application Resources
Notice that the WordpressService instance resources are deployed in a Namespace wp-tenant1, which was created by KubePlus.
kubectl appresources WordpressService wp-tenant1 -k kubeplus-saas-provider.json
NAMESPACE KIND NAME
default WordpressService wp-tenant1
wp-tenant1 PersistentVolumeClaim mysql-pv-claim
wp-tenant1 PersistentVolumeClaim wp-for-tenant1
wp-tenant1 Service wordpress-mysql
wp-tenant1 Service wp-for-tenant1
wp-tenant1 Deployment mysql
wp-tenant1 Deployment wp-for-tenant1
wp-tenant1 Pod mysql-76d6d9bdfd-2wl2p
wp-tenant1 Pod wp-for-tenant1-87c4c954-s2cct
wp-tenant1 NetworkPolicy allow-external-traffic
wp-tenant1 NetworkPolicy restrict-cross-ns-traffic
wp-tenant1 ResourceQuota wordpressservice-wp-tenant1
7. Check Application Resource Consumption
kubectl metrics WordpressService wp-tenant1 -k kubeplus-saas-provider.json
----------------------------------------------------------
Kubernetes Resources created:
Number of Sub-resources: -
Number of Pods: 2
Number of Containers: 2
Number of Nodes: 1
Number of Not Running Pods: 0
Underlying Physical Resources consumed:
Total CPU(cores): 0.773497m
Total MEMORY(bytes): 516.30859375Mi
Total Storage(bytes): 40Gi
Total Network bytes received: 0
Total Network bytes transferred: 0
----------------------------------------------------------
8. Cleanup
kubectl delete wordpressservice wp-tenant1 --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
kubectl delete wordpressservice wp-tenant2 --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
kubectl delete resourcecomposition wordpress-service-composition --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
helm delete kubeplus -n $KUBEPLUS_NS
python3 provider-kubeconfig.py delete $KUBEPLUS_NS
Network Isolation Testing
This section verifies that the network policies are correctly isolating application instances.
Steps
Install a Network Driver
On Minikube, install a network driver capable of recognizing NetworkPolicy objects (e.g., Cilium):
minikube start --cni=cilium
eval $(minikube docker-env)
Refer to Main README for Installing the KubePlus Operator and Plugins
Create HelloWorldService Instances
kubectl create -f examples/multitenancy/hello-world/hello-world-service-composition.yaml --kubeconfig=kubeplus-saas-provider.json
Wait for the HelloWorldService CRD to be registered:
until kubectl get crds --kubeconfig=kubeplus-saas-provider.json | grep helloworldservices.platformapi.kubeplus ; do echo "Waiting for HelloWorldService CRD to be registered.."; sleep 1; done
Then create the HelloWorldService instances:
kubectl create -f examples/multitenancy/hello-world/hs1.yaml --kubeconfig=kubeplus-saas-provider.json
kubectl create -f examples/multitenancy/hello-world/hs2.yaml --kubeconfig=kubeplus-saas-provider.json
Test Network Isolation
-
Ping/HTTP Test from
hs1tohs2:# Get the Pod name for hs1 HELLOWORLD_POD_HS1=$(kubectl get pods -n hs1 --kubeconfig=kubeplus-saas-provider.json -o jsonpath='{.items[0].metadata.name}') # Get the Pod IP for hs2 HS2_POD_IP=$(kubectl get pods -n hs2 --kubeconfig=kubeplus-saas-provider.json -o jsonpath='{.items[0].status.podIP}') # Update and install curl on hs1 pod kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=kubeplus-saas-provider.json -- apt update kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=kubeplus-saas-provider.json -- apt install curl -y # Test connectivity from hs1 to hs2 using the IP kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=kubeplus-saas-provider.json -- curl $HS2_POD_IP:5000The connection should be denied.
-
Ping/HTTP Test from
hs2tohs1:# Get the Pod name for hs2 HELLOWORLD_POD_HS2=$(kubectl get pods -n hs2 --kubeconfig=kubeplus-saas-provider.json -o jsonpath='{.items[0].metadata.name}') # Get the Pod IP for hs1 HS1_POD_IP=$(kubectl get pods -n hs1 --kubeconfig=kubeplus-saas-provider.json -o jsonpath='{.items[0].status.podIP}') # Update and install curl on hs2 pod kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=kubeplus-saas-provider.json -- apt update kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=kubeplus-saas-provider.json -- apt install curl -y # Test connectivity from hs2 to hs1 using the IP kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=kubeplus-saas-provider.json -- curl $HS1_POD_IP:5000The connection should be denied.
Allowing Cross Namespace Traffic
In some scenarios, you might want to enable controlled communication between instances running in different namespaces. KubePlus provides a custom kubectl plugin for this purpose. To allow bi-directional traffic between the two HelloWorldService instances (deployed in namespaces hs1 and hs2), run:
kubectl allow network traffic hs1 hs2 -k kubeplus-saas-provider.json
# Test connectivity from hs1 to hs2 using the IP
kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=kubeplus-saas-provider.json -- curl $HS2_POD_IP:5000
# Test connectivity from hs2 to hs1 using the IP
kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=kubeplus-saas-provider.json -- curl $HS1_POD_IP:5000
kubectl get networkpolicy -o yaml restrict-cross-ns-traffic -n hs1
kubectl get networkpolicy -o yaml restrict-cross-ns-traffic -n hs2
You should see that each policy’s ingress section now includes a rule that uses a namespaceSelector matching the other namespace (using the label kubernetes.io/metadata.name).
The connection should be allowed
To deny the traffic between namespace
kubectl deny network traffic hs1 hs2 -k kubeplus-saas-provider.json
# Test connectivity from hs1 to hs2 using the IP
kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=kubeplus-saas-provider.json -- curl $HS2_POD_IP:5000
# Test connectivity from hs2 to hs1 using the IP
kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=kubeplus-saas-provider.json -- curl $HS1_POD_IP:5000
Clean Up
kubectl delete -f examples/multitenancy/hello-world/hs1-no-replicas.yaml --kubeconfig=kubeplus-saas-provider.json
kubectl delete -f examples/multitenancy/hello-world/hs2-no-replicas.yaml --kubeconfig=kubeplus-saas-provider.json
kubectl delete -f examples/multitenancy/hello-world/hello-world-service-composition.yaml --kubeconfig=kubeplus-saas-provider.json
Ensure the helloworldservices.platformapi.kubeplus CRD is removed.