Skip to content

Commit bddafb3

Browse files
committed
add multi-master option to galera
This change adds the new value enableMultiMaster to the Galera CR defaulting to false; when set to true, the "statefulset.kubernetes.io/pod-name" key is removed from the mariadb service spec, and when set to false it is restored. This has the effect of publishing the service either under one specific pod for active/passive use, or using any pod for any request which is multi-master use. the value of the attribute is also propigated out to the status within the MariaDBDatabase CR, which is then consumable by openstack services in a similar manner as the TLS settings. Openstack services will then want to set wsrep_sync_wait accordingly for AP or MM mode, which will be proposed in followup changes. New teardown steps added to kuttl tests galera_cluster_restart and galera_log_to_disk as there seem to be pvcs being not cleaned up on CI leading to hangs Fixes: OSPRH-7406
1 parent 8c6251d commit bddafb3

17 files changed

+305
-10
lines changed

api/bases/mariadb.openstack.org_galeras.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ spec:
6464
description: When TLS is configured, only allow connections to the
6565
DB over TLS
6666
type: boolean
67+
enableMultiMaster:
68+
default: false
69+
description: Use multi-master service routing
70+
type: boolean
6771
logToDisk:
6872
description: Log Galera pod's output to disk
6973
type: boolean
@@ -104,6 +108,7 @@ spec:
104108
type: object
105109
required:
106110
- containerImage
111+
- enableMultiMaster
107112
- replicas
108113
- secret
109114
- storageClass

api/bases/mariadb.openstack.org_mariadbdatabases.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ spec:
9898
- type
9999
type: object
100100
type: array
101+
enableMultiMaster:
102+
description: whether the DB instance is using multi-master routing
103+
type: boolean
101104
hash:
102105
additionalProperties:
103106
type: string

api/v1beta1/galera_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ type GaleraSpecCore struct {
8989
// +kubebuilder:validation:Optional
9090
// Log Galera pod's output to disk
9191
LogToDisk bool `json:"logToDisk"`
92+
// +kubebuilder:default=false
93+
// Use multi-master service routing
94+
EnableMultiMaster bool `json:"enableMultiMaster"`
9295
}
9396

9497
// GaleraAttributes holds startup information for a Galera host

api/v1beta1/mariadbdatabase_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ type MariaDBDatabaseStatus struct {
5555

5656
// Whether TLS is supported by the DB instance
5757
TLSSupport bool `json:"tlsSupport,omitempty"`
58+
59+
// whether the DB instance is using multi-master routing
60+
EnableMultiMaster bool `json:"enableMultiMaster,omitempty"`
5861
}
5962

6063
//+kubebuilder:object:root=true

config/crd/bases/mariadb.openstack.org_galeras.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ spec:
6464
description: When TLS is configured, only allow connections to the
6565
DB over TLS
6666
type: boolean
67+
enableMultiMaster:
68+
default: false
69+
description: Use multi-master service routing
70+
type: boolean
6771
logToDisk:
6872
description: Log Galera pod's output to disk
6973
type: boolean
@@ -104,6 +108,7 @@ spec:
104108
type: object
105109
required:
106110
- containerImage
111+
- enableMultiMaster
107112
- replicas
108113
- secret
109114
- storageClass

config/crd/bases/mariadb.openstack.org_mariadbdatabases.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ spec:
9898
- type
9999
type: object
100100
type: array
101+
enableMultiMaster:
102+
description: whether the DB instance is using multi-master routing
103+
type: boolean
101104
hash:
102105
additionalProperties:
103106
type: string

controllers/galera_controller.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -509,16 +509,23 @@ func (r *GaleraReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
509509
// service get stuck.
510510
controllerutil.AddFinalizer(service, helper.GetFinalizer())
511511

512-
// NOTE(dciabrin) We deploy Galera as an A/P service (i.e. no multi-master writes)
513-
// by setting labels in the service's label selectors.
514-
// This label is dynamically set based on the status of the Galera cluster,
515-
// so in this CreateOrPatch block we must reuse whatever is present in
516-
// the existing service CR in case we're patching it.
517-
activePod, present := service.Spec.Selector[mariadb.ActivePodSelectorKey]
518-
service.Spec = pkgsvc.Spec
519-
if present {
520-
service.Spec.Selector[mariadb.ActivePodSelectorKey] = activePod
512+
if !instance.Spec.EnableMultiMaster {
513+
// NOTE(dciabrin) We deploy Galera as an A/P service (i.e. no multi-master writes)
514+
// by setting labels in the service's label selectors.
515+
// This label is dynamically set based on the status of the Galera cluster,
516+
// so in this CreateOrPatch block we must reuse whatever is present in
517+
// the existing service CR in case we're patching it.
518+
activePod, present := service.Spec.Selector[mariadb.ActivePodSelectorKey]
519+
service.Spec = pkgsvc.Spec
520+
521+
if present {
522+
service.Spec.Selector[mariadb.ActivePodSelectorKey] = activePod
523+
}
524+
} else {
525+
service.Spec = pkgsvc.Spec
526+
delete(service.Spec.Selector, mariadb.ActivePodSelectorKey)
521527
}
528+
522529
err := controllerutil.SetControllerReference(instance, service, r.Client.Scheme())
523530
if err != nil {
524531
return err

controllers/mariadbdatabase_controller.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
ctrl "sigs.k8s.io/controller-runtime"
2828
"sigs.k8s.io/controller-runtime/pkg/client"
2929
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
30+
"sigs.k8s.io/controller-runtime/pkg/handler"
31+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3032

3133
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
3234
helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper"
@@ -145,7 +147,7 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ
145147

146148
// here we know that Galera exists so add a finalizer to ourselves and to the db CR. Before this point there is no reason to have a finalizer on ourselves as nothing to cleanup.
147149
if instance.DeletionTimestamp.IsZero() || isNewInstance { // this condition can be removed if you wish as it is always true at this point otherwise we would returned earlier.
148-
if controllerutil.AddFinalizer(dbGalera, fmt.Sprintf("%s-%s", helper.GetFinalizer(), instance.Name)) {
150+
if dbGalera.DeletionTimestamp.IsZero() && controllerutil.AddFinalizer(dbGalera, fmt.Sprintf("%s-%s", helper.GetFinalizer(), instance.Name)) {
149151
err := r.Update(ctx, dbGalera)
150152
if err != nil {
151153
return ctrl.Result{}, err
@@ -200,6 +202,9 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ
200202
return ctrl.Result{}, err
201203
}
202204

205+
// DB instances setup for multi master
206+
instance.Status.EnableMultiMaster = dbGalera.Spec.EnableMultiMaster
207+
203208
dbCreateHash := instance.Status.Hash[databasev1beta1.DbCreateHash]
204209
dbCreateJob := job.NewJob(
205210
jobDef,
@@ -245,8 +250,43 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ
245250

246251
// SetupWithManager -
247252
func (r *MariaDBDatabaseReconciler) SetupWithManager(mgr ctrl.Manager) error {
253+
254+
updateStatusFn := func(ctx context.Context, o client.Object) []reconcile.Request {
255+
log := GetLog(ctx, "MariaDBDatabase")
256+
257+
result := []reconcile.Request{}
258+
259+
mariaDBDatabases := &databasev1beta1.MariaDBDatabaseList{}
260+
261+
listOpts := []client.ListOption{
262+
client.InNamespace(o.GetNamespace()),
263+
}
264+
if err := r.Client.List(ctx, mariaDBDatabases, listOpts...); err != nil {
265+
log.Error(err, "Unable to retrieve MariaDBDatabase CRs %w")
266+
return nil
267+
}
268+
269+
for _, cr := range mariaDBDatabases.Items {
270+
271+
if o.GetName() == cr.GetLabels()["dbName"] {
272+
name := client.ObjectKey{
273+
Namespace: o.GetNamespace(),
274+
Name: cr.Name,
275+
}
276+
log.Info(fmt.Sprintf("Galera %s is used by MariaDBDatabase CR %s", o.GetName(), cr.Name))
277+
result = append(result, reconcile.Request{NamespacedName: name})
278+
}
279+
}
280+
281+
if len(result) > 0 {
282+
return result
283+
}
284+
return nil
285+
}
286+
248287
return ctrl.NewControllerManagedBy(mgr).
249288
For(&databasev1beta1.MariaDBDatabase{}).
289+
Watches(&databasev1beta1.Galera{}, handler.EnqueueRequestsFromMapFunc(updateStatusFn)).
250290
Complete(r)
251291
}
252292

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: kuttl.dev/v1beta
2+
kind: TestStep
3+
delete:
4+
- apiVersion: mariadb.openstack.org/v1beta1
5+
kind: Galera
6+
name: openstack
7+
commands:
8+
- script: |
9+
oc delete -n $NAMESPACE pvc mysql-db-openstack-galera-0 mysql-db-openstack-galera-1 mysql-db-openstack-galera-2
10+
for i in `oc get pv | awk '/mysql-db.*galera/ {print $1}'`; do oc patch pv $i -p '{"spec":{"claimRef": null}}'; done
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: kuttl.dev/v1beta
2+
kind: TestStep
3+
delete:
4+
- apiVersion: mariadb.openstack.org/v1beta1
5+
kind: Galera
6+
name: openstack
7+
commands:
8+
- script: |
9+
oc delete -n $NAMESPACE pvc mysql-db-openstack-galera-0 mysql-db-openstack-galera-1 mysql-db-openstack-galera-2
10+
for i in `oc get pv | awk '/mysql-db.*galera/ {print $1}'`; do oc patch pv $i -p '{"spec":{"claimRef": null}}'; done

0 commit comments

Comments
 (0)