From e7747f6baa4185ccb8b8fe9bbb3ab12424b2c96c Mon Sep 17 00:00:00 2001 From: Oliver Walsh Date: Thu, 19 Sep 2024 14:21:05 +0100 Subject: [PATCH] Use prod config for rabbitmq --- ....openstack.org_openstackcontrolplanes.yaml | 2 + .../v1beta1/openstackcontrolplane_types.go | 5 ++ ....openstack.org_openstackcontrolplanes.yaml | 2 + pkg/openstack/rabbitmq.go | 56 ++++++++++++++----- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 665ff2def..4184a1546 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -17493,6 +17493,8 @@ spec: type: object type: object type: object + topologySpreadKey: + type: string required: - secret - storageClass diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 289cc7e30..f853b0187 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -90,6 +90,11 @@ type OpenStackControlPlaneSpec struct { // NodeSelector to target subset of worker nodes running control plane services (currently only applies to KeystoneAPI and PlacementAPI) NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // TopologySpread TopologyKey label to define worker node availability domains when running control plane services e.g topology.kubernetes.io/zone + TopologySpreadKey string `json:"topologySpreadKey,omitempty"` + // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec // +kubebuilder:default={ingress: {enabled: true, ca: {duration: "87600h"}, cert: {duration: "43800h"}}, podLevel: {enabled: true, internal:{ca: {duration: "87600h"}, cert: {duration: "43800h"}}, libvirt: {ca: {duration: "87600h"}, cert: {duration: "43800h"}}, ovn: {ca: {duration: "87600h"}, cert: {duration: "43800h"}}}} diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 665ff2def..4184a1546 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -17493,6 +17493,8 @@ spec: type: object type: object type: object + topologySpreadKey: + type: string required: - secret - storageClass diff --git a/pkg/openstack/rabbitmq.go b/pkg/openstack/rabbitmq.go index 2737ae45d..b712b3d95 100644 --- a/pkg/openstack/rabbitmq.go +++ b/pkg/openstack/rabbitmq.go @@ -259,6 +259,28 @@ func reconcileRabbitMQ( }, } + // https://github.com/rabbitmq/cluster-operator/tree/d41c06dd43588e09b15c19e5bd78ed219baa0702/docs/examples/production-ready + if instance.Spec.TopologySpreadKey != "" { + defaultStatefulSet.Spec.Template.Spec.TopologySpreadConstraints = []corev1.TopologySpreadConstraint{ + { + MaxSkew: 1, + TopologyKey: instance.Spec.TopologySpreadKey, + WhenUnsatisfiable: corev1.DoNotSchedule, + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "app.kubernetes.io/name", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + rabbitmq.Name, + }, + }, + }, + }, + }, + } + } + hostname := fmt.Sprintf("%s.%s.svc", name, instance.Namespace) hostnameHeadless := fmt.Sprintf("%s-nodes.%s.svc", name, instance.Namespace) hostnames := []string{ @@ -331,32 +353,40 @@ func reconcileRabbitMQ( //spec.Affinity.DeepCopyInto(rabbitmq.Spec.Affinity) } else { // default anti affinity as in - // https://github.com/rabbitmq/cluster-operator/blob/11361d4201a55f457da7c1a2f69e75b2b0cfd069/docs/examples/pod-anti-affinity/rabbitmq.yaml + // https://github.com/rabbitmq/cluster-operator/tree/d41c06dd43588e09b15c19e5bd78ed219baa0702/docs/examples/production-ready rabbitmq.Spec.Affinity = &corev1.Affinity{ PodAntiAffinity: &corev1.PodAntiAffinity{ - PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ { - Weight: 100, - PodAffinityTerm: corev1.PodAffinityTerm{ - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "app.kubernetes.io/name", - Operator: metav1.LabelSelectorOpIn, - Values: []string{ - "pod-anti-affinity", - }, + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "app.kubernetes.io/name", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + rabbitmq.Name, }, }, }, - TopologyKey: "kubernetes.io/hostname", }, + TopologyKey: "kubernetes.io/hostname", }, }, }, } } + // TODO: + // apiVersion: policy/v1 + // kind: PodDisruptionBudget + // metadata: + // name: production-ready-rabbitmq + // spec: + // maxUnavailable: 1 + // selector: + // matchLabels: + // app.kubernetes.io/name: + if rabbitmq.Spec.Persistence.StorageClassName == nil { Log.Info(fmt.Sprintf("Setting StorageClassName: " + instance.Spec.StorageClass)) rabbitmq.Spec.Persistence.StorageClassName = &instance.Spec.StorageClass