change meta-service to statefulset and use storageClass as well
diff --git a/deploy/crds/cache_v1alpha1_broker_cr.yaml b/deploy/crds/cache_v1alpha1_broker_cr.yaml
index 7ed3aaa..2518720 100644
--- a/deploy/crds/cache_v1alpha1_broker_cr.yaml
+++ b/deploy/crds/cache_v1alpha1_broker_cr.yaml
@@ -21,7 +21,7 @@
   # size is the number of the broker cluster, each broker cluster contains a master broker and [slavePerGroup] slave brokers.
   size: 2
   # nameServers is the [ip:port] list of name service
-  nameServers: 192.168.130.33:9876;192.168.130.34:9876
+  nameServers: 192.168.130.33:9876
   # replicationMode is the broker slave sync mode, can be ASYNC or SYNC
   replicationMode: ASYNC
   # slavePerGroup is the number of each broker cluster
@@ -35,7 +35,7 @@
     - metadata:
         name: broker-storage
         annotations:
-          volume.beta.kubernetes.io/storage-class: rocketmq-broker-storage
+          volume.beta.kubernetes.io/storage-class: rocketmq-storage
       spec:
         accessModes: [ "ReadWriteOnce" ]
         resources:
diff --git a/deploy/crds/rocketmq_v1alpha1_metaservice_cr.yaml b/deploy/crds/rocketmq_v1alpha1_metaservice_cr.yaml
index d4fc0c8..d8f658b 100644
--- a/deploy/crds/rocketmq_v1alpha1_metaservice_cr.yaml
+++ b/deploy/crds/rocketmq_v1alpha1_metaservice_cr.yaml
@@ -24,3 +24,14 @@
   metaServiceImage: 2019liurui/rocketmq-namesrv:4.5.0-alpine
   # imagePullPolicy is the image pull policy
   imagePullPolicy: Always
+  # volumeClaimTemplates defines the storageClass
+  volumeClaimTemplates:
+    - metadata:
+        name: namesrv-storage
+        annotations:
+          volume.beta.kubernetes.io/storage-class: rocketmq-storage
+      spec:
+        accessModes: [ "ReadWriteOnce" ]
+        resources:
+          requests:
+            storage: 1Gi
diff --git a/deploy/crds/rocketmq_v1alpha1_metaservice_crd.yaml b/deploy/crds/rocketmq_v1alpha1_metaservice_crd.yaml
index c350dce..b8818d7 100644
--- a/deploy/crds/rocketmq_v1alpha1_metaservice_crd.yaml
+++ b/deploy/crds/rocketmq_v1alpha1_metaservice_crd.yaml
@@ -39,10 +39,16 @@
               description: Size is the number of the name service Pod
               format: int32
               type: integer
+            volumeClaimTemplates:
+              description: VolumeClaimTemplates defines the StorageClass
+              items:
+                type: object
+              type: array
           required:
           - size
           - metaServiceImage
           - imagePullPolicy
+          - volumeClaimTemplates
           type: object
         status:
           properties:
diff --git a/pkg/apis/rocketmq/v1alpha1/metaservice_types.go b/pkg/apis/rocketmq/v1alpha1/metaservice_types.go
index f4e7690..247a9f9 100644
--- a/pkg/apis/rocketmq/v1alpha1/metaservice_types.go
+++ b/pkg/apis/rocketmq/v1alpha1/metaservice_types.go
@@ -34,6 +34,8 @@
 	MetaServiceImage string `json:"metaServiceImage"`
 	// ImagePullPolicy defines how the image is pulled.
 	ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"`
+	// VolumeClaimTemplates defines the StorageClass
+	VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates"`
 }
 
 // MetaServiceStatus defines the observed state of MetaService
diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go
index 7df0d37..2a8f85c 100644
--- a/pkg/constants/constants.go
+++ b/pkg/constants/constants.go
@@ -31,6 +31,7 @@
 const StoreMountPath = "/home/rocketmq/store"
 const LogSubPathName = "logs"
 const StoreSubPathName = "store"
+const ContainerPortName9876  = "9876port"
 const ContainerPortName10909  = "10909port"
 const ContainerPortName10911  = "10911port"
 const ContainerPortName10912  = "10912port"
diff --git a/pkg/controller/metaservice/metaservice_controller.go b/pkg/controller/metaservice/metaservice_controller.go
index 7fabe66..146faf5 100644
--- a/pkg/controller/metaservice/metaservice_controller.go
+++ b/pkg/controller/metaservice/metaservice_controller.go
@@ -125,30 +125,30 @@
 		return reconcile.Result{}, err
 	}
 
-	// Check if the deployment already exists, if not create a new one
-	found := &appsv1.Deployment{}
+	// Check if the statefulSet already exists, if not create a new one
+	found := &appsv1.StatefulSet{}
 
-	dep := r.deploymentForMetaService(instance)
+	dep := r.statefulSetForMetaService(instance)
 	err = r.client.Get(context.TODO(), types.NamespacedName{Name: dep.Name, Namespace: dep.Namespace}, found)
 	if err != nil && errors.IsNotFound(err) {
 		err = r.client.Create(context.TODO(), dep)
 		if err != nil {
-			reqLogger.Error(err, "Failed to create new Deployment of MetaService", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
+			reqLogger.Error(err, "Failed to create new StatefulSet of MetaService", "StatefulSet.Namespace", dep.Namespace, "StatefulSet.Name", dep.Name)
 		}
-		// Deployment created successfully - return and requeue
+		// StatefulSet created successfully - return and requeue
 		return reconcile.Result{Requeue: true}, nil
 	} else if err != nil {
-		reqLogger.Error(err, "Failed to get MetaService Deployment.")
+		reqLogger.Error(err, "Failed to get MetaService StatefulSet.")
 	}
 
-	// Ensure the deployment size is the same as the spec
+	// Ensure the statefulSet size is the same as the spec
 	size := instance.Spec.Size
 	if *found.Spec.Replicas != size {
 		found.Spec.Replicas = &size
 		err = r.client.Update(context.TODO(), found)
 		reqLogger.Info("MetaService Updated")
 		if err != nil {
-			reqLogger.Error(err, "Failed to update Deployment.", "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name)
+			reqLogger.Error(err, "Failed to update StatefulSet.", "StatefulSet.Namespace", found.Namespace, "StatefulSet.Name", found.Name)
 			return reconcile.Result{}, err
 		}
 	}
@@ -160,7 +160,7 @@
 func (r *ReconcileMetaService) updateMetaServiceStatus(instance *rocketmqv1alpha1.MetaService, request reconcile.Request, requeue bool) (reconcile.Result, error){
 	reqLogger := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)
 	reqLogger.Info("Check the MetaServers status")
-	// List the pods for this metaService's deployment
+	// List the pods for this metaService's statefulSet
 	podList := &corev1.PodList{}
 	labelSelector := labels.SelectorFromSet(labelsForMetaService(instance.Name))
 	listOps := &client.ListOptions{
@@ -247,14 +247,14 @@
 	return map[string]string{"app": "meta_service", "meta_service_cr": name}
 }
 
-func (r *ReconcileMetaService) deploymentForMetaService(m *rocketmqv1alpha1.MetaService) *appsv1.Deployment {
+func (r *ReconcileMetaService) statefulSetForMetaService(m *rocketmqv1alpha1.MetaService) *appsv1.StatefulSet {
 	ls := labelsForMetaService(m.Name)
-	dep := &appsv1.Deployment{
+	dep := &appsv1.StatefulSet{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      m.Name,
 			Namespace: m.Namespace,
 		},
-		Spec: appsv1.DeploymentSpec{
+		Spec: appsv1.StatefulSetSpec{
 			Replicas: &m.Spec.Size,
 			Selector: &metav1.LabelSelector{
 				MatchLabels: ls,
@@ -273,33 +273,17 @@
 						ImagePullPolicy: m.Spec.ImagePullPolicy,
 						Ports: []corev1.ContainerPort{{
 							ContainerPort: 9876,
-							Name:          "9876port",
+							Name:          cons.ContainerPortName9876,
 						}},
 						VolumeMounts: []corev1.VolumeMount{{
-							MountPath: "/home/rocketmq/logs",
-							Name: "namesrvlogs",
-						},{
-							MountPath: "/home/rocketmq/store",
-							Name: "namesrvstore",
+							MountPath: cons.LogMountPath,
+							Name: m.Spec.VolumeClaimTemplates[0].Name,
+							SubPath: cons.LogSubPathName,
 						}},
 					}},
-					Volumes: []corev1.Volume{{
-						Name: "namesrvlogs",
-						VolumeSource: corev1.VolumeSource{
-							HostPath: &corev1.HostPathVolumeSource{
-								Path: "/data/namesrv/logs",
-							},
-						},
-					},{
-						Name: "namesrvstore",
-						VolumeSource: corev1.VolumeSource{
-							HostPath: &corev1.HostPathVolumeSource{
-								Path: "/data/namesrv/store",
-							},
-						},
-					}},
 				},
 			},
+			VolumeClaimTemplates: m.Spec.VolumeClaimTemplates,
 		},
 	}
 	// Set Broker instance as the owner and controller