# 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.
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
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
kubectl get wordpressservices -n $KUBEPLUS_NS
NAME AGE
wp-tenant1 86s
wp-tenant2 26s
kubectl describe wordpressservices wp-tenant1 -n $KUBEPLUS_NS
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
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
----------------------------------------------------------
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
This section verifies that the network policies are correctly isolating application instances.
On Minikube, install a network driver capable of recognizing NetworkPolicy
objects (e.g., Cilium):
minikube start --cni=cilium
eval $(minikube docker-env)
kubectl create -f hello-world-service-composition.yaml --kubeconfig=provider.conf
kubectl create -f hs1.yaml --kubeconfig=provider.conf
kubectl create -f hs2.yaml --kubeconfig=provider.conf
-
Ping/HTTP Test from
hs1
tohs2
:# Get the Pod name for hs1 HELLOWORLD_POD_HS1=$(kubectl get pods -n hs1 --kubeconfig=provider.conf -o jsonpath='{.items[0].metadata.name}') # Get the Pod IP for hs2 HS2_POD_IP=$(kubectl get pods -n hs2 --kubeconfig=provider.conf -o jsonpath='{.items[0].status.podIP}') # Update and install curl on hs1 pod kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=provider.conf -- apt update kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=provider.conf -- apt install curl -y # Test connectivity from hs1 to hs2 using the IP kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=provider.conf -- curl $HS2_POD_IP:5000
The connection should be denied.
-
Ping/HTTP Test from
hs2
tohs1
:# Get the Pod name for hs2 HELLOWORLD_POD_HS2=$(kubectl get pods -n hs2 --kubeconfig=provider.conf -o jsonpath='{.items[0].metadata.name}') # Get the Pod IP for hs1 HS1_POD_IP=$(kubectl get pods -n hs1 --kubeconfig=provider.conf -o jsonpath='{.items[0].status.podIP}') # Update and install curl on hs2 pod kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=provider.conf -- apt update kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=provider.conf -- apt install curl -y # Test connectivity from hs2 to hs1 using the IP kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=provider.conf -- curl $HS1_POD_IP:5000
The connection should be denied.
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 provider.conf
# Test connectivity from hs1 to hs2 using the IP
kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=provider.conf -- curl $HS2_POD_IP:5000
# Test connectivity from hs2 to hs1 using the IP
kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=provider.conf -- 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 provider.conf
# Test connectivity from hs1 to hs2 using the IP
kubectl exec -it $HELLOWORLD_POD_HS1 -n hs1 --kubeconfig=provider.conf -- curl $HS2_POD_IP:5000
# Test connectivity from hs2 to hs1 using the IP
kubectl exec -it $HELLOWORLD_POD_HS2 -n hs2 --kubeconfig=provider.conf -- curl $HS1_POD_IP:5000
kubectl delete -f hs1-no-replicas.yaml --kubeconfig=provider.conf
kubectl delete -f hs2-no-replicas.yaml --kubeconfig=provider.conf
kubectl delete -f hello-world-service-composition.yaml --kubeconfig=provider.conf
Ensure the helloworldservices.platformapi.kubeplus
CRD is removed.