diff --git a/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml b/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml index 834c43c9..c5e0aa7c 100644 --- a/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml +++ b/deploy/crds/rocketmq_v1alpha1_broker_crd.yaml @@ -79,6 +79,31 @@ spec: items: type: object type: array + affinity: + description: Affinity and anti-affinity scheduling + type: object + securityContext: + description: Defines privilege and access control settings for a Pod or Container. + type: object + imagePullSecrets: + description: Pull an image from a private registry + items: + type: object + type: array + tolerations: + description: Taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes + items: + type: object + type: array + nodeSelector: + description: The simplest recommended form of node selection constraint. + type: object + podAnnotations: + description: You can use annotations to attach arbitrary non-identifying metadata to objects. + type: object + priorityClassName: + description: Defines priority class's name + type: string required: - size - replicaPerGroup diff --git a/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml b/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml index 437ce049..e9fafa2d 100644 --- a/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml +++ b/deploy/crds/rocketmq_v1alpha1_nameservice_crd.yaml @@ -63,6 +63,31 @@ spec: items: type: object type: array + affinity: + description: Affinity and anti-affinity scheduling + type: object + securityContext: + description: Defines privilege and access control settings for a Pod or Container. + type: object + imagePullSecrets: + description: Pull an image from a private registry + items: + type: object + type: array + tolerations: + description: Taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes + items: + type: object + type: array + nodeSelector: + description: The simplest recommended form of node selection constraint. + type: object + podAnnotations: + description: You can use annotations to attach arbitrary non-identifying metadata to objects. + type: object + priorityClassName: + description: Defines priority class's name + type: string required: - size - nameServiceImage diff --git a/example/rocketmq_v1alpha1_rocketmq_feature_cluster.yaml b/example/rocketmq_v1alpha1_rocketmq_feature_cluster.yaml new file mode 100644 index 00000000..fd1b1dc1 --- /dev/null +++ b/example/rocketmq_v1alpha1_rocketmq_feature_cluster.yaml @@ -0,0 +1,180 @@ +# 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: ConfigMap +metadata: + name: broker-config +data: + # BROKER_MEM sets the broker JVM, if set to "" then Xms = Xmx = max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB)) + BROKER_MEM: " -Xms2g -Xmx2g -Xmn1g " + broker-common.conf: | + # brokerClusterName, brokerName, brokerId are automatically generated by the operator and do not set it manually!!! + deleteWhen=04 + fileReservedTime=48 + flushDiskType=ASYNC_FLUSH + # set brokerRole to ASYNC_MASTER or SYNC_MASTER. DO NOT set to SLAVE because the replica instance will automatically be set!!! + brokerRole=ASYNC_MASTER + +--- +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: "" + # replicaPerGroup is the number of each broker cluster + replicaPerGroup: 0 + # brokerImage is the customized docker image repo of the RocketMQ broker + brokerImage: apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0 + # imagePullPolicy is the image pull policy + imagePullPolicy: Always + # resources describes the compute resource requirements and limits + resources: + requests: + memory: "2048Mi" + cpu: "250m" + limits: + memory: "12288Mi" + 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: /tmp/data/rocketmq/broker + # scalePodName is [Broker name]-[broker group number]-master-0 + scalePodName: broker-0-master-0 + # env defines custom env, e.g. BROKER_MEM + env: + - name: BROKER_MEM + valueFrom: + configMapKeyRef: + name: broker-config + key: BROKER_MEM + # volumes defines the broker.conf + volumes: + - name: broker-config + configMap: + name: broker-config + items: + - key: broker-common.conf + path: broker-common.conf + # volumeClaimTemplates defines the storageClass + volumeClaimTemplates: + - metadata: + name: broker-storage + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 8Gi + selector: + matchLabels: + app: broker-storage-pv +--- +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-nameserver:4.5.0-alpine-operator-0.3.0 + # imagePullPolicy is the image pull policy + imagePullPolicy: Always + # hostNetwork can be true or false + hostNetwork: true + podAnnotations: + prometheus.io/path: /metrics + prometheus.io/port: "5557" + prometheus.io/scrape: "true" + securityContext: + allowPrivilegeEscalation: true + runAsUser: 0 + runAsGroup: 0 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - azure-k8s-7 + - azure-k8s-1 + - azure-k8s-3 + - azure-k8s-2 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - name_service + topologyKey: kubernetes.io/hostname + priorityClassName: "" + imagePullSecrets: + - name: registry-secret + nodeSelector: + azure: "true" + tolerations: + - key: "key1" + operator: "Equal" + value: "value1" + effect: "NoSchedule" + - key: "key2" + operator: "Equal" + value: "value1" + effect: "NoExecute" + # 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/pkg/apis/rocketmq/v1alpha1/broker_types.go b/pkg/apis/rocketmq/v1alpha1/broker_types.go index 1e694ee5..5939bec6 100644 --- a/pkg/apis/rocketmq/v1alpha1/broker_types.go +++ b/pkg/apis/rocketmq/v1alpha1/broker_types.go @@ -56,6 +56,21 @@ type BrokerSpec struct { VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates"` // The name of pod where the metadata from ScalePodName string `json:"scalePodName"` + // Affinity, affinity and anti-affinity scheduling + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // SecurityContext defines privilege and access control settings for a Pod or Container. + SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + // ImagePullSecrets pull an image from a private registry + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` + // Tolerations taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // NodeSelector is the simplest recommended form of node selection constraint. + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // PodAnnotations you can use annotations to attach arbitrary non-identifying metadata to objects. + PodAnnotations map[string]string `json:"podAnnotations,omitempty"` + // PriorityClassName defines priority class's name + PriorityClassName string `json:"priorityClassName,omitempty"` + } // BrokerStatus defines the observed state of Broker diff --git a/pkg/apis/rocketmq/v1alpha1/nameservice_types.go b/pkg/apis/rocketmq/v1alpha1/nameservice_types.go index b8900e9b..9b4f2476 100644 --- a/pkg/apis/rocketmq/v1alpha1/nameservice_types.go +++ b/pkg/apis/rocketmq/v1alpha1/nameservice_types.go @@ -49,6 +49,20 @@ type NameServiceSpec struct { HostPath string `json:"hostPath"` // VolumeClaimTemplates defines the StorageClass VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates"` + // Affinity, affinity and anti-affinity scheduling + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // SecurityContext defines privilege and access control settings for a Pod or Container. + SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + // ImagePullSecrets pull an image from a private registry + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` + // Tolerations taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // NodeSelector is the simplest recommended form of node selection constraint. + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // PodAnnotations you can use annotations to attach arbitrary non-identifying metadata to objects. + PodAnnotations map[string]string `json:"podAnnotations,omitempty"` + // PriorityClassName defines priority class's name + PriorityClassName string `json:"priorityClassName,omitempty"` } // NameServiceStatus defines the observed state of NameService diff --git a/pkg/controller/broker/broker_controller.go b/pkg/controller/broker/broker_controller.go index 5b2de774..00d9e55f 100644 --- a/pkg/controller/broker/broker_controller.go +++ b/pkg/controller/broker/broker_controller.go @@ -401,8 +401,15 @@ func (r *ReconcileBroker) getBrokerStatefulSet(broker *rocketmqv1alpha1.Broker, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: ls, + Annotations: broker.Spec.PodAnnotations, }, Spec: corev1.PodSpec{ + Affinity: broker.Spec.Affinity, + SecurityContext: broker.Spec.SecurityContext, + ImagePullSecrets: broker.Spec.ImagePullSecrets, + Tolerations: broker.Spec.Tolerations, + NodeSelector: broker.Spec.NodeSelector, + PriorityClassName: broker.Spec.PriorityClassName, Containers: []corev1.Container{{ Resources: broker.Spec.Resources, Image: broker.Spec.BrokerImage, diff --git a/pkg/controller/nameservice/nameservice_controller.go b/pkg/controller/nameservice/nameservice_controller.go index 410515f8..5222b1b3 100644 --- a/pkg/controller/nameservice/nameservice_controller.go +++ b/pkg/controller/nameservice/nameservice_controller.go @@ -316,10 +316,17 @@ func (r *ReconcileNameService) statefulSetForNameService(nameService *rocketmqv1 Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: ls, + Annotations: nameService.Spec.PodAnnotations, }, Spec: corev1.PodSpec{ HostNetwork: nameService.Spec.HostNetwork, DNSPolicy: nameService.Spec.DNSPolicy, + Affinity: nameService.Spec.Affinity, + SecurityContext: nameService.Spec.SecurityContext, + ImagePullSecrets: nameService.Spec.ImagePullSecrets, + Tolerations: nameService.Spec.Tolerations, + NodeSelector: nameService.Spec.NodeSelector, + PriorityClassName: nameService.Spec.PriorityClassName, Containers: []corev1.Container{{ Resources: nameService.Spec.Resources, Image: nameService.Spec.NameServiceImage,