[ISSUE #16] [ISSUE #27] [ISSUE #32] Open Resource Limit and HostNetwork Configurations in CRD  (#33)

* feat(nameserver): exposure hostNetwork and DNSPolicy

* feat(*): exposure resource limit and adapted to yoda

* recover(*): recover subPath

* feat(images): use root user in nameserver and broker images and open resource limit in CRD

* docs(README): change default name server hostNetwork description

* fix(name server): open dnsPolicy in name server CRD

* fix(name server): fix crd

* fix(go.mod): fix mod

* fix(images): fix rocketmq release download address

* fix(images): fix docker repo

Co-authored-by: liurui <liurui@B-R2T6MD6M-0047.local>
diff --git a/README.md b/README.md
index 5a616c2..e82c4ab 100644
--- a/README.md
+++ b/README.md
@@ -68,40 +68,34 @@
 
 Before RocketMQ deployment, you may need to do some preparation steps for RocketMQ data persistence. 
 
-Currently we provide several options for your RocketMQ data persistence: ```EmptyDir```, ```HostPath``` and ```NFS```, which can be configured in CR files, for example in ```rocketmq_v1alpha1_nameservice_cr.yaml```:
+Currently we provide several options for your RocketMQ data persistence: ```EmptyDir```, ```HostPath``` and ```StorageClass```, which can be configured in CR files, for example in ```rocketmq_v1alpha1_nameservice_cr.yaml```:
 
 ```
 ...
- # storageMode can be EmptyDir, HostPath, NFS
+ # storageMode can be EmptyDir, HostPath, StorageClass
   storageMode: HostPath
 ...
 ```
 
+#### EmptyDir
+
 If you choose ```EmptyDir```, you don't need to do extra preparation steps for data persistence. But the data storage life is the same with the pod's life, if the pod is deleted you may lost the data.
 
 If you choose other storage modes, please refer to the following instructions to prepare the data persistence.
 
-#### Prepare HostPath
+#### HostPath
 
-This storage mode means the RocketMQ data (including all the logs and store files) is stored in each host where the pod lies on. In that case you need to create an dir where you want the RocketMQ data to be stored on. 
-
-We provide a script in ```deploy/storage/hostpath/prepare-host-path.sh```, which you can use to create the ```HostPath``` dir on every worker node of your Kubernetes cluster. 
+This storage mode means the RocketMQ data (including all the logs and store files) is stored in each host where the pod lies on. You need to create a directory on the host where you want the RocketMQ data to be stored. For example:
 
 ```
-$ cd deploy/storage/hostpath
-
-$ sudo su
-
-$ ./prepare-hostpath.sh 
-Changed hostPath /data/rocketmq/nameserver uid to 3000, gid to 3000
-Changed hostPath /data/rocketmq/broker uid to 3000, gid to 3000
+$ mkdir /data/rocketmq/broker
 ```
 
-You may refer to the instructions in the script for more information.
+You can configure the host path in the CRD yaml file like ```hostPath: /data/rocketmq/broker``` in the ```example/rocketmq_v1alpha1_rocketmq_cluster.yaml``` file.
 
-#### Prepare Storage Class of NFS
+#### StorageClass (Use NFS for Example)
 
-If you choose NFS as the storage mode, the first step is to prepare a storage class based on NFS provider to create PV and PVC where the RocketMQ data will be stored. 
+If you choose StorageClass as the storage mode, you need to prepare the storage class related provisioner and other dependencies. Using the NFS storage class as an example, the first step is to prepare a storage class based on NFS provider to create PV and PVC where the RocketMQ data will be stored. 
 
 1. Deploy NFS server and clients on your Kubernetes cluster. You can refer to [NFS deployment document](docs/en/nfs_install_en.md) for more details. Please make sure they are functional before you go to the next step. Here is a instruction on how to verify NFS service.
 
@@ -163,9 +157,55 @@
 
 RocketMQ Operator provides several CRDs to allow users define their RocketMQ service component cluster, which includes the Name Server cluster and the Broker cluster.
 
-1. Check the file ```rocketmq_v1alpha1_nameservice_cr.yaml``` in the ```example``` directory, for example:
+1. Check the file ```rocketmq_v1alpha1_rocketmq_cluster.yaml``` in the ```example``` directory, for example:
 ```
 apiVersion: rocketmq.apache.org/v1alpha1
+kind: Broker
+metadata:
+  # name of broker cluster
+  name: broker
+spec:
+  # size is the number of the broker cluster, each broker cluster contains a master broker and [replicaPerGroup] replica brokers.
+  size: 1
+  # nameServers is the [ip:port] list of name service
+  nameServers: ""
+  # replicationMode is the broker replica sync mode, can be ASYNC or SYNC
+  replicationMode: ASYNC
+  # replicaPerGroup is the number of each broker cluster
+  replicaPerGroup: 1
+  # brokerImage is the customized docker image repo of the RocketMQ broker
+  brokerImage: apacherocketmq/rocketmq-broker:4.5.0-alpine
+  # imagePullPolicy is the image pull policy
+  imagePullPolicy: Always
+  # resources describes the compute resource requirements and limits
+  resources:
+    requests:
+      memory: "2048Mi"
+      cpu: "250m"
+    limits:
+      memory: "4096Mi"
+      cpu: "500m"
+  # allowRestart defines whether allow pod restart
+  allowRestart: true
+  # storageMode can be EmptyDir, HostPath, StorageClass
+  storageMode: EmptyDir
+  # hostPath is the local path to store data
+  hostPath: /data/rocketmq/broker
+  # scalePodName is broker-[broker group number]-master-0
+  scalePodName: broker-0-master-0
+  # volumeClaimTemplates defines the storageClass
+  volumeClaimTemplates:
+    - metadata:
+        name: broker-storage
+      spec:
+        accessModes:
+          - ReadWriteOnce
+        storageClassName: rocketmq-storage
+        resources:
+          requests:
+            storage: 8Gi
+---
+apiVersion: rocketmq.apache.org/v1alpha1
 kind: NameService
 metadata:
   name: name-service
@@ -176,128 +216,90 @@
   nameServiceImage: apacherocketmq/rocketmq-namesrv:4.5.0-alpine
   # imagePullPolicy is the image pull policy
   imagePullPolicy: Always
-  # storageMode can be EmptyDir, HostPath, NFS
-  storageMode: HostPath
+  # hostNetwork can be true or false
+  hostNetwork: true
+  #  Set DNS policy for the pod.
+  #  Defaults to "ClusterFirst".
+  #  Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'.
+  #  DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy.
+  #  To have DNS options set along with hostNetwork, you have to specify DNS policy
+  #  explicitly to 'ClusterFirstWithHostNet'.
+  dnsPolicy: ClusterFirstWithHostNet
+  # resources describes the compute resource requirements and limits
+  resources:
+    requests:
+      memory: "512Mi"
+      cpu: "250m"
+    limits:
+      memory: "1024Mi"
+      cpu: "500m"
+  # storageMode can be EmptyDir, HostPath, StorageClass
+  storageMode: EmptyDir
   # hostPath is the local path to store data
   hostPath: /data/rocketmq/nameserver
   # volumeClaimTemplates defines the storageClass
   volumeClaimTemplates:
     - metadata:
         name: namesrv-storage
-        annotations:
-          volume.beta.kubernetes.io/storage-class: rocketmq-storage
       spec:
-        accessModes: [ "ReadWriteOnce" ]
+        accessModes:
+          - ReadWriteOnce
+        storageClassName: rocketmq-storage
         resources:
           requests:
             storage: 1Gi
 ```
 
-which defines the RocketMQ name service (name server) cluster scale.
-
-2. Check the file ```rocketmq_v1alpha1_broker_cr.yaml``` in the ```example``` directory, for example:
-```
-apiVersion: rocketmq.apache.org/v1alpha1
-kind: Broker
-metadata:
-  # name of broker cluster
-  name: broker
-spec:
-  # size is the number of the broker cluster, each broker cluster contains a master broker and [replicaPerGroup] replica brokers.
-  size: 2
-  # nameServers is the [ip:port] list of name service
-  nameServers: ""
-  # replicationMode is the broker replica sync mode, can be ASYNC or SYNC
-  replicationMode: ASYNC
-  # replicaPerGroup is the number of replica broker in each group
-  replicaPerGroup: 1
-  # brokerImage is the customized docker image repo of the RocketMQ broker
-  brokerImage: apacherocketmq/rocketmq-broker:4.5.0-alpine
-  # imagePullPolicy is the image pull policy
-  imagePullPolicy: Always
-  # allowRestart defines whether allow pod restart
-  allowRestart: true
-  # storageMode can be EmptyDir, HostPath, NFS
-  storageMode: HostPath
-  # hostPath is the local path to store data
-  hostPath: /data/rocketmq/broker
-  # scalePodName is broker-[broker group number]-master-0
-  scalePodName: broker-0-master-0
-  # volumeClaimTemplates defines the storageClass
-  volumeClaimTemplates:
-    - metadata:
-        name: broker-storage
-        annotations:
-          volume.beta.kubernetes.io/storage-class: rocketmq-storage
-      spec:
-        accessModes: [ "ReadWriteOnce" ]
-        resources:
-          requests:
-            storage: 8Gi
-``` 
-which defines the RocketMQ broker cluster scale, the [ip:port] list of name service and so on. By default, the nameServers is an empty string which means it is automatically obtained by the operator.
+which defines the RocketMQ name server cluster and the broker cluster scale, the [ip:port] list of name service and so on. By default, the nameServers is an empty string which means it is automatically obtained by the operator.
 
 ### Create RocketMQ Cluster
 
 1. Deploy the RocketMQ name service cluster by running:
 
 ``` 
-$ kubectl apply -f example/rocketmq_v1alpha1_nameservice_cr.yaml 
+$ kubectl apply -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
+broker.rocketmq.apache.org/broker created
 nameservice.rocketmq.apache.org/name-service created
 ```
 
+The name server cluster will be created first, after all name server cluster is in running state, the operator will create the broker cluster.
+
 Check the status:
 
 ```
 $ kubectl get pods -owide
-NAME                                      READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
-name-service-0                            1/1     Running   0          3m18s   192.168.130.33   k2data-13   <none>           <none>
-nfs-client-provisioner-7cf858f754-7vxmm   1/1     Running   0          150m    10.244.2.114     k2data-14   <none>           <none>
-rocketmq-operator-564b5d75d-jllzk         1/1     Running   0          5m53s   10.244.2.116     k2data-14   <none>           <none>
+NAME                                 READY   STATUS    RESTARTS   AGE     IP             NODE             NOMINATED NODE   READINESS GATES
+broker-0-master-0                    1/1     Running   0          27s     10.1.2.27      docker-desktop   <none>           <none>
+broker-0-replica-1-0                 1/1     Running   0          27s     10.1.2.28      docker-desktop   <none>           <none>
+name-service-0                       1/1     Running   0          27s     192.168.65.3   docker-desktop   <none>           <none>
+rocketmq-operator-76b4b9f4db-x52mz   1/1     Running   0          3h25m   10.1.2.17      docker-desktop   <none>           <none>
 ```
 
-We can see We can see that there are 1 name service Pod running on 1 node.
+Using the default yaml, we can see that there are 2 name server Pods and 1 master broker 1 replica(slave) broker running on the k8s cluster.
 
-2. Deploy the RocketMQ broker clusters by running:
+2. By default, the name server cluster is using host network ip(because ```hostNetwork: true```). If you set ```hostNetwork: true```, and need tp exposure the name server cluster to the outside, you can use the Service:
+
 ```
-$ kubectl apply -f example/rocketmq_v1alpha1_broker_cr.yaml
-broker.rocketmq.apache.org/broker created 
+$ kubectl apply -f example/rocketmq_cluster_service.yaml
+service/rocketmq-service created
 ```
 
-After a while the Broker Containers will be created, the Kubernetes clusters status should be like:
-
-``` 
-$ kubectl get pods -owide
-NAME                                      READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
-broker-0-master-0                         1/1     Running   0          38s     10.244.4.18      k2data-11   <none>           <none>
-broker-0-replica-1-0                      1/1     Running   0          38s     10.244.1.128     k2data-13   <none>           <none>
-broker-1-master-0                         1/1     Running   0          38s     10.244.2.117     k2data-14   <none>           <none>
-broker-1-replica-1-0                      1/1     Running   0          38s     10.244.3.17      k2data-15   <none>           <none>
-name-service-0                            1/1     Running   0          6m7s    192.168.130.33   k2data-13   <none>           <none>
-nfs-client-provisioner-7cf858f754-7vxmm   1/1     Running   0          153m    10.244.2.114     k2data-14   <none>           <none>
-rocketmq-operator-564b5d75d-jllzk         1/1     Running   0          8m42s   10.244.2.116     k2data-14   <none>           <none>
-```
-
-3. Check the PV and PVC status:
+3. If you are using storage class, check the PV and PVC status:
 ```
 $ kubectl get pvc
 NAME                                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
 broker-storage-broker-0-master-0        Bound    pvc-7a74871b-c005-441a-bb15-8106566c9d19   8Gi        RWO            rocketmq-storage   78s
 broker-storage-broker-0-replica-1-0     Bound    pvc-521e7e9a-3795-487a-9f76-22da74db74dd   8Gi        RWO            rocketmq-storage   78s
-broker-storage-broker-1-master-0        Bound    pvc-d7b76efe-384c-4f8d-9e8a-ebe209ba826c   8Gi        RWO            rocketmq-storage   78s
-broker-storage-broker-1-replica-1-0     Bound    pvc-af266db9-83a9-4929-a2fe-e40fb5fdbfa4   8Gi        RWO            rocketmq-storage   78s
 namesrv-storage-name-service-0          Bound    pvc-c708cb49-aa52-4992-8cac-f46a48e2cc2e   1Gi        RWO            rocketmq-storage   79s
 
 $ kubectl get pv
 NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                       STORAGECLASS       REASON   AGE
 pvc-521e7e9a-3795-487a-9f76-22da74db74dd   8Gi        RWO            Delete           Bound    default/broker-storage-broker-0-replica-1-0 rocketmq-storage            79s
 pvc-7a74871b-c005-441a-bb15-8106566c9d19   8Gi        RWO            Delete           Bound    default/broker-storage-broker-0-master-0    rocketmq-storage            79s
-pvc-af266db9-83a9-4929-a2fe-e40fb5fdbfa4   8Gi        RWO            Delete           Bound    default/broker-storage-broker-1-replica-1-0 rocketmq-storage            78s
-pvc-c708cb49-aa52-4992-8cac-f46a48e2cc2e   1Gi        RWO            Delete           Bound    default/namesrv-storage-name-service-0      rocketmq-storage            79s
 pvc-d7b76efe-384c-4f8d-9e8a-ebe209ba826c   8Gi        RWO            Delete           Bound    default/broker-storage-broker-1-master-0    rocketmq-storage            78s
 ```
 
-> Notice: if you don't choose the NFS storage mode, then the above PV and PVC won't be created.
+> Notice: if you don't choose the StorageClass storage mode, then the above PV and PVC won't be created.
 
 Congratulations! You have successfully deployed your RocketMQ cluster by RocketMQ Operator.
 
@@ -322,14 +324,14 @@
 $ cd /data/k8s/
 
 $ ls
-default-broker-storage-broker-0-master-0-pvc-7a74871b-c005-441a-bb15-8106566c9d19   default-broker-storage-broker-1-replica-1-0-pvc-af266db9-83a9-4929-a2fe-e40fb5fdbfa4
-default-broker-storage-broker-0-replica-1-0-pvc-521e7e9a-3795-487a-9f76-22da74db74dd  default-namesrv-storage-name-service-0-pvc-c708cb49-aa52-4992-8cac-f46a48e2cc2e
-default-broker-storage-broker-1-master-0-pvc-d7b76efe-384c-4f8d-9e8a-ebe209ba826c
+default-broker-storage-broker-0-master-0-pvc-7a74871b-c005-441a-bb15-8106566c9d19   
+default-broker-storage-broker-0-replica-1-0-pvc-521e7e9a-3795-487a-9f76-22da74db74dd  
+default-namesrv-storage-name-service-0-pvc-c708cb49-aa52-4992-8cac-f46a48e2cc2e
 
-$ ls default-broker-storage-broker-1-master-0-pvc-d7b76efe-384c-4f8d-9e8a-ebe209ba826c/logs/rocketmqlogs/
+$ ls default-broker-storage-broker-0-master-0-pvc-7a74871b-c005-441a-bb15-8106566c9d19/logs/rocketmqlogs/
 broker_default.log  broker.log  commercial.log  filter.log  lock.log  protection.log  remoting.log  stats.log  storeerror.log  store.log  transaction.log  watermark.log
 
-$ cat default-broker-storage-broker-1-master-0-pvc-d7b76efe-384c-4f8d-9e8a-ebe209ba826c/logs/rocketmqlogs/broker.log 
+$ cat default-broker-storage-broker-0-master-0-pvc-7a74871b-c005-441a-bb15-8106566c9d19/logs/rocketmqlogs/broker.log 
 ...
 2019-09-10 14:12:22 INFO main - The broker[broker-1-master-0, 10.244.2.117:10911] boot success. serializeType=JSON and name server is 192.168.130.33:9876
 ...
@@ -369,7 +371,7 @@
 
 3. Apply the new configurations:
 ```
-kubectl apply -f example/rocketmq_v1alpha1_broker_cr.yaml
+$ kubectl apply -f example/rocketmq_v1alpha1_broker_cr.yaml
 ```
 Then a new broker group of pods will be deployed and meanwhile the operator will copy the metadata from the source broker pod to the newly created broker pods before the new brokers are stared, so the new brokers will reload previous topic and subscription information.
 
@@ -431,16 +433,11 @@
 
 ## Clean the Environment
 
-If you want to tear down the RocketMQ cluster, to remove the broker clusters run
+If you want to tear down the RocketMQ cluster, to remove the name server and broker clusters run
 
 ```
-$ kubectl delete -f example/rocketmq_v1alpha1_broker_cr.yaml
-```
-
-to remove the name service clusters:
-
-```
-$ kubectl delete -f example/rocketmq_v1alpha1_nameservice_cr.yaml
+$ kubectl delete -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
+$ kubectl delete -f example/rocketmq_cluster_service.yaml
 ```
 
 to remove the RocketMQ Operator:
@@ -456,7 +453,7 @@
 $ ./remove-storage-class.sh
 ```
 
-> Note: the NFS and HostPath persistence data will not be deleted by default.
+> Note: the StorageClass and HostPath persistence data will not be deleted by default.
 
 ## Development
 
@@ -491,12 +488,12 @@
 You can also modify the ```DOCKERHUB_REPO``` variable in the scripts to push the newly build images to your own repository:
 
 ```
-$ cd images/broker
+$ cd images/alpine/broker
 $ ./build-broker-image.sh
 ```
 
 ```
-$ cd images/namesrv
+$ cd images/alpine/namesrv
 $ ./build-namesrv-image.sh
 ```
 
diff --git a/create-operator.sh b/create-operator.sh
index b589ad4..8a21106 100755
--- a/create-operator.sh
+++ b/create-operator.sh
@@ -18,7 +18,7 @@
 set -eux;
 
 # You can change the DOCKERHUB_REPO to your docker repo for development purpose
-DOCKERHUB_REPO="apacherocketmq/rocketmq-operator:0.2.1"
+DOCKERHUB_REPO="apacherocketmq/rocketmq-operator:0.2.1-snapshot"
 # The version of RocketMQ including the Admin Tool
 ROCKETMQ_VERSION="4.5.0"
 
diff --git a/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml b/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml
index 01ec2d6..a85bbf4 100644
--- a/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml
+++ b/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml
@@ -33,13 +33,13 @@
               description: AllowRestart defines whether allow pod restart
               type: boolean
             brokerImage:
-              description: BaseImage is the broker image to use for the Pods.
+              description: BaseImage is the broker image to use for the Pods
               type: string
             hostPath:
               description: HostPath is the local path to store data
               type: string
             imagePullPolicy:
-              description: ImagePullPolicy defines how the image is pulled.
+              description: ImagePullPolicy defines how the image is pulled
               type: string
             nameServers:
               description: NameServers defines the name service list e.g. 192.168.1.1:9876;192.168.1.2:9876
@@ -51,6 +51,9 @@
             replicationMode:
               description: ReplicationMode is SYNC or ASYNC
               type: string
+            resources:
+              description: Resources describes the compute resource requirements
+              type: object
             scalePodName:
               description: The name of pod where the metadata from
               type: string
@@ -62,7 +65,7 @@
               format: int64
               type: integer
             storageMode:
-              description: StorageMode can be EmptyDir, HostPath, NFS
+              description: StorageMode can be EmptyDir, HostPath, StorageClass
               type: string
             volumeClaimTemplates:
               description: VolumeClaimTemplates defines the StorageClass
@@ -75,6 +78,7 @@
           - brokerImage
           - imagePullPolicy
           - allowRestart
+          - resources
           - storageMode
           - hostPath
           - volumeClaimTemplates
diff --git a/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml b/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml
index 10a82c1..437ce04 100644
--- a/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml
+++ b/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml
@@ -29,6 +29,12 @@
           type: object
         spec:
           properties:
+            dnsPolicy:
+              description: dnsPolicy defines how a pod's DNS will be configured
+              type: string
+            hostNetwork:
+              description: HostNetwork can be true or false
+              type: boolean
             hostPath:
               description: HostPath is the local path to store data
               type: string
@@ -38,6 +44,9 @@
             nameServiceImage:
               description: NameServiceImage is the name service image
               type: string
+            resources:
+              description: Resources describes the compute resource requirements
+              type: object
             size:
               description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
                 Important: Run "operator-sdk generate k8s" to regenerate code after
@@ -58,6 +67,9 @@
           - size
           - nameServiceImage
           - imagePullPolicy
+          - hostNetwork
+          - dnsPolicy
+          - resources
           - storageMode
           - hostPath
           - volumeClaimTemplates
diff --git a/deploy/operator.yaml b/deploy/operator.yaml
index c096ad3..2f62851 100644
--- a/deploy/operator.yaml
+++ b/deploy/operator.yaml
@@ -31,7 +31,7 @@
       containers:
         - name: rocketmq-operator
           # Replace this with the built image name
-          image: apacherocketmq/rocketmq-operator:0.2.1
+          image: apacherocketmq/rocketmq-operator:0.2.1-snapshot
           command:
           - rocketmq-operator
           imagePullPolicy: Always
diff --git a/docs/cn/README.md b/docs/cn/README.md
index eee417b..2444f18 100644
--- a/docs/cn/README.md
+++ b/docs/cn/README.md
@@ -167,7 +167,7 @@
   # size is the the name service instance number of the name service cluster
   size: 1
   # nameServiceImage is the customized docker image repo of the RocketMQ name service
-  nameServiceImage: rocketmqinc/rocketmq-namesrv:4.5.0-alpine
+  nameServiceImage: apacherocketmq/rocketmq-namesrv:4.5.0-alpine
   # imagePullPolicy is the image pull policy
   imagePullPolicy: Always
   # storageMode can be EmptyDir, HostPath, NFS
@@ -205,7 +205,7 @@
   # replicaPerGroup is the number of replica broker in each group
   replicaPerGroup: 1
   # brokerImage is the customized docker image repo of the RocketMQ broker
-  brokerImage: rocketmqinc/rocketmq-broker:4.5.0-alpine
+  brokerImage: apacherocketmq/rocketmq-broker:4.5.0-alpine
   # imagePullPolicy is the image pull policy
   imagePullPolicy: Always
   # allowRestart defines whether allow pod restart
diff --git a/example/rocketmq_v1alpha1_broker_cr.yaml b/example/rocketmq_v1alpha1_broker_cr.yaml
index 44b37a7..1de157e 100644
--- a/example/rocketmq_v1alpha1_broker_cr.yaml
+++ b/example/rocketmq_v1alpha1_broker_cr.yaml
@@ -28,13 +28,21 @@
   # replicaPerGroup is the number of each broker cluster
   replicaPerGroup: 1
   # brokerImage is the customized docker image repo of the RocketMQ broker
-  brokerImage: rocketmqinc/rocketmq-broker:4.5.0-alpine
+  brokerImage: apacherocketmq/rocketmq-broker:4.5.0-alpine
   # imagePullPolicy is the image pull policy
   imagePullPolicy: Always
+  # resources describes the compute resource requirements and limits
+  resources:
+    requests:
+      memory: "2048Mi"
+      cpu: "250m"
+    limits:
+      memory: "4096Mi"
+      cpu: "500m"
   # allowRestart defines whether allow pod restart
   allowRestart: true
-  # storageMode can be EmptyDir, HostPath, NFS
-  storageMode: EmptyDir
+  # storageMode can be EmptyDir, HostPath, StorageClass
+  storageMode: HostPath
   # hostPath is the local path to store data
   hostPath: /data/rocketmq/broker
   # scalePodName is broker-[broker group number]-master-0
diff --git a/example/rocketmq_v1alpha1_cluster_service.yaml b/example/rocketmq_v1alpha1_cluster_service.yaml
new file mode 100644
index 0000000..479d3d8
--- /dev/null
+++ b/example/rocketmq_v1alpha1_cluster_service.yaml
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: rocketmq-service
+  namespace: default
+spec:
+  type: NodePort
+  selector:
+    name_service_cr: name-service
+  ports:
+    - port: 9876
+      targetPort: 9876
+      # use this port to access the name server cluster
+      nodePort: 30080
diff --git a/example/rocketmq_v1alpha1_nameservice_cr.yaml b/example/rocketmq_v1alpha1_nameservice_cr.yaml
index 75c4a65..4c2c178 100644
--- a/example/rocketmq_v1alpha1_nameservice_cr.yaml
+++ b/example/rocketmq_v1alpha1_nameservice_cr.yaml
@@ -21,11 +21,28 @@
   # size is the the name service instance number of the name service cluster
   size: 1
   # nameServiceImage is the customized docker image repo of the RocketMQ name service
-  nameServiceImage: rocketmqinc/rocketmq-namesrv:4.5.0-alpine
+  nameServiceImage: apacherocketmq/rocketmq-namesrv:4.5.0-alpine
   # imagePullPolicy is the image pull policy
   imagePullPolicy: Always
-  # storageMode can be EmptyDir, HostPath, NFS
-  storageMode: EmptyDir
+  # hostNetwork can be true or false
+  hostNetwork: true
+  #  Set DNS policy for the pod.
+  #  Defaults to "ClusterFirst".
+  #  Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'.
+  #  DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy.
+  #  To have DNS options set along with hostNetwork, you have to specify DNS policy
+  #  explicitly to 'ClusterFirstWithHostNet'.
+  dnsPolicy: ClusterFirstWithHostNet
+  # resources describes the compute resource requirements and limits
+  resources:
+    requests:
+      memory: "512Mi"
+      cpu: "250m"
+    limits:
+      memory: "1024Mi"
+      cpu: "500m"
+  # storageMode can be EmptyDir, HostPath, StorageClass
+  storageMode: HostPath
   # hostPath is the local path to store data
   hostPath: /data/rocketmq/nameserver
   # volumeClaimTemplates defines the storageClass
diff --git a/example/rocketmq_v1alpha1_rocketmq_cluster.yaml b/example/rocketmq_v1alpha1_rocketmq_cluster.yaml
new file mode 100644
index 0000000..f385832
--- /dev/null
+++ b/example/rocketmq_v1alpha1_rocketmq_cluster.yaml
@@ -0,0 +1,104 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: rocketmq.apache.org/v1alpha1
+kind: Broker
+metadata:
+  # name of broker cluster
+  name: broker
+spec:
+  # size is the number of the broker cluster, each broker cluster contains a master broker and [replicaPerGroup] replica brokers.
+  size: 1
+  # nameServers is the [ip:port] list of name service
+  nameServers: ""
+  # replicationMode is the broker replica sync mode, can be ASYNC or SYNC
+  replicationMode: ASYNC
+  # replicaPerGroup is the number of each broker cluster
+  replicaPerGroup: 1
+  # brokerImage is the customized docker image repo of the RocketMQ broker
+  brokerImage: apacherocketmq/rocketmq-broker:4.5.0-alpine
+  # imagePullPolicy is the image pull policy
+  imagePullPolicy: Always
+  # resources describes the compute resource requirements and limits
+  resources:
+    requests:
+      memory: "2048Mi"
+      cpu: "250m"
+    limits:
+      memory: "4096Mi"
+      cpu: "500m"
+  # allowRestart defines whether allow pod restart
+  allowRestart: true
+  # storageMode can be EmptyDir, HostPath, StorageClass
+  storageMode: EmptyDir
+  # hostPath is the local path to store data
+  hostPath: /data/rocketmq/broker
+  # scalePodName is broker-[broker group number]-master-0
+  scalePodName: broker-0-master-0
+  # volumeClaimTemplates defines the storageClass
+  volumeClaimTemplates:
+    - metadata:
+        name: broker-storage
+      spec:
+        accessModes:
+          - ReadWriteOnce
+        storageClassName: rocketmq-storage
+        resources:
+          requests:
+            storage: 8Gi
+---
+apiVersion: rocketmq.apache.org/v1alpha1
+kind: NameService
+metadata:
+  name: name-service
+spec:
+  # size is the the name service instance number of the name service cluster
+  size: 1
+  # nameServiceImage is the customized docker image repo of the RocketMQ name service
+  nameServiceImage: apacherocketmq/rocketmq-namesrv:4.5.0-alpine
+  # imagePullPolicy is the image pull policy
+  imagePullPolicy: Always
+  # hostNetwork can be true or false
+  hostNetwork: true
+  #  Set DNS policy for the pod.
+  #  Defaults to "ClusterFirst".
+  #  Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'.
+  #  DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy.
+  #  To have DNS options set along with hostNetwork, you have to specify DNS policy
+  #  explicitly to 'ClusterFirstWithHostNet'.
+  dnsPolicy: ClusterFirstWithHostNet
+  # resources describes the compute resource requirements and limits
+  resources:
+    requests:
+      memory: "512Mi"
+      cpu: "250m"
+    limits:
+      memory: "1024Mi"
+      cpu: "500m"
+  # storageMode can be EmptyDir, HostPath, StorageClass
+  storageMode: EmptyDir
+  # hostPath is the local path to store data
+  hostPath: /data/rocketmq/nameserver
+  # volumeClaimTemplates defines the storageClass
+  volumeClaimTemplates:
+    - metadata:
+        name: namesrv-storage
+      spec:
+        accessModes:
+          - ReadWriteOnce
+        storageClassName: rocketmq-storage
+        resources:
+          requests:
+            storage: 1Gi
diff --git a/images/broker/Dockerfile b/images/broker/alpine/Dockerfile
similarity index 73%
rename from images/broker/Dockerfile
rename to images/broker/alpine/Dockerfile
index 0105df3..f25716f 100644
--- a/images/broker/Dockerfile
+++ b/images/broker/alpine/Dockerfile
@@ -19,32 +19,21 @@
 
 RUN apk add --no-cache bash gettext nmap-ncat openssl busybox-extras
 
-ARG user=rocketmq
-ARG group=rocketmq
-ARG uid=3000
-ARG gid=3000
-
-# RocketMQ is run with user `rocketmq`, uid = 1001
-# If you bind mount a volume from the host or a data container,
-# ensure you use the same uid
-RUN addgroup --gid ${gid} ${group} \
-    && adduser --uid ${uid} -G ${group} ${user} -s /bin/bash -D
-
 ARG version
 
 # Rocketmq version
 ENV ROCKETMQ_VERSION ${version}
 
 # Rocketmq home
-ENV ROCKETMQ_HOME  /home/rocketmq/rocketmq-${ROCKETMQ_VERSION}
+ENV ROCKETMQ_HOME  /root/rocketmq-${ROCKETMQ_VERSION}
 
 WORKDIR  ${ROCKETMQ_HOME}
 
 # Install
 RUN set -eux; \
     apk add --virtual .build-deps curl gnupg unzip; \
-    curl https://dist.apache.org/repos/dist/release/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip -o rocketmq.zip; \
-    curl https://dist.apache.org/repos/dist/release/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip.asc -o rocketmq.zip.asc; \
+    curl https://archive.apache.org/dist/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip -o rocketmq.zip; \
+    curl https://archive.apache.org/dist/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip.asc -o rocketmq.zip.asc; \
     #https://www.apache.org/dist/rocketmq/KEYS
 	curl https://www.apache.org/dist/rocketmq/KEYS -o KEYS; \
 	\
@@ -53,7 +42,8 @@
     unzip rocketmq.zip; \
 	mv rocketmq-all*/* . ; \
 	rmdir rocketmq-all* ; \
-	rm rocketmq.zip rocketmq.zip.asc KEYS; \
+	rm rocketmq.zip ; \
+	rm rocketmq.zip.asc KEYS; \
 	apk del .build-deps ; \
     rm -rf /var/cache/apk/* ; \
     rm -rf /tmp/*
@@ -61,8 +51,6 @@
 # Copy customized scripts
 COPY runbroker-customize.sh ${ROCKETMQ_HOME}/bin/
 
-RUN chown -R ${uid}:${gid} ${ROCKETMQ_HOME}
-
 # Expose broker ports
 EXPOSE 10909 10911 10912
 
@@ -82,8 +70,6 @@
 RUN chmod a+x ${ROCKETMQ_HOME}/bin/brokerGenConfig.sh \
  && chmod a+x ${ROCKETMQ_HOME}/bin/brokerStart.sh
 
-USER ${user}
-
 WORKDIR ${ROCKETMQ_HOME}/bin
 
 CMD ["/bin/bash", "./brokerStart.sh"]
\ No newline at end of file
diff --git a/images/broker/brokerGenConfig.sh b/images/broker/alpine/brokerGenConfig.sh
similarity index 100%
rename from images/broker/brokerGenConfig.sh
rename to images/broker/alpine/brokerGenConfig.sh
diff --git a/images/broker/brokerStart.sh b/images/broker/alpine/brokerStart.sh
similarity index 100%
rename from images/broker/brokerStart.sh
rename to images/broker/alpine/brokerStart.sh
diff --git a/images/namesrv/build-namesrv-image.sh b/images/broker/alpine/build-broker-image.sh
similarity index 96%
copy from images/namesrv/build-namesrv-image.sh
copy to images/broker/alpine/build-broker-image.sh
index 8934f30..e02c1ee 100755
--- a/images/namesrv/build-namesrv-image.sh
+++ b/images/broker/alpine/build-broker-image.sh
@@ -33,7 +33,7 @@
 fi
 
 ROCKETMQ_VERSION=$1
-DOCKERHUB_REPO=rocketmqinc/rocketmq-namesrv
+DOCKERHUB_REPO=apacherocketmq/rocketmq-broker
 
 checkVersion $ROCKETMQ_VERSION
 
diff --git a/images/broker/runbroker-customize.sh b/images/broker/alpine/runbroker-customize.sh
similarity index 100%
rename from images/broker/runbroker-customize.sh
rename to images/broker/alpine/runbroker-customize.sh
diff --git a/images/broker/build-broker-image.sh b/images/broker/build-broker-image.sh
deleted file mode 100755
index 0b6f31d..0000000
--- a/images/broker/build-broker-image.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-checkVersion()
-{
-    echo "Version = $1"
-	echo $1 |grep -E "^[0-9]+\.[0-9]+\.[0-9]+" > /dev/null
-    if [ $? = 0 ]; then
-        return 1
-    fi
-
-	echo "Version $1 illegal, it should be X.X.X format(e.g. 4.5.0), please check released versions in 'https://dist.apache.org/repos/dist/release/rocketmq/'"
-    exit 2
-}
-
-if [ $# -lt 1 ]; then
-    echo -e "Usage: sh $0 Version"
-    exit 2
-fi
-
-ROCKETMQ_VERSION=$1
-DOCKERHUB_REPO=rocketmqinc/rocketmq-broker
-
-checkVersion $ROCKETMQ_VERSION
-
-docker build -t ${DOCKERHUB_REPO}:${ROCKETMQ_VERSION}-alpine --build-arg version=${ROCKETMQ_VERSION} .
-
-docker push ${DOCKERHUB_REPO}:${ROCKETMQ_VERSION}-alpine
diff --git a/images/namesrv/Dockerfile b/images/namesrv/alpine/Dockerfile
similarity index 72%
rename from images/namesrv/Dockerfile
rename to images/namesrv/alpine/Dockerfile
index e56eba2..b0303f2 100644
--- a/images/namesrv/Dockerfile
+++ b/images/namesrv/alpine/Dockerfile
@@ -19,32 +19,21 @@
 
 RUN apk add --no-cache bash gettext nmap-ncat openssl busybox-extras
 
-ARG user=rocketmq
-ARG group=rocketmq
-ARG uid=3000
-ARG gid=3000
-
-# RocketMQ is run with user `rocketmq`, uid = 3000
-# If you bind mount a volume from the host or a data container,
-# ensure you use the same uid
-RUN addgroup --gid ${gid} ${group} \
-    && adduser --uid ${uid} -G ${group} ${user} -s /bin/bash -D
-
 ARG version
 
 # Rocketmq version
 ENV ROCKETMQ_VERSION ${version}
 
 # Rocketmq home
-ENV ROCKETMQ_HOME  /home/rocketmq/rocketmq-${ROCKETMQ_VERSION}
+ENV ROCKETMQ_HOME  /root/rocketmq-${ROCKETMQ_VERSION}
 
 WORKDIR  ${ROCKETMQ_HOME}
 
 # Install
 RUN set -eux; \
     apk add --virtual .build-deps curl gnupg unzip; \
-    curl https://dist.apache.org/repos/dist/release/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip -o rocketmq.zip; \
-    curl https://dist.apache.org/repos/dist/release/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip.asc -o rocketmq.zip.asc; \
+    curl https://archive.apache.org/dist/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip -o rocketmq.zip; \
+    curl https://archive.apache.org/dist/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip.asc -o rocketmq.zip.asc; \
     #https://www.apache.org/dist/rocketmq/KEYS
 	curl https://www.apache.org/dist/rocketmq/KEYS -o KEYS; \
 	\
@@ -53,7 +42,8 @@
     unzip rocketmq.zip; \
 	mv rocketmq-all*/* . ; \
 	rmdir rocketmq-all* ; \
-	rm rocketmq.zip rocketmq.zip.asc KEYS; \
+	rm rocketmq.zip ; \
+    rm rocketmq.zip.asc KEYS; \
 	apk del .build-deps ; \
     rm -rf /var/cache/apk/* ; \
     rm -rf /tmp/*
@@ -61,8 +51,6 @@
 # Copy customized scripts
 COPY runserver-customize.sh ${ROCKETMQ_HOME}/bin/
 
-RUN chown -R ${uid}:${gid} ${ROCKETMQ_HOME}
-
 # Expose namesrv port
 EXPOSE 9876
 
@@ -75,8 +63,6 @@
  && export JAVA_OPT=" -Duser.home=/opt" \
  && sed -i 's/${JAVA_HOME}\/jre\/lib\/ext/${JAVA_HOME}\/jre\/lib\/ext:${JAVA_HOME}\/lib\/ext/' ${ROCKETMQ_HOME}/bin/tools.sh
 
-USER ${user}
-
 WORKDIR ${ROCKETMQ_HOME}/bin
 
 CMD ["/bin/bash", "mqnamesrv"]
diff --git a/images/namesrv/build-namesrv-image.sh b/images/namesrv/alpine/build-namesrv-image.sh
similarity index 96%
rename from images/namesrv/build-namesrv-image.sh
rename to images/namesrv/alpine/build-namesrv-image.sh
index 8934f30..36f1bf3 100755
--- a/images/namesrv/build-namesrv-image.sh
+++ b/images/namesrv/alpine/build-namesrv-image.sh
@@ -33,7 +33,7 @@
 fi
 
 ROCKETMQ_VERSION=$1
-DOCKERHUB_REPO=rocketmqinc/rocketmq-namesrv
+DOCKERHUB_REPO=apacherocketmq/rocketmq-namesrv
 
 checkVersion $ROCKETMQ_VERSION
 
diff --git a/images/namesrv/runserver-customize.sh b/images/namesrv/alpine/runserver-customize.sh
similarity index 100%
rename from images/namesrv/runserver-customize.sh
rename to images/namesrv/alpine/runserver-customize.sh
diff --git a/images/try-images.sh b/images/try-images.sh
index 9a7275a..d018436 100755
--- a/images/try-images.sh
+++ b/images/try-images.sh
@@ -15,8 +15,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-NAMESRV_DOCKERHUB_REPO=rocketmqinc/rocketmq-namesrv
-BROKER_DOCKERHUB_REPO=rocketmqinc/rocketmq-broker
+NAMESRV_DOCKERHUB_REPO=apacherocketmq/rocketmq-namesrv
+BROKER_DOCKERHUB_REPO=apacherocketmq/rocketmq-broker
 ROCKETMQ_VERSION=4.5.0
 
 start_namesrv_broker()
diff --git a/install-operator.sh b/install-operator.sh
index cee05a6..76318e1 100755
--- a/install-operator.sh
+++ b/install-operator.sh
@@ -23,7 +23,4 @@
 kubectl create -f deploy/role_binding.yaml
 kubectl create -f deploy/operator.yaml
 
-echo "Wait for operator being ready..."
-sleep 2
-#kubectl create -f example/rocketmq_v1alpha1_nameservice_cr.yaml
-#kubectl create -f example/rocketmq_v1alpha1_broker_cr.yaml
+#kubectl create -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
diff --git a/pkg/apis/rocketmq/v1alpha1/broker_types.go b/pkg/apis/rocketmq/v1alpha1/broker_types.go
index fc7be5d..8eb31de 100644
--- a/pkg/apis/rocketmq/v1alpha1/broker_types.go
+++ b/pkg/apis/rocketmq/v1alpha1/broker_types.go
@@ -38,13 +38,15 @@
 	ReplicationMode string `json:"replicationMode,omitempty"`
 	// ReplicaPerGroup each broker cluster's replica number
 	ReplicaPerGroup int `json:"replicaPerGroup"`
-	// BaseImage is the broker image to use for the Pods.
+	// BaseImage is the broker image to use for the Pods
 	BrokerImage string `json:"brokerImage"`
-	// ImagePullPolicy defines how the image is pulled.
+	// ImagePullPolicy defines how the image is pulled
 	ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"`
 	// AllowRestart defines whether allow pod restart
 	AllowRestart bool `json:"allowRestart"`
-	// StorageMode can be EmptyDir, HostPath, NFS
+	// Resources describes the compute resource requirements
+	Resources corev1.ResourceRequirements `json:"resources"`
+	// StorageMode can be EmptyDir, HostPath, StorageClass
 	StorageMode string `json:"storageMode"`
 	// HostPath is the local path to store data
 	HostPath string `json:"hostPath"`
diff --git a/pkg/apis/rocketmq/v1alpha1/nameservice_types.go b/pkg/apis/rocketmq/v1alpha1/nameservice_types.go
index 7cb1a46..cb4d4f5 100644
--- a/pkg/apis/rocketmq/v1alpha1/nameservice_types.go
+++ b/pkg/apis/rocketmq/v1alpha1/nameservice_types.go
@@ -37,6 +37,12 @@
 	NameServiceImage string `json:"nameServiceImage"`
 	// ImagePullPolicy defines how the image is pulled.
 	ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"`
+	// HostNetwork can be true or false
+	HostNetwork bool `json:"hostNetwork"`
+	// dnsPolicy defines how a pod's DNS will be configured
+	DNSPolicy corev1.DNSPolicy `json:"dnsPolicy"`
+	// Resources describes the compute resource requirements
+	Resources corev1.ResourceRequirements `json:"resources"`
 	// StorageMode can be EmptyDir, HostPath, NFS
 	StorageMode string `json:"storageMode"`
 	// HostPath is the local path to store data
diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go
index 555147b..233e9c2 100644
--- a/pkg/constants/constants.go
+++ b/pkg/constants/constants.go
@@ -59,10 +59,10 @@
 	EnvBrokerName = "BROKER_NAME"
 
 	// LogMountPath is the directory of RocketMQ log files
-	LogMountPath = "/home/rocketmq/logs"
+	LogMountPath = "/root/logs"
 
 	// StoreMountPath is the directory of RocketMQ store files
-	StoreMountPath = "/home/rocketmq/store"
+	StoreMountPath = "/root/store"
 
 	// LogSubPathName is the sub-path name of log dir under mounted host dir
 	LogSubPathName = "logs"
@@ -94,8 +94,8 @@
 	// BrokerHighAvailabilityContainerPortName is the high availability port name of broker container
 	BrokerHighAvailabilityContainerPortName = "ha"
 
-	// StorageModeNFS is the name of NFS storage mode
-	StorageModeNFS = "NFS"
+	// StorageModeStorageClass is the name of StorageClass storage mode
+	StorageModeStorageClass = "StorageClass"
 
 	// StorageModeEmptyDir is the name of EmptyDir storage mode
 	StorageModeEmptyDir = "EmptyDir"
diff --git a/pkg/controller/broker/broker_controller.go b/pkg/controller/broker/broker_controller.go
index 1879d64..9055692 100644
--- a/pkg/controller/broker/broker_controller.go
+++ b/pkg/controller/broker/broker_controller.go
@@ -399,6 +399,7 @@
 				},
 				Spec: corev1.PodSpec{
 					Containers: []corev1.Container{{
+						Resources: broker.Spec.Resources,
 						Image: broker.Spec.BrokerImage,
 						Name:  cons.BrokerContainerName,
 						Lifecycle: &corev1.Lifecycle{
@@ -460,7 +461,7 @@
 
 func getVolumeClaimTemplates(broker *rocketmqv1alpha1.Broker) []corev1.PersistentVolumeClaim {
 	switch broker.Spec.StorageMode {
-	case cons.StorageModeNFS:
+	case cons.StorageModeStorageClass:
 		return broker.Spec.VolumeClaimTemplates
 	case cons.StorageModeEmptyDir, cons.StorageModeHostPath:
 		fallthrough
@@ -471,7 +472,7 @@
 
 func getVolumes(broker *rocketmqv1alpha1.Broker) []corev1.Volume {
 	switch broker.Spec.StorageMode {
-	case cons.StorageModeNFS:
+	case cons.StorageModeStorageClass:
 		return nil
 	case cons.StorageModeEmptyDir:
 		volumes := []corev1.Volume{{
diff --git a/pkg/controller/broker/broker_controller_test.go b/pkg/controller/broker/broker_controller_test.go
index fc28059..1ea721f 100644
--- a/pkg/controller/broker/broker_controller_test.go
+++ b/pkg/controller/broker/broker_controller_test.go
@@ -46,7 +46,7 @@
 	var (
 		name            = "rocketmq-operator"
 		namespace       = "broker"
-		replicas  int32 = 3
+		replicas   		= 3
 	)
 
 	// A Broker resource with metadata and spec.
@@ -96,7 +96,7 @@
 		t.Fatalf("get deployment: (%v)", err)
 	}
 	dsize := *dep.Spec.Replicas
-	if dsize != replicas {
+	if dsize != int32(replicas) {
 		t.Errorf("dep size (%d) is not the expected size (%d)", dsize, replicas)
 	}
 
diff --git a/pkg/controller/nameservice/nameservice_controller.go b/pkg/controller/nameservice/nameservice_controller.go
index 5b93f33..410515f 100644
--- a/pkg/controller/nameservice/nameservice_controller.go
+++ b/pkg/controller/nameservice/nameservice_controller.go
@@ -190,7 +190,6 @@
 
 		if len(oldNameServerListStr) <= cons.MinIpListLength {
 			oldNameServerListStr = share.NameServersStr
-			share.IsNameServersStrInitialized = true
 		} else if len(share.NameServersStr) > cons.MinIpListLength {
 			oldNameServerListStr = oldNameServerListStr[:len(oldNameServerListStr)-1]
 			share.IsNameServersStrUpdated = true
@@ -232,6 +231,11 @@
 		reqLogger.Info("NameServers IP " + strconv.Itoa(i) + ": " + value)
 	}
 
+	runningNameServerNum := getRunningNameServersNum(podList.Items)
+	if runningNameServerNum == instance.Spec.Size {
+		share.IsNameServersStrInitialized = true
+	}
+
 	if requeue {
 		return reconcile.Result{Requeue: true, RequeueAfter: time.Duration(cons.RequeueIntervalInSecond) * time.Second}, nil
 	}
@@ -241,7 +245,7 @@
 
 func getVolumeClaimTemplates(nameService *rocketmqv1alpha1.NameService) []corev1.PersistentVolumeClaim {
 	switch nameService.Spec.StorageMode {
-	case cons.StorageModeNFS:
+	case cons.StorageModeStorageClass:
 		return nameService.Spec.VolumeClaimTemplates
 	case cons.StorageModeEmptyDir, cons.StorageModeHostPath:
 		fallthrough
@@ -252,7 +256,7 @@
 
 func getVolumes(nameService *rocketmqv1alpha1.NameService) []corev1.Volume {
 	switch nameService.Spec.StorageMode {
-	case cons.StorageModeNFS:
+	case cons.StorageModeStorageClass:
 		return nil
 	case cons.StorageModeEmptyDir:
 		volumes := []corev1.Volume{{
@@ -278,11 +282,21 @@
 func getNameServers(pods []corev1.Pod) []string {
 	var nameServers []string
 	for _, pod := range pods {
-		nameServers = append(nameServers, pod.Status.HostIP)
+		nameServers = append(nameServers, pod.Status.PodIP)
 	}
 	return nameServers
 }
 
+func getRunningNameServersNum(pods []corev1.Pod) int32 {
+	var num int32 = 0
+	for _, pod := range pods {
+		if reflect.DeepEqual(pod.Status.Phase, corev1.PodRunning) {
+			num++
+		}
+	}
+	return num
+}
+
 func labelsForNameService(name string) map[string]string {
 	return map[string]string{"app": "name_service", "name_service_cr": name}
 }
@@ -304,9 +318,10 @@
 					Labels: ls,
 				},
 				Spec: corev1.PodSpec{
-					HostNetwork: true,
-					DNSPolicy:   "ClusterFirstWithHostNet",
+					HostNetwork: nameService.Spec.HostNetwork,
+					DNSPolicy: nameService.Spec.DNSPolicy,
 					Containers: []corev1.Container{{
+						Resources: nameService.Spec.Resources,
 						Image: nameService.Spec.NameServiceImage,
 						// Name must be lower case !
 						Name:            "name-service",
diff --git a/purge-operator.sh b/purge-operator.sh
index f49bb32..34f4a8f 100755
--- a/purge-operator.sh
+++ b/purge-operator.sh
@@ -16,8 +16,7 @@
 # limitations under the License.
 
 echo "Stopping RocketMQ-Operator..."
-#kubectl delete -f example/rocketmq_v1alpha1_broker_cr.yaml
-#kubectl delete -f example/rocketmq_v1alpha1_nameservice_cr.yaml
+#kubectl delete -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
 
 kubectl delete -f deploy/operator.yaml
 kubectl delete -f deploy/role_binding.yaml